Доступ к текстуре трафарета глубины в программе шейдера

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

На первом проходе рендеринга я не только визуализирую информацию о цвете и глубине, но также использую операции трафарета для подсчета объектов. Для этого я использую мульти-рендер FBO с цветными буферами и комбинированным буфером трафарета глубины. Все они представлены в виде текстур (объекты буфера рендеринга не задействованы).

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

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

  • Можно ли привязать текстуру трафарета глубины к блоку текстуры для использования в программе шейдера? Невозможно получить доступ к глубине и текстурам трафарета с помощью "обычных" сэмплеров? Возможно ли это с каким-то "специальным" сэмплером? Зависит ли это от режима интерполяции, установленного на текстуре или аналогичных настроек?

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

Настройка текстур, используемых промежуточным FBO, следующая:

// The textures for color information (GL_COLOR_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// The texture for depth and stencil information (GL_DEPTH_STENCIL_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);

Во втором проходе рендеринга я сейчас пытаюсь только «отладить» содержимое всех текстур. Поэтому я устанавливаю шейдер со следующими значениями:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, <texture>);
glUniform1i(texLocation, 0);

и пусть программа шейдера просто скопирует текстуру на экран:

uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;

void main() {
    fragColor = texture2D(tex, texCoord);
}

Результаты следующие:

  • Когда <texture> выше относится к одной из моих цветовых текстур, я вижу вывод цвета, отображаемый на первом проходе рендеринга, чего я и ожидал.

  • Когда <texture> выше относится к текстуре трафарета глубины, шейдер ничего не делает (я вижу цвет, которым очищаю экран).

  • При копировании текстуры трафарета глубины в ЦП и ее изучении я вижу информацию о глубине и трафарете в упакованных 24 + 8-битных данных, как и ожидалось.


person leemes    schedule 03.10.2013    source источник


Ответы (1)


У меня нет опыта использования трафарета в качестве текстуры, но вы можете взглянуть на следующее расширение:

http://www.opengl.org/registry/specs/ARB/stencil_texturing.txt

Другой вариант - создать вид текстуры с помощью

http://www.opengl.org/registry/specs/ARB/texture_view.txt

Или вы можете подсчитывать объекты без буфера трафарета, возможно, используя MRT и аддитивное смешивание на второй цели рендеринга, используя:

http://www.opengl.org/registry/specs/EXT/draw_buffers2.txt

Но я боюсь, что эти опции не включены в чистый GL3.3 ...

person rotoglup    schedule 03.10.2013
comment
Спасибо, что указали мне на расширение! Я погуглил, что привело меня к следующему обсуждению: stackoverflow.com/a/13171346/592323. Таким образом, кажется, что мой второй подход является лучшим, если я не хочу использовать расширение. Поскольку мне нужен только результат одного теста, это хороший способ. Но, возможно, есть более быстрые способы, такие как необработанное копирование между 24 + 8-битным буфером с трафаретом глубины и 32-битным буфером цвета ARGB (тогда я бы просто прочитал синий компонент). Я не уверен, возможно ли это ... - person leemes; 04.10.2013
comment
Ваши варианты очень сильно зависят от версии GL, на которую вы нацеливаетесь. Который из них ? - person rotoglup; 04.10.2013
comment
Я пытаюсь вернуться к версии 3.3 в своем приложении и поэтому не хочу использовать какие-либо необычные расширения, которые могут быть недоступны в системах только с 3.3. Но меня обычно интересует несколько способов решения проблем. В настоящее время я решил проблему с помощью дополнительной текстуры копии трафарета, в которой я рисую выровненный по экрану четырехугольник с включенным тестом трафарета. Конечно, это возможно только потому, что меня интересуют только логические выражения. Если бы мне пришлось использовать числовое значение буфера трафарета в шейдере, это, конечно, не было бы решением. - person leemes; 04.10.2013
comment
Я понимаю вашу точку зрения. Чистый нерасширенный GL может быть целью, но более свежие расширения также могут быть представлены в том же классе оборудования с более новыми драйверами. Я отредактировал свой ответ, добавив еще несколько вариантов, о которых я мог подумать. - person rotoglup; 05.10.2013