我正在为OpenGL ES 2.0,iOS开发一个简单的3D应用程序。
我想要做的是我想在片段着色器中获取深度缓冲区中场景的深度值。
所以,我创建了一个深度缓冲区作为2D纹理
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
self.Dimension = IVVec3I_Make(size.x, size.y, 0);
self.BufferObjID = texture;
并将其作为深度附件附加到帧缓冲区。
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, pRD.BufferObjID,0);
当我渲染场景时,深度缓冲区正常工作(深度测试和深度写入完全正常工作)。
但是,当我将深度缓冲区分配给着色器中的采样器并使用全屏四边形平面将深度缓冲区渲染到屏幕时,它全部为黑色。并且,着色器本身没有任何问题,因为当我为采样器指定另一个普通纹理时,它会正确渲染纹理。
这是片段着色器。
uniform sampler2D DepthBuffer;
void main()
{
highp vec2 tex_coord = vec2(gl_FragCoord.x/1024.0,gl_FragCoord.y/768.0);
tex_coord.y = 1.0-tex_coord.y;
gl_FragColor = texture2D(DepthBuffer, tex_coord);
}
当我通过捕获OpenGL ES Frame检查深度缓冲区时,调试器显示全部为白色的深度缓冲区(这是正确的,因为几乎所有深度值都非常接近1.0)。
那么,这可能有什么问题?
答案 0 :(得分:2)
我遇到了完全相同的问题,结果发现纹理过滤是个问题。 尝试GL_NEAREST,如下所示。
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT32F, texWidth, texHeight,
0, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_FLOAT, null);
GLES30.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES30.GL_TEXTURE_COMPARE_MODE, GLES20.GL_NONE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
注意:我使用的是GLES 3.0,但此修复程序也适用于2.0。 设备:HTC m8 t-mo Android 5.0 Lollipop
答案 1 :(得分:0)
如果您的应用程序没有更多设置,很难说,但这里有一些猜测:
*将深度纹理的GL_TEXTURE_COMPARE_MODE参数设置为GL_NONE。如果这是GL_COMPARE_R_TO_TEXTURE,它可能不会产生您期望的结果。
*您实际上只需要texture2D查找中的第一个组件,因为存储了单个值。 您可以在frag shader中尝试此操作:
gl_FragColor = vec4(texture2D(DepthBuffer, tex_coord).rrr, 1.0);
我也会考虑这些实验。
*通过glReadPixels
手动检查纹理的内容*将深度纹理的内容复制到颜色纹理中,然后尝试渲染(我建议使用glBlitFramebuffer,但它在ES 2.0中不可用)。您可以使用glReadPixels然后使用glTexImage2D。