我怎样才能添加"深度信息到主帧缓冲区

时间:2014-04-04 19:32:06

标签: opengl glsl

我们说我有这个场景 enter image description here

我想从自定义片段着色器中添加深度信息。

现在直观的做法是在没有启用深度测试但是使用glDepthMask(1)和glColorMask(0,0,0,0)的情况下在我的茶壶上绘制四边形。写一些片段gl_FragDepth并丢弃其他一些片段。

if ( gl_FragCoord.x < 100 )
    gl_FragDepth = 0.1;
else
    discard;

出于某种原因,在NVidia Quadro 600和K5000上它按预期工作但在NVidia K3000M和Firepro上(不记得哪一个),我丢弃的片段所覆盖的所有区域都被赋予了深度值四边形。

我不能保留丢弃的片段深度值吗?

编辑我找到了解决问题的方法。事实证明,正如Andon M. Coleman和Matt Fishman指出的那样,我启用了early_fragment_test但不是因为我启用了它,而是因为我使用了imageStore,imageLoad。

由于我必须解决问题的时间很短,我只是在&#34;添加深度传递之前复制了当前深度缓冲区的内容。到纹理。将其分配给统一的sampler2D。这是我的着色器中的代码:

if ( gl_FragCoord.x < 100 )
    gl_FragDepth = 0.1;
else
{
    gl_FragDepth = texture( depthTex, gl_PointCoord ).r;
    color = vec4(0.0,0.0,0.0,0.0);
    return;
}

这将写入一个完全透明的像素,其z值保持不变。

2 个答案:

答案 0 :(得分:2)

嗯,这听起来像是一个驱动程序错误 - 丢弃的碎片不应该打到深度缓冲区。您可以将原始深度缓冲区绑定为纹理,使用gl_FragCoord对其进行采样,然后将结果写回而不是使用discard。这将添加额外的纹理查找 - 但它可能是一个合适的解决方法。

编辑:来自GLSL 4.40 Specification的第6.4节:

  

只有片段着色器才允许使用discard关键字。有可能   在片段着色器中使用以放弃对当前操作的操作   分段。此关键字导致片段被丢弃,否   将发生对任何缓冲区的更新。控制流退出着色器,并且   后续的隐式或显式   当该出口不均匀时,衍生物是不确定的。它会   通常在条件语句中使用,例如:

     

if (intensity < 0.0) discard;

     

片段着色器可以测试片段   alpha值并根据该测试丢弃片段。但是,它   应该注意,覆盖测试发生在片段着色器之后   运行,覆盖测试可以更改alpha值。如果

(强调我的)

答案 1 :(得分:1)

发布单独的答案,因为我在OpenGL规范中找到了一些新信息:

  

如果启用了早期片段测试,则由计算的任何深度值   片段着色器无效。另外,深度缓冲,模板   缓冲区和遮挡查询样本计数甚至可以更新   片段着色器后将丢弃的片段或样本   由于每个片段操作(例如alpha-to-coverage或)而执行   alpha测试。

您是否启用了早期片段测试?更多信息:Early Fragment Test