Можно ли протестировать глубину по текстуре глубины, которую я также отбираю, в том же вызове draw?

#opengl #fbo #opengl-4 #deferred-rendering

#opengl #fbo #opengl-4 #отложенный рендеринг

Вопрос:

Контекст:

Я использую настройку отложенного рендеринга, где на первом этапе у меня есть два FBO: один — GBuffer, для хранения нормалей, альбедо и информации о материале для всех видимых фрагментов. Этот FBO имеет текстуру 32-битной глубины. Это выполняется на этапе геометрии, прежде чем вычисляется какое-либо освещение.

Второй FBO доступен только для цвета и начинается с черного, но накапливает освещение за несколько проходов от шейдеров освещения, которые отбирают из GBuffer и записывают в буфер только для цвета с использованием аддитивного смешивания.

Проблема в том, что я действительно хотел бы использовать раннее тестирование глубины, чтобы мое освещение вычислялось ТОЛЬКО для фрагментов, которые содержат фактическую геометрию (не только небо). Лучший способ, который я могу придумать для этого, — использовать тестирование глубины, чтобы исключить любые пиксели, глубина которых равна единице в случае солнечного света, или исключить любые пиксели, которые находятся за сферой влияния для точечных источников света. Однако я не думаю, что смогу привязать эту текстуру глубины к моему color FBO, поскольку я также отбираю из нее внутри шейдера освещения для вычисления положения фрагментов в мировом пространстве.

Итак, мой вопрос: есть ли способ использовать одну и ту же текстуру глубины как для раннего теста глубины, так и для выборки внутри шейдера? Или, если нет, есть ли какой-либо другой (достаточно производительный) способ отклонения пикселей, в которых нет геометрии? Я вообще не буду записывать в эту текстуру глубины в моем проходе освещения.

Мне нужно настроить таргетинг только на современное графическое оборудование на ПК (поэтому я могу использовать любые распространенные расширения или функции OpenGL 4.6).

Ответ №1:

В OpenGL существуют правила чтения из данных в шейдере, которые также обновляются из-за операции фреймбуфера. Раньше эти правила были довольно строгими. Действительно, до GL 4.4 правила были настолько строгими, что то, что вы пытаетесь сделать, на самом деле было неопределенным поведением. То есть, если изображение из текстуры было прикреплено к FBO рендеринга, и вы взяли образец из этой текстуры таким образом, что было вообще возможно считывать с прикрепленного изображения, вы получили неопределенное поведение. Неважно, если ваша маска записи означала, что записи не произошло; это был UB.

К счастью, теперь это четко определено. Вы получаете UB только в том случае, если вы выполняете реальную запись, а не просто потому, что у вас есть изображение, прикрепленное к FBO. И под «сейчас» я подразумеваю в основном любое оборудование, созданное за последние 10 лет. Хотя ARB_texture_barrier и GL 4.5 появились довольно недавно, их предшественник NV_texture_barrier на самом деле довольно старый. И несмотря на то, что по названию это расширение NVIDIA, оно было настолько широко реализовано, что доступно даже в версиях macOS.