В «современных» средах расширение «NV Occlusion Query» предоставляет метод для получения количества фрагментов, прошедших тест глубины. Однако на iPad / iPhone, использующем OpenGL ES, расширение недоступно.
Каков наиболее эффективный подход для реализации аналогичного поведения во фрагментном шейдере?
Некоторые из моих идей:
Визуализируйте объект полностью белым, затем подсчитайте все цвета вместе, используя двухпроходный шейдер, где сначала отображается вертикальная линия, и для каждого фрагмента шейдер вычисляет сумму по всей строке. Затем отображается одна вершина, фрагмент которой суммирует все частичные суммы первого прохода. Кажется, не очень эффективно.
Сделать объект полностью белым на черном фоне. Рекурсивно уменьшать выборку, используя аппаратную линейную интерполяцию между текстурами, пока разрешение не будет достаточно маленьким. Это приводит к фрагментам, которые имеют уровень оттенков серого в зависимости от количества белых пикселей в соответствующей области. Это даже достаточно точно?
Используйте mipmaps и просто читайте пиксель на уровне 1x1. Опять же вопрос точности и возможно ли это даже при использовании текстур не-степени двух.
Проблема этих подходов заключается в том, что конвейер останавливается, что приводит к серьезным проблемам с производительностью. Поэтому я ищу более эффективный способ достичь своей цели.
Использование расширения EXT_OCCLUSION_QUERY_BOOLEAN
Apple представила EXT_OCCLUSION_QUERY_BOOLEAN в iOS 5.0 для iPad 2.
"4.1.6 Occlusion Queries Occlusion queries use query objects to track the number of fragments or samples that pass the depth test. An occlusion query can be started and finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT. When an occlusion query is started with the target ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is set to FALSE. While that occlusion query is active, the samples-boolean state is set to TRUE if any fragment or sample passes the depth test. When the occlusion query finishes, the samples-boolean state of FALSE or TRUE is written to the corresponding query object as the query result value, and the query result for that object is marked as available. If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may choose to use a less precise version of the test which can additionally set the samples-boolean state to TRUE in some other implementation dependent cases."
Первое предложение намекает на поведение, которое именно то, что я ищу: получить количество пикселей, которые прошли тест глубины асинхронным способом без значительного снижения производительности. Однако остальная часть документа описывает только то, как получить логические результаты.
Можно ли использовать это расширение, чтобы получить количество пикселей? Поддерживает ли это аппаратное обеспечение, так что может быть скрытый API для доступа к количеству пикселей?
Другими расширениями, которые могли бы быть использованы, были бы функции отладки, например, количество вызовов фрагмента шейдера (PSInvocations в DirectX - не уверен, что что-то похожее доступно в OpenGL ES). Однако это также приведет к остановке трубопровода.
источник
Ответы:
Нет и нет Ну, я предположил, что если вы рисуете серию треугольника размером в один пиксель в пространстве окна, вы можете посчитать, сколько булевых значений вы получите. Но для этого потребуется отдельный запрос для каждого пикселя. Наверное, не самая быстрая вещь в мире.
Если есть «скрытый API», у вас не будет доступа к нему (поскольку он скрыт), поэтому это не имеет значения. Кроме того, характер расширения уже предполагает, что нет. В конце концов, если у оборудования было фактическое количество фрагментов, почему бы просто не предоставить его напрямую, как это делает настольный OpenGL? Если бы оборудование поддерживало это, они могли бы просто взять ARB_occlusion_query и использовать это.
Но они этого не сделали. Что сильно говорит о том, что они не могли.
источник
Результаты возвращаются в GLuint (также может быть GLint для другого вызова), к сожалению, результат всегда равен 0 или 1, возможно, они изменят его для регистрации фрагов в будущем.
Кроме того, похоже, что ни один человек во всем Интернете не опубликовал об этих новых расширениях ... так что здесь они настроены правильно ... что нигде не документировано, насколько я могу судить ... вы можете представить, как они будет идти в вашем коде из этого маленького кода sudo здесь:
источник
GLint
, не означает, что это целое число числа проходящих фрагментов. Спецификация довольно ясно, чтоQUERY_RESULT_EXT
состояние является логическим значением; вы просто запрашиваете его как целое число. ЭтоGL_FALSE
если это не удалось, аGL_FALSE
если не прошло.