当前位置: 首页 > 知识库问答 >
问题:

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

艾才良
2023-03-14

以下是我的情况:

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

此外,我还在我的G-Buffer FBO上附加了一个渲染缓冲区对象(RBO),该对象初始化为GL_DEPTH_STENCIL_ATTACHMENT(GL_DEPTH24_STENCIL8)。因此,在G缓冲区执行期间,我的4个纹理同时被填充,渲染缓冲区同时填充模具和深度缓冲区。

我有两个问题:

  • 出于任何原因,是否可以将此深度缓冲区用作片段着色器中的sampler2D均匀变量?例如,我可以在照明过程中使用它来计算某些内容(例如,从深度恢复视图空间中的顶点位置)?这将是一个增益的时间直接使用这个深度缓冲区

如果不可能:

  • 是否可以在MRT中填充深度纹理(GL_DEPTH_COMPONENT格式)?例如,是否可以使用MRT渲染技术填充深度纹理和颜色纹理?(我尝试过但没有成功,但可能被严重捕获)。我是否需要使用MRT填充我的颜色缓冲区和深度缓冲区(这里需要两个渲染通道而不是一个)?

如果再也不可能了,你有什么建议?

提前非常感谢你的帮助!

共有1个答案

夏侯阳
2023-03-14

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

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

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

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

可以在MRT中填充深度纹理(GL_depth_组件格式)吗?例如,是否可以使用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。)-

  •  类似资料:
    • 在DirectX中,您可以有单独的渲染目标和深度缓冲区,因此可以绑定渲染目标和一个深度缓冲区、执行一些渲染、移除深度缓冲区然后使用旧的深度缓冲区作为纹理进行更多渲染。 你会如何在opengl中做到这一点?根据我的理解,您有一个帧缓冲区对象,其中包含颜色缓冲区和可选的深度缓冲区。我不认为我可以同时绑定多个帧缓冲器对象,我是否必须在每次更改时(可能一帧几次)重新创建帧缓冲器对象?普通的 opengl

    • 我有一个正在开发的OpenGL应用程序。正在渲染的地形似乎没有遵循深度缓冲规则,所以我猜我在某个地方搞砸了 我的代码中有GL11.glEnable(GL11.GL_CULL_FACE) 这是飞机在没有四边形在另一个后面的情况下的样子,所以即使没有z缓冲区,事情看起来也很正常。请注意,这是从“自上而下”的视图中,其中“相机”在飞机上方 而现在,从不同的角度看 离场景最远的四边形正在更靠近计算机的四边

    • 我对openGL渲染很陌生,无论我做什么,深度深度都不起作用。我显然已经启用了深度测试(),并且我清除了每一帧的缓冲区。 但是 openGL 不断显示最后在其他人面前渲染的对象... 你可以在我的github上看到我的代码。这是两个相关的文件:主循环。我的主循环在,渲染在。 我正在使用java和lwjgl。

    • 我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是。 我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理? 能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码? 目前,我使用<code>glCopyTexSubImage2D<code>。我

    • 我在游戏中使用延迟渲染器。因此,第一个渲染过程是使用多个渲染rarget创建反照率和法线缓冲区,并填充深度缓冲区。所有这些缓冲区实际上都是纹理。 现在我想从其他渲染通道访问深度缓冲区,从而访问其他帧缓冲区,而不改变深度纹理。我只想读取深度值。对于这些通道,我主要绘制全屏四边形,我不希望他们更新深度纹理并将其消隐为深度值0。 如何将一个给定的深度纹理附加到另一个帧缓冲区,并确保它是只写的?

    • 本文向大家介绍emacs 文件和缓冲区,包括了emacs 文件和缓冲区的使用技巧和注意事项,需要的朋友参考一下 示例 在Emacs中,文件的含义与操作系统中的含义相同,并且用于永久存储数据。甲缓冲器是正在编辑的文件的内部表示。可以使用将文件读取到缓冲区中C-x C-f,并且可以使用C-x C-s(将文件保存到当前位置)或C-x C-w(将文件写入其他位置,提示输入-等效于Save as)将缓冲区写