Получить количество фрагментов в каждом примитиве - PullRequest
0 голосов
/ 19 февраля 2020

Есть ли способ получить количество фрагментов (пикселей) перед проверкой глубины для каждого примитива (треугольника)? Я пытался использовать запросы opengl, но они, кажется, очень медленные.

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

1 Ответ

1 голос
/ 19 февраля 2020

Вы хотите количество фрагментов до теста глубины? Нет никакого способа сделать это вообще. Не гарантированно.

См., Хотя в спецификации говорится, что тесты глубины выполняются после фрагментного шейдера, может быть дорогостоящим запуск сложной FS, результаты которой отбрасываются из-за простого теста. Таким образом, правило «как если бы» позволяет реализациям пытаться выполнить фрагментные тесты перед FS , если между ними не будет поведенческой разницы.

Однако, хотя существует явный механизм для включите силу ранних тестов фрагментов, обратный механизм для не предотвращает ранние тесты А без этого то, что вы хотите, невозможно.

Теперь, потому что ранние тесты - это оптимизация «как будто», если ваша FS делает что-то, что требует выполнения фрагментного шейдера перед тестом глубины , тогда вы бы заставили реализацию не оптимизировать выполнение ФС. Проблема в том, что единственным действием, которое гарантирует такую ​​вещь, будет изменение значения gl_FragDepth. Проверка глубины требуется для соблюдения значения gl_FragDepth шейдера фрагмента, поэтому проверка глубины должна выполняться после выполнения FS.

Проблема в том, что изменение gl_FragDepth означает изменение глубины сгенерированного фрагмента, что, вероятно, не то, что вы хотите. О, конечно, вполне возможно, что просто наличие gl_FragDepth = gl_FragCoord.z; в верхней части функции main вашей FS достаточно для реализации, чтобы отключить ранние тесты. Но особенно умный компилятор может заметить, что эта FS фактически оставляет значение gl_FragDepth без изменений, поскольку его значение по умолчанию действительно gl_FragCoord.z. И поэтому он все еще может пройти ранние тесты.

Даже что-то вроде gl_FragDepth = gl_FragCoord.z + 0; можно оптимизировать; в конце концов, компилятор может увидеть, что вы ничего не добавляете.

Если вы хотите предположить, что компилятор не настолько умен, чтобы оптимизировать gl_FragDepth = gl_FragCoord.z или какую-то похожую конструкцию, вы можете сфабриковать, что Вы хотите использовать существующую функциональность шейдера. Для увеличения счетчика фрагментов вы можете использовать функцию загрузки / сохранения изображения / 1043 * или функцию SSBO. Вспомогательные вызовы не выполняют эти операции, поэтому вам не нужно об этом беспокоиться.

И если вам действительно нужно количество фрагментов для каждого треугольника / линии / точки, вы можете использовать gl_PrimitiveID чтобы выяснить, на каком ты примитиве. Это значение будет увеличиваться, начиная с 0, если на предыдущей стадии обработки вершин не было с этим каких-либо проблем. Если геометрический шейдер существует, то значение gl_PrimitiveID не определено, если GS не записывает в него значение для этого примитива. Шейдеры тесселяции могут даже отбрасывать примитивы, которые могут влиять на неявное значение gl_PrimitiveID в фрагментном шейдере.

Но если вы не играете с этими этапами, тогда gl_PrimitiveID будет разумным значением .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...