如何将深度缓冲区复制到GPU上的纹理?

时间:2011-06-14 08:05:58

标签: opengl glsl depth

我想将当前深度缓冲区获取到纹理,以在着色器中访问它。由于各种原因,我无法进行单独的深度传递,但需要复制已经渲染的深度。

glReadPixels会涉及CPU并可能会扼杀性能,据我所知glBlitFramebuffer无法深入到颜色,只有深度到深度。

如何在GPU上执行此操作?

3 个答案:

答案 0 :(得分:7)

这样做的现代方法是使用FBO。为其附加颜色和深度纹理,渲染,然后禁用FBO并使用纹理作为将渲染到默认帧缓冲区的着色器的输入。

您可以找到有关FBO的所有详细信息here

答案 1 :(得分:5)

将深度缓冲区复制到纹理非常简单。如果您创建了一个未调用glTexImage *的新纹理,则可以使用glCopyTexImage2D。这会将像素从帧缓冲区复制到纹理。要复制深度像素,请使用GL_DEPTH_COMPONENT格式。我建议GL_DEPTH_COMPONENT24。

如果您之前已经创建了具有深度组件格式的纹理(即:在第一帧之后的任何时间),那么您可以使用glCopyTexSubImage2D直接复制到此图像数据中。

您似乎无法在着色器中访问深度组件纹理,因为您要复制深度到颜色(这是不允许的)。如果你是,那么这是一个问题你应该得到解决。

无论如何,复制应该是最后的方法。您应该尽可能使用framebuffer对象。只需直接渲染纹理。

答案 2 :(得分:3)

最佳方式是使用FBO,以获得更好的性能和一些编码风格问题。 如果您不感兴趣,请查看此代码。这是从我年轻的时候开始的!(并且不知道FBO存在)

int shadowMapWidth = 512;
int shadowMapHeight = 512;
glGenTextures(1, &m_depthTexture);

glBindTexture(GL_TEXTURE_2D, m_depthTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512,512);