Что произойдет с буфером глубины, если я отброшу фрагмент в шейдере с помощью Early_fragment_tests?

Я использую фрагментный шейдер, который отбрасывает некоторые фрагменты с помощью ключевого слова discard. Мой шейдер также использует early_fragment_tests (загрузка хранилища изображений обязывает).

EDIT: я не пишу gl_FragDepth, я позволяю стандартному OpenGL обрабатывать значение глубины.

Будет ли мой буфер глубины обновляться глубиной фрагмента до выполнения ключевого слова discard?

EDIT: не похоже на моих NVidia Quadro 600 и K5000.

Есть какие-нибудь подсказки, где я могу найти эту информацию? К вашему сведению, я искал http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt. Я нашел достаточно близкие темы, но не эту конкретную.


person Jean-Simon Brochu    schedule 06.11.2013    source источник
comment
Я провел несколько тестов с более простой программой, и кажется, что она в конце концов не обновляется ... Мне все еще интересно, зависит ли это от реализации или нет.   -  person Jean-Simon Brochu    schedule 06.11.2013
comment
Я только что нашел свой ответ, он зависит от реализации. Я провел несколько тестов на K3000M с той же версией драйвера, что и мой K5000, и он обновляет буфер глубины, даже если я отбрасываю свой фрагмент.   -  person Jean-Simon Brochu    schedule 04.04.2014


Ответы (2)


Будет ли мой буфер глубины обновляться глубиной фрагмента до того, как будет выполнено ключевое слово discard?

Нет, такое поведение явно запрещено в шейдере, который содержит discard или записывает произвольное значение в gl_FragDepth. Это связано с тем, что в таком шейдере глубина вашего фрагмента после его затенения может быть не связана с позицией, сгенерированной во время начальной растеризации (предварительного затенения).

Без записи в gl_FragDepth или отбрасывания глубина фрагмента фактически известна задолго до фактического выполнения фрагментного шейдера, и это формирует основу для ранних тестов глубины. Растеризацию/затенение можно пропустить для некоторых (отдельных мозаичных областей) или всего примитива, если можно определить, что он не прошел бы проверку глубины до фрагментного шейдера. оценивается, но если сам фрагментный шейдер определяет глубину фрагмента, то все ставки сняты.

В DX11/OpenGL 4.x есть исключение из этого правила. Если вы пишете свои шейдеры таким образом, что вы можете гарантировать, что выходная глубина всегда будет сохранять результат теста глубины (тот же результат, что и глубина, сгенерированная во время растеризации), можно включить ранние тесты фрагментов в шейдере, который использует discard или записывает до gl_FragDepth. Эта функция известна как консервативная глубина, и если вы не используете это, обычно понимается, что discard нарушит раннюю оптимизацию глубины по всем направлениям.

Теперь, поскольку вы никогда не должны записывать в буфер глубины, пока не узнаете, проходит ли записываемое вами значение тест глубины или нет (gl_FragDepth может быть другим) или фрагмент вообще выживает (может использоваться discard), вы можете понять, почему примитив, затененный фрагментным шейдером, который содержит discard, не может выполнять запись в буфер глубины до того, как шейдер будет оценен.

person Andon M. Coleman    schedule 07.11.2013
comment
Спасибо за ваш ответ, но я думаю, что меня неправильно поняли: я явно не пишу в gl_FragDepth (нигде ни в каком пути управления шейдером), я использую механизм записи буфера глубины по умолчанию. То есть нарисовать что-то фрагментным шейдером, который может отбрасывать фрагменты или нет. Фрагментный шейдер включает Early_fragment_tests. Я хотел убедиться, что мой фрагмент не обновит буфер глубины значением глубины (вычисленным до фрагментного шейдера). - person Jean-Simon Brochu; 07.11.2013
comment
@Jean-SimonBrochu: я никогда не говорил, что ты писал gl_FragDepth. Я объяснял вам, почему запись глубины не может быть выполнена до полного выполнения шейдера; есть два обстоятельства, discard и запись на gl_FragDepth. Если ваш шейдер не содержит ни того, ни другого, то эта оптимизация возможна, но если он содержит любой из них, запись глубины происходит только после полного выполнения шейдера. В любом случае, вы не используете стандартный механизм записи глубины, если ваш шейдер содержит discard, как я пытался указать, ранние тесты фрагментов в этой ситуации не определены. - person Andon M. Coleman; 08.11.2013
comment
@Jean-SimonBrochu: Конечно, если вы не используете консервативное расширение глубины, на которое я указал. Затем ранние тесты фрагментов будут работать в шейдере, который изменяет глубину после выполнения. Отбрасывание фрагмента — это, кстати, модификация глубины — глубина, сгенерированная при растеризации, — это не то, что записывается после оценки шейдера. - person Andon M. Coleman; 08.11.2013

