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

使用帧缓冲区将深度缓冲区渲染为纹理

易书
2023-03-14

我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是glCopyTexSubImage2D

我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理?

能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码?

目前,我使用<code>glCopyTexSubImage2D<code>。我初始化纹理如下:

glGenTextures(1, &textureNo)
glBindTexture(GL_TEXTURE_2D, textureNo)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL)
glTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY)
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 2048, 2048, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, null)

然后我这样渲染:

glBindTexture(GL_TEXTURE_2D, textureNo)
glClear(GL_DEPTH_BUFFER_BIT)
drawScene()
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2048, 2048)

这很好,纹理最终保持了场景的深度通道——这意味着我的投影和视图矩阵设置正确,可以从光线的角度查看场景。我想改用帧缓冲对象。

我需要改变上面的什么来直接渲染到纹理而不是使用一个帧缓冲对象?

编辑:

这是我尝试的。我首先初始化了帧缓冲区对象:

glGenFramebuffers(1, &fbo)

然后我呈现如下:

glBindFramebuffer(GL_FRAMEBUFFER, fbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureNo, 0)
glBindTexture(GL_TEXTURE_2D, textureNo)
drawScene()

我已经确认,上述方法适用于GL_RGBGL_COLOR_ATTACHMENT0,但似乎不适用于GL_ DEPTH_COMPONENTtype纹理和GL_ DEPTH_attach-深度通道不会渲染到上述纹理textureNo

共有1个答案

章博耘
2023-03-14

假设这是所有FBO设置代码,我没有看到你称之为glCheckFramebufferStatus的部分。您知道,该函数会告诉您帧缓冲器对象不完整,因此渲染到它将失败。

具体来说,它会给你GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,因为你没有设置有效的绘图缓冲区。如果您不使用颜色附件,您需要使用glDrawBuffer来设置写入GL_NONE的所有颜色缓冲区。

这是一个常见的FBO陷阱;你不会是第一个没看过的人。但这也是为什么在修改FBO后务必检查< code > glCheckFramebufferStatus 的原因。

 类似资料:
  • 我做了一个在上面渲染天空盒和粒子的应用程序。我想添加一些效果,我需要使用帧缓冲区来渲染天空盒、粒子颜色、深度和位置以分离纹理。然后我想使用简单的着色器来使用这些纹理中的值并以适当的方式混合它们。我为纹理、帧缓冲区和屏幕四边形(渲染简单的矩形)编写了辅助类,但不幸的是——当我尝试使用它时没有任何渲染。 当绑定帧缓冲区被注释掉时,我的场景如下所示: 修改着色器表明深度和位置值计算正确。因此问题在于纹理

  • 我是OpenGL的新手。我想使用帧缓冲区读取并保存渲染场景中的所有深度值。我设法将其设置为附加到深度组件的帧缓冲区。但是当我将深度纹理渲染到默认帧缓冲区(显示窗口)时,它只显示白色,即使我线性化了深度值(教程从https://learnopengl.com/开始)。当我在默认帧缓冲区片段着色器中从gl_FragCoord. z访问深度值时,我会得到一个深度图,并且绘图也可以,但是当将深度作为纹理从

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

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

  • 这是更大项目的一部分,基本上,我用以下方式创建带有颜色、深度和模具缓冲区的帧缓冲区: 我用以下方法将其绑定: 当我转储附加的纹理: 我收到主帧缓冲区(0)的内容。 知道我哪里错了吗?先谢谢你。

  • 对于SSAO效果,我必须生成两种纹理:法线(在视图空间中)和深度。 根据微软教程(阅读深度模板缓冲区作为纹理章节),我决定使用深度缓冲区作为纹理。 不幸的是,渲染后我从深度缓冲区(下图)中没有得到任何信息: 我想这是不对的。奇怪的是,深度缓冲区似乎有效(我得到了正确的人脸顺序等)。 深度缓冲区代码: 使用第一遍渲染后,我将深度模板与其他渲染目标(颜色、法线)一起设置为纹理资源,将其附加到数组: 在