2013-07-17 217 views
1

我正在为OpenGL ES 2.0,iOS开发一个简单的3D应用程序。在Open GL ES 2.0中从深度缓冲区获取黑色

我想要做的是我想在片段着色器的深度缓冲区中获取场景的深度值。

所以,我创建深度缓冲器作为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帧检查的深度缓冲器,调试器显示所有白色深度缓冲器(因为几乎所有的深度值是相当接近1.0这是正确的)。

那么,这里有什么问题?

回答

0

很难说没有更多的从你的应用程序设置的,但这里有一些猜测:

*设置GL_TEXTURE_COMPARE_MODE参数为您深度纹理GL_NONE。如果这是GL_COMPARE_R_TO_TEXTURE,它可能不会产生您所期望的。

*您真的只需要从纹理二维查找的第一个组件,因为存储单个值。 你可以在你的frag着色器试试这个:

gl_FragColor = vec4(texture2D(DepthBuffer, tex_coord).rrr, 1.0); 

我还考虑这些实验。

*手工检查纹理的内容,通过glReadPixels

*深度纹理的内容复制到一个颜色纹理,并尝试渲染(我建议glBlitFramebuffer,但它不提供ES 2.0)。你可以使用glReadPixels,然后使用glTexImage2D。

+0

感谢您的建议。但是,他们没有帮助:(而且,据我所知,glReadPixels不适用于ES 2中的深度附件。0 –

+0

glReadPixels上的好点。 我仍然对检查纹理数据感到好奇。您可以绑定呈现到深度纹理的FB,然后使用glCopyTexImage2D将其复制到虚拟颜色纹理中。然后你可以阅读! –

1

缩股利,

我已经运行到完全相同的问题,事实证明,在纹理过滤是问题。 尝试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棒棒糖

+1

从渲染目标纹理读取时,我在nvidia tegra硬件上遇到类似问题。 Tegra具有渲染目标纹理的地址模式限制: \t glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); \t glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); 可能相同的要求与深度缓冲区纹理有关。 – Dave