Я думаю, что информация, которую вы ищете, находится на этой странице:

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

Слово «может» в «буфер глубины [и т. д.] может быть обновлено» подразумевает, что это зависит от реализации (или полностью случайно).

person GuyRT    schedule 06.11.2013
comment
Да, я читал эту информацию, но мне показалось, что речь идет о фрагментах, которые отбрасываются после выполнения фрагментного шейдера, а не по ключевому слову discard. Поправьте меня если я ошибаюсь. Я где-то читал, что это из-за устаревшего статуса альфа-тестов. - person Jean-Simon Brochu; 06.11.2013
comment
Формулировка этого абзаца открыта для интерпретации, но я думаю, что операции над фрагментами, такие как альфа-покрытие или альфа-тесты. может включать использование discard во фрагментном шейдере. Я должен признать, что я перевел альфа-тесты в цитируемом абзаце на использование discard в своей голове, потому что в данный момент я много работаю с OpenGL ES 2 (где discard — единственный способ выполнить альфа-тест). - person GuyRT; 07.11.2013
comment
@GuyRT: Честно говоря, вы должны перевести это именно так. Это единственный способ реализовать альфа-тесты в современном OpenGL. Это не значит, что на графических процессорах есть специальное оборудование для альфа-тестирования, это просто дополнительный багаж реализации, который возникает после затенения фрагментов в профилях совместимости. Поскольку это можно сделать во фрагментном шейдере, он был удален из ES 2.0 и GL 3.0. - person Andon M. Coleman; 07.11.2013
comment
То, что будет отброшено после выполнения фрагментного шейдера, заставляет меня поверить, что есть до и во время. Следовательно, НЕ включая ключевое слово discard. И на самом деле, после проведения некоторых тестов, похоже, это действительно так. Я проведу больше тестов на другом оборудовании и опубликую результаты. - person Jean-Simon Brochu; 07.11.2013
comment
@Jean-SimonBrochu: Вы правы, есть до и во время. Когда примитивы растрируются, они имеют известную глубину до выполнения фрагментного шейдера. Вы также можете записать произвольную глубину в gl_FragDepth или discard глубину, сгенерированную во время растеризации во фрагментном шейдере. Если ваш шейдер делает одно из этих двух действий, реализация OpenGL не может записывать значение глубины перед выполнением шейдера. На самом деле, early_fragment_tests на самом деле не работает в шейдере, который делает любую из этих двух вещей (по крайней мере, не часть теста глубины... трафарет может). - person Andon M. Coleman; 08.11.2013
comment
@ AndonM.Coleman: Вы уверены, что ситуация одинакова, когда квалификатор early_fragment_tests используется в шейдере по сравнению с ранней оптимизацией z (которая отключена при наличии discard)? Кажется странным, что реализациям предоставляется свобода действий для обновления или нет буфера глубины при сбое альфа-теста, но не предоставляется такая же свобода для фрагментов discarded. Жаль, что эта проблема не рассматривается явно в спецификации shader_image_load_store. - person GuyRT; 08.11.2013
comment
@GuyRT: у меня разное поведение с двумя картами NVidia с одинаковой версией драйвера. - person Jean-Simon Brochu; 04.04.2014