OpenGL-как получить доступ к значениям буфера глубины? - Или: гленкорд.Z и оказание глубина текстуры
Я хочу получить доступ к значению буфера глубины в текущем обрабатываемом пикселе в шейдере пикселей.
Как мы можем достичь этой цели? В принципе, есть два варианта:
- рендеринг глубины в текстуру. Как мы можем это сделать и в чем заключается компромисс?
- Используйте значение, предоставленное gl_FragCoord.з-но: это правильное значение?
2 ответов:
По вопросу 1: Вы не можете непосредственно читать из буфера глубины в шейдере фрагментов (если только нет последних расширений, с которыми я не знаком). Необходимо выполнить рендеринг для объекта Frame Buffer (FBO). Типичные действия:
- создайте и свяжите FBO. Если вы раньше не использовали FBO, найдите такие вызовы, как
glGenFramebuffersиglBindFramebuffer.- создайте текстуру или рендербуфер, который будет использоваться в качестве цветового буфера, и прикрепите его к точке прикрепления
GL_COLOR_ATTACHMENT0Вашего FBO с помощьюglFramebufferTexture2DилиglFramebufferRenderbuffer. Если бы вы только заботьтесь о глубине от этого прохода отрисовки, вы можете пропустить это и отрисовывать без цветового буфера.- создайте текстуру глубины и прикрепите ее к точке крепления
GL_DEPTH_ATTACHMENTFBO.- сделайте рендеринг, который создает глубину, которую вы хотите использовать.
- используйте
glBindFramebufferдля переключения обратно в буфер кадров по умолчанию.- свяжите текстуру глубины с сэмплером, используемым шейдером фрагментов.
- Теперь ваш шейдер фрагментов может выполнять выборку из текстуры глубины.
На вопрос 2:
gl_FragCoord.z- это значение глубины фрагмента, над которым работает шейдер, , а не текущее значение буфера глубины в позиции фрагмента.
gl_FragCoord.zявляется значением глубины оконного пространства текущего фрагмента. Это не имеет никакого отношения к значению, хранящемуся в буфере глубины. Значение может позже записывается в буфер глубины, если фрагмент не являетсяdiscarded и он проходит тест трафарета / глубины.Технически есть некоторые аппаратные оптимизации, которые будут записывать / тестировать глубину рано, но для всех намерений и целей
gl_FragCoord.zне является значением, хранящимся в буфере глубины.Если вы не рендерите в нескольких проходит, вы не можете читать и записывать в буфер глубины в шейдере фрагмента. Другими словами, вы не можете использовать текстуру глубины, чтобы прочитать глубину, а затем развернуться и написать новую глубину. Это сродни попытке реализовать смешивание в шейдере фрагментов, если вы не сделаете что-то экзотическое с оборудованием класса DX11 и загрузкой/хранением изображений, это просто не будет работать.
Если вам нужна только глубина последней нарисованной сцены для чего-то вроде теневого отображения, то вы можете сделать предварительный проход только по глубине чтобы заполнить буфер глубины. Во втором проходе вы будете читать буфер глубины, но не записывать в него.
Comments