Запросы об окклюзии только с трафаретным тестом

Работают ли запросы на окклюзию, если я вообще отключаю тестирование глубины, когда заранее определено, что набор препятствий находится строго между камерой и объектом, который нужно проверить? Это попытка улучшить производительность, поскольку, по логике вещей, мне не нужны сложные z-тесты, если ни один из окклюдеров не находится за окклюзией.

Я использую следующие команды для инициализации буферов цвета / глубины / трафарета:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
...
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

glDisable(GL_CULL_FACE);

glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

glEnable(GL_STENCIL_TEST);
glStencilMask(0x00000001);
...
glClear(GL_STENCIL_BUFFER_BIT);

2 ответа

Решение

Наиболее убедительным документом является последняя спецификация OpenGL. Из спецификации OpenGL 4.5, раздел "17.3.7 Запросы окклюзии", на странице 476 (с акцентом, добавленным мной):

Запросы окклюзии используют объекты запросов для отслеживания количества фрагментов или образцов, которые проходят тест глубины.

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

Таким образом, возникает реальный вопрос: что значит "пройти тест глубины"? Проходит ли пиксель тест глубины, если нет теста глубины? И как тест трафарета вступает в игру?

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

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

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);

glEnable(GL_STENCIL_TEST);
...

Теперь будет ли он работать так, как нужно, без буфера глубины или с отключенным буфером глубины? Ответ на первую часть дан в конце раздела "17.3.6 Проверка буфера глубины":

Если буфера глубины нет, это как если бы тест буфера глубины всегда проходил.

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

Второй случай описан ранее в разделе "17.3.6 Проверка буфера глубины":

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

На рисунке 17.1 в спецификации показано "Окклюзионный запрос" в качестве следующей операции, следующей за "Тестом глубинного буфера". Поэтому все фрагменты, прошедшие более ранние тесты (включая трафарет), будут подсчитаны по окклюзионному запросу, если тест глубины отключен.

И окончательный ответ: ДА, вы можете использовать окклюзионные запросы только с помощью трафаретного теста.

Благодарность: последняя версия пересмотрена на основе отзывов @jozxyqk и @user2464424

От https://www.opengl.org/registry/specs/ARB/occlusion_query.txt

Это расширение решает обе эти проблемы [HP_occlusion_test]. В качестве результата возвращает количество образцов, прошедших тесты глубины и трафарета.

...

На какой именно стадии конвейера мы считаем образцы?

РЕШЕНО: Мы рассчитываем сразу после обоих тестов глубины и трафарета, то есть образцов, которые проходят оба. Обратите внимание, что проверка глубины проводится после проверки трафарета, поэтому достаточно сказать, что это число, которое прошло проверку глубины; хотя часто концептуально полезно думать о том, что тесты глубины и трафарета объединены, потому что результат теста глубины влияет на используемую операцию трафарета.

От https://www.opengl.org/registry/specs/ARB/occlusion_query2.txt

Это расширение тривиально добавляет запрос булевой окклюзии к ARB_occlusion_query

С выключенным тестом глубины я бы предположил, что все фрагменты пройдены Из вышесказанного звучит так, что вы можете положиться только на трафаретный тест, влияющий на результаты запроса окклюзии, что противоречит следующему на opengl.org/wiki.

Тест трафарета, альфа-тест или отбрасывание фрагмента шейдера не имеет отношения к запросам

Расширение не упоминает discard, В разделе запроса окклюзии в спецификациях ядра/ компиляции GL 4.5 упоминается только подсчет фрагментов, прошедших тест глубины. Если фрагмент не проходит тест на глубину, то, я думаю, он не считается пройденным.

Небольшое примечание, но я думаю, что стоит упомянуть и ранний фрагментный тест.

Другие вопросы по тегам