【问题标题】:Is it possible to fill both depth buffer and color buffer within a MRT context using OpenGL and GLSL?是否可以使用 OpenGL 和 GLSL 在 MRT 上下文中填充深度缓冲区和颜色缓冲区?
【发布时间】:2015-10-22 05:25:49
【问题描述】:

这是我的情况:

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

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

我有两个问题:

  • 是否可以出于任何原因将这个深度缓冲区用作片段着色器中的 sampler2D 统一变量,例如我可以用来在光照过程中计算某些东西(例如,从深度恢复视图空间中的顶点位置)?直接使用这个深度缓冲区会节省时间!

如果不可能:

  • 是否可以在 MRT 中填充深度纹理(GL_DEPTH_COMPONENT 格式)?例如,是否可以使用 MRT 渲染技术填充深度纹理和颜色纹理? (我试过但没有成功,但也许我被抓得很厉害)。我是否需要分别使用 MRT 填充颜色缓冲区和深度缓冲区(此处需要两个渲染通道而不是一个)?

如果这不可能再次发生,你有什么建议?

非常感谢您的帮助!

【问题讨论】:

  • 你到底遇到了什么问题?是否设法创建具有深度(+模板)内部格式的纹理并将其附加到您的 FBO 的深度(+模板)连接点?那么您是否设法在着色器中正常使用该纹理(绑定到 TU 并使用普通的texture(depthSampler, coordinates); 调用使用sampler2D 进行采样)?

标签: opengl glsl shader


【解决方案1】:

是否可以出于任何原因将此深度缓冲区用作 sampler2D 片段着色器中的统一变量,例如我可以用来 在光照过程中计算一些东西(例如,恢复 从深度来看视图空间中的顶点位置)?这将是时间的收获 直接使用这个深度缓冲区!

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

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

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

是否可以填充深度纹理(GL_DEPTH_COMPONENT 格式) 在地铁内?例如,是否可以填充深度纹理和 使用 MRT 渲染技术的颜色纹理? (我试过没有任何 成功,但也许我被抓得很厉害)。我需要填充我的颜色吗 使用 MRT 的缓冲区和单独的深度缓冲区(两个渲染通道 这里需要而不是一个)?

是的,正如我上面所说,这是典型的方式。只需将深度纹理附加到帧缓冲区的深度部分(或者如果它是深度+模板纹理,则将其附加到帧缓冲区的深度+模板部分)。见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 传输。)

【讨论】:

  • “一个纹理不能同时写入和读取”是什么意思。我知道这是不可能的,就我而言,我不会那样做。在材质传递期间,我将数据写入我的 g-buffer(深度纹理从 RBO 填充)并在光照传递期间读取 G-Buffer。我的问题是:是否可以在光照传递期间绑定(使用glBindTexture)深度缓冲区,就像其他颜色缓冲区的情况一样->在我的光照像素着色器中用作采样器的正常、颜色、镜面反射)->我的意思是深度使用 RBO 填充的缓冲区不是单独的深度缓冲区。提前致谢。
  • 换句话说,是否可以通过绑定从渲染缓冲区访问深度缓冲区?我不这么认为,但我不确定这一点!对我来说,我认为有两种方法可以存储深度信息并通过纹理绑定在照明通道中使用它:在单独的通道中渲染到经典深度纹理中,或者这次在 MRT 上下文中将深度信息存储到颜色缓冲区 (rgb) !我对此有何看法?
  • 实际上,我使用附加到我的 FBO 的 RBO 进行深度测试(确定每个像素处最近的表面),并使用模板缓冲区来定位片段着色器的使用(G-Buffer{position,正常、颜色、镜面反射 + {RBO{深度、模板}}})。所以你的第一个解决方案会很好,但我会失去模板缓冲区的使用。我知道使用模板缓冲区抛出 FBO 的唯一方法是将 RBO GL_DEPTH24_STENCIL8 附加到它。这就是为什么我建议将 RBO 用于深度测试和模板操作,并使用颜色纹理来存储深度信息。你怎么看?
  • 我找到了这个教程gamedevs.org/uploads/deferred-shading-tutorial.pdf。请参阅第 12 页有关材料通行证的内容。再次感谢您的反馈!
  • GL_DEPTH24_STENCIL8 是一种有效的纹理格式,可以使用glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,textureId,0) .opengl.org/wiki/Image_Format#Depth_stencil_formats 直接附加到FBO 上
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
相关资源
最近更新 更多