【发布时间】:2014-04-04 19:32:06
【问题描述】:
假设我有这个场景
我想从定制的片段着色器中添加深度信息。
现在要做的直观的事情是在我的茶壶上绘制一个四边形,而不启用深度测试,但使用 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。
在我不得不解决这个问题的时间很少的情况下,我只是在“添加深度通道”之前将当前深度缓冲区的内容复制到纹理。将其分配给统一的 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 值不变。
【问题讨论】:
-
您使用的是什么 OpenGL 版本?
-
这个问题可能和早z测试有关——在这种情况下,shader写入的深度值没有影响,甚至丢弃的片段也可能写入深度缓冲区(这在硬件方面非常有意义,因为测试和 Z 缓冲区更新通常是原子条件内存更新,而不是两个单独的步骤)。然而,一个实现应该表现得好像只有在您启用它时才使用早期 z 测试(它可能在“安全情况”下也使用它们,在这种情况下,片段着色器中不会发生丢弃和深度写入。)。跨度>
-
如果你说的是“early_fragment_tests”,它是没有启用的。我有另一个程序需要这个功能,但不是这个特定的。
-
您没有使用图像加载/存储,是吗?这隐含地启用了早期片段测试。
-
嗯,真的。我在将片段累积到链表中的过程中启用了早期片段测试。但是在我写入深度缓冲区的过程中,我只使用 imageLoad 方法加载该链表。我不知道这会隐含地启用早期片段测试。