2015-07-30 1 views
0

Учитывая фрагментарный шейдер, который изменяет исходную глубину фрагмента и записывает в gl_FragDepth. Будет ли выполняться код после записи до gl_Fragdepth, если тест глубины завершится с ошибкой в ​​этой точке?Выполнение шейдера после записи в gl_FragDepth

Пример:

in float depth; 
layout(depth_less) out float gl_FragDepth; 
void main() { 
    float newDepth = depth - someModification; 
    gl_FragDepth = newDepth; 
    A(); 
} 

Будет A быть выполнена, если newDepth больше, чем текущее значение в gl_FragDepth?

Если да, то какова была бы альтернатива, чтобы остановить шейдер от выполнения ненужных вычислений в A - без использования настраиваемого буфера глубины?

ответ

1

В вашем примере A() всегда будет выполняться до тех пор, пока он вносит вклад в любое выходное значение, например. цвет (иначе компилятор удалит его как оптимизацию). Тест глубины представляет собой операцию на выборку, обычно выполняемую после фрагментарного шейдера. Under special circumstances, этот тест можно выполнить перед фрагментарным шейдером, но для этого требуется, чтобы сам шейдер фрагмента не записывался в gl_FragDepth.

Является ли изменение, которое вы делаете единообразным, или оно отличается для каждого фрагмента? Если он однородный, вы можете сделать это в геометрическом шейдере - просто примените модификацию глубины ко всему примитиву. Тогда вы можете использовать ранний z. Если он основан на фрагменте, вы можете попытаться привязать текущий целевой рендеринг глубины как readonly image, получить запомненное значение глубины, выполнить ручное сравнение в вашем шейдере и отбросить фрагмент, если он сработает. Тем не менее, я не знаю, действительно ли вы можете привязать текущие привязанные объекты framebuffer к изображениям как изображения, даже как только для чтения, и не будет ли это более или менее результативным, чем просто выполнение A().

+0

Благодарим вас за ответ. Модификация зависит от фрагмента. Ваше предлагаемое решение работало для меня при рисовании геометрии с помощью glDraw *(). Поскольку мне нужно рисовать одну и ту же геометрию несколько раз, я использую glDraw * Instaced(), но в этом случае ручной анализ глубины вызывает артефакты. В любом случае, что A() всегда будет выполняться до тех пор, пока он вносит вклад в любой выход, отвечает на мой главный вопрос. – nils

+0

Да ... тест против gl_FragDepth может произойти в любое время после его появления. Карта может вычислять перекрывающиеся фрагменты в любом порядке, а глубины фрагментов от каждого вычисления в конечном итоге определяют, какой из них «выигрывает». –

Смежные вопросы