【问题标题】:Getting Black Color from Depth Buffer in Open GL ES 2.0在 Open GL ES 2.0 中从深度缓冲区获取黑色
【发布时间】:2013-07-17 18:36:43
【问题描述】:

我正在为 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 帧检查深度缓冲区时,调试器将深度缓冲区全部显示为白色(这是正确的,因为几乎所有深度值都非常接近 1.0)。

那么,这里可能有什么问题?

【问题讨论】:

    标签: opengl-es-2.0 depth-buffer


    【解决方案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 Lollipop

    【讨论】:

    • 从渲染目标纹理读取时,我在 nvidia tegra 硬件上遇到了类似的问题。 Tegra 对渲染目标纹理有地址模式限制: glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);可能相同的要求与深度缓冲区纹理有关。
    • 谢谢你,我疯了。使用 GL_NEAREST 解决了我在绑定时读取 FBO 的深度纹理并将其设置为着色器统一(Nexus 5x、Adreno 418、Android 8.1.1)的问题,因此看起来这仍然是对较新设备和 Adreno 驱动程序的限制.
    【解决方案2】:

    如果没有应用程序的更多设置,很难判断,但这里有一些猜测:

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

    *您实际上只需要从 texture2D 查找中的第一个组件,因为正在存储单个值。 你可以在你的片段着色器中试试这个:

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

    我也会考虑这些实验。

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

    *将深度纹理的内容复制到颜色纹理中,然后尝试渲染它(我推荐 glBlitFramebuffer,但它在 ES 2.0 中不可用)。您可以使用 glReadPixels,然后使用 glTexImage2D。

    【讨论】:

    • 感谢您的建议。但是,他们没有帮助:(而且,根据我的知识,glReadPixels 不适用于 ES 2.0 中的深度附件
    • 关于 glReadPixels 的要点。我仍然对检查纹理数据感到好奇。您可以将渲染到深度纹理的 FB 绑定,然后使用 glCopyTexImage2D 复制到您的虚拟颜色纹理中。然后你可以从中阅读!
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    相关资源
    最近更新 更多