【问题标题】:Access depth-stencil texture in a shader program在着色器程序中访问深度模板纹理
【发布时间】:2013-10-10 18:20:45
【问题描述】:

似乎很难找到有关如何在连续渲染通道的着色器中访问深度和模板缓冲区的信息。

在第一次渲染过程中,我不仅渲染颜色和深度信息,还使用模板操作来计算对象。为此,我使用了多渲染目标 FBO,并附加了颜色缓冲区和组合深度模板缓冲区。所有这些都是纹理的形式(不涉及渲染缓冲区对象)。

在第二次渲染过程中(渲染到屏幕时),我想访问先前计算的基于每个像素的模板索引(但不一定是我当时正在绘制的相同像素),就像你想要的那样访问之前渲染的颜色缓冲区以应用一些后期处理效果。

但我未能将第二遍中的深度模板纹理作为制服绑定到我的着色器程序。至少只从中读取黑色值,所以我它没有正确绑定。

  • 是否可以将深度模板纹理绑定到纹理单元以在着色器程序中使用?使用“普通”采样器是否无法访问深度和模板纹理?是否可以使用一些“特殊”采样器?是取决于贴图上设置的插值模式还是类似的设置?

  • 如果不是,在这两个渲染通道之间将模板信息复制到单独的颜色纹理中的最佳(最快)方法是什么?可能涉及使用模板测试绘制单一颜色的第三次渲染通道(我只需要在最终渲染通道中使用 binary 版本的模板缓冲区,准确地说,我需要测试该值是否为零)。

中间 FBO 使用的纹理设置如下:

// The textures for color information (GL_COLOR_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// The texture for depth and stencil information (GL_DEPTH_STENCIL_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);

在第二个渲染过程中,我目前只尝试“调试”所有纹理的内容。因此,我使用这些值设置着色器:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, <texture>);
glUniform1i(texLocation, 0);

让着色器程序简单地将纹理复制到屏幕上:

uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;

void main() {
    fragColor = texture2D(tex, texCoord);
}

结果如下:

  • 当上面的&lt;texture&gt; 引用我的一个颜色纹理时,我看到在第一个渲染通道中渲染的颜色输出,这是我所期望的。

  • &lt;texture&gt; 上面提到深度模板纹理时,着色器不做任何事情(我看到了我清除屏幕时使用的颜色)。

  • 在将深度模板纹理复制到 CPU 并对其进行检查时,我可以在打包的 24 + 8 位数据中看到深度和模板信息。

【问题讨论】:

    标签: opengl textures rendering glsl depth-buffer


    【解决方案1】:

    我没有使用模板作为纹理的经验,但您可能想看看以下扩展:

    http://www.opengl.org/registry/specs/ARB/stencil_texturing.txt

    另一种选择是使用

    创建纹理视图

    http://www.opengl.org/registry/specs/ARB/texture_view.txt

    或者您可以在没有模板缓冲区的情况下计算对象,可能使用 MRT 并在第二个渲染目标上使用附加混合:

    http://www.opengl.org/registry/specs/EXT/draw_buffers2.txt

    但恐怕这些选项不包含在纯 GL3.3 中...

    【讨论】:

    • 感谢您指向我的扩展!我用谷歌搜索了它,这导致我进行了这个讨论:stackoverflow.com/a/13171346/592323。因此,如果我不想使用扩展,我提到的第二种方法似乎是最好的。因为我只需要一次测试的结果,这是一个好方法。但也许有更快的方法,比如在深度模板 24+8 位缓冲区和 ARGB 颜色 32 位缓冲区之间进行原始复制(然后我只需读取蓝色分量)。我不确定这是否可能......
    • 您的选择很大程度上取决于您所针对的 GL 版本。是哪一个?
    • 我尝试在我的应用程序中支持回到 3.3 版,因此不想使用任何在只有 3.3 的系统上可能不可用的花哨的扩展。但我通常对不止一种解决问题的方法感兴趣。我目前通过额外的“模板复制”纹理解决了这个问题,在该纹理中我绘制了一个启用了模板测试的屏幕对齐四边形。当然,这只是可能的,因为我只对布尔表达式感兴趣。如果我要在着色器中使用模板缓冲区的数值,这当然不是解决方案。
    • 我明白你的意思。纯未扩展的 GL 可以成为目标,但更新的扩展也可以在具有更新驱动程序的同一类硬件中公开。我编辑了我的答案,增加了一些我可以考虑的选项。
    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多