我们说我有这个场景
我想从自定义片段着色器中添加深度信息。
现在直观的做法是在没有启用深度测试但是使用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值保持不变。
答案 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