是否可以使用 OpenGL 和 GLSL 在 MRT 上下文中填充深度缓冲区和颜色缓冲区?

Is it possible to fill both depth buffer and color buffer within a MRT context using OpenGL and GLSL?

这是我的情况:

我已经使用 MRT(多渲染目标)编写了一个小型延迟 3D 引擎来填充我的 G-Buffer(同时填充我所有的位置、法线、颜色和镜面纹理)。

此外,我已将初始化为 GL_DEPTH_STENCIL_ATTACHMENT (GL_DEPTH24_STENCIL8) 的渲染缓冲区对象 (RBO) 附加到我的 G-Buffer FBO。所以在 G-Buffer 执行期间,我的 4 个纹理同时填充,渲染缓冲区同时填充模板和深度缓冲区。

我有两个问题:

如果不可能:

如果再次不可能,你对我有什么建议?

非常感谢您的帮助!

Is it possible to use for any reasons THIS depth buffer as a sampler2D uniform variable within a fragment shader for example I could use to compute something during the lighting pass (for instance, recover vertex position in view-space from depth)? It would be a gain of time to use this depth buffer directly!

是的,深度缓冲区可以是片段着色器中的采样器,可以使用典型的 texture(depthTexture,...) 命令访问。

在典型的延迟渲染路径中,您首先编写 gBuffer(深度缓冲区是 gBuffer 的一部分),然后将所有 gBuffer 纹理绑定到采样器并在光照计算时使用它们。

如果你的意思是 'THIS' 深度缓冲区,你想对你正在写入的当前使用的深度缓冲区进行采样,那么这是不可能的。不能同时写入和读取纹理(此处 OpenGL ES 可能是个例外)。

Is it possible to fill a depth texture (GL_DEPTH_COMPONENT format) within a MRT? For example, is it possible to fill a depth texture and a color texture using MRT rendering technique ? (I tried without any success but maybe I got caught badly). Do I need to fill my color buffer using MRT, and the depth buffer separatly (two render passes are needed here instead of one)?

是的,正如我上面所说,这是典型的方式。只需将深度纹理附加到帧缓冲区的深度部分(或者如果它是深度+模板纹理,则将其附加到帧缓冲区的深度+模板部分)。参见 https://www.opengl.org/sdk/docs/man4/docbook4/xhtml/glFramebufferTexture.xml

更新

对不起,我没看懂你说的 RBO。

不,RBO 的深度缓冲区可以绑定到纹理采样器(因为它不是纹理)。有两种方法可以解决这个问题:

  • 使用 FBO 而不是附加了深度纹理的 RBO。 (推荐)
  • 将RBO的数据复制到深度纹理中。如果你真的想这样做,还有两种可能的方法:

    • 创建一个仅附加深度纹理的 FBO,然后使用 glBlitFramebuffers 将 RBO 复制到该纹理,参见:https://www.opengl.org/sdk/docs/man3/xhtml/glBlitFramebuffer.xml
    • 使用glReadPixel将深度缓冲区复制到CPU,然后将其复制回深度纹理。 (当然推荐使用 FBO 方法,因为它将是 GPU->GPU 传输。)