【发布时间】:2011-09-14 12:08:20
【问题描述】:
我想获取纹理的当前深度缓冲区,以便在着色器中访问它。由于各种原因,我无法进行单独的深度传递,但需要复制已经渲染的深度。
glReadPixels 会涉及 CPU 并可能会降低性能,据我所知,glBlitFramebuffer 不能将深度着色,只能着色深度。
如何在 GPU 上做到这一点?
【问题讨论】:
-
我也遇到了同样的问题,你解决了吗?
我想获取纹理的当前深度缓冲区,以便在着色器中访问它。由于各种原因,我无法进行单独的深度传递,但需要复制已经渲染的深度。
glReadPixels 会涉及 CPU 并可能会降低性能,据我所知,glBlitFramebuffer 不能将深度着色,只能着色深度。
如何在 GPU 上做到这一点?
【问题讨论】:
最好的方法是使用 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);
【讨论】:
将深度缓冲区复制到纹理非常简单。如果您创建了一个尚未调用 glTexImage* 的新纹理,则可以使用 glCopyTexImage2D。这会将像素从帧缓冲区复制到纹理。要复制深度像素,请使用 GL_DEPTH_COMPONENT 格式。我建议使用 GL_DEPTH_COMPONENT24。
如果您之前创建了具有深度分量格式的纹理(即:第一帧之后的任何时间),那么您可以使用 glCopyTexSubImage2D 直接复制到此图像数据中。
您似乎也无法在着色器中访问深度分量纹理,因为您想复制深度到颜色(这是不允许的)。如果你是,那么这是一个你应该解决的问题。
无论如何,复制应该是最后的手段。您应该尽可能使用帧缓冲区对象。只需直接渲染到您的纹理即可。
【讨论】:
执行此操作的现代方法是使用 FBO。将颜色和深度纹理附加到它,渲染,然后禁用 FBO 并将纹理用作着色器的输入,该着色器将渲染到默认帧缓冲区。
您需要的有关 FBO 的所有详细信息都可以在 here 找到。
【讨论】: