OpenGL模板测试在碎片程序运行之前还是之后发生?

问题描述:

当我设置glStencilFunc(GL_NEVER, . . .)有效地禁用所有绘图,然后运行我的[shader-bound]程序时,我得到的性能并没有超过让片段着色器运行。我认为模板测试发生在片段程序之前。情况并非如此,或者至少不能保证?用一个简单地将常量写入gl_FragColor的片段着色器代替片段着色器会产生更高的FPS。OpenGL模板测试在碎片程序运行之前还是之后发生?

看看下面的大纲为DX10流水线,它说,模板测试像素着色器之前运行:

http://3.bp.blogspot.com/_2YU3pmPHKN4/Sz_0vqlzrBI/AAAAAAAAAcg/CpDXxOB-r3U/s1600-h/D3D10CheatSheet.jpg

和相同的是真正的DX11:

http://4.bp.blogspot.com/_2YU3pmPHKN4/S1KhDSPmotI/AAAAAAAAAcw/d38b4oA_DxM/s1600-h/DX11.JPG

我不知道这是在OpenGL规范中强制执行的,但是在运行片段程序之前执行不执行模板测试是不利的。

+0

根据此页面:http://www.opengl.org/wiki/Rendering_Pipeline_Overview#Pipeline如果在片段着色器中未修改深度,则模板和深度测试可以在片段着色器之前运行。但是,这似乎并没有发生在我的情况(我没有写入片段着色器中的gl_FragDepth)。 – david 2010-05-03 05:48:46

它实际上是两个。每个片段操作应该在片段程序之后发生,如您在此OpenGL ES 2.0 pipeline diagram中所看到的。然而,只要你没有写入片段着色器的深度,许多现代图形卡都有一个早期的z测试,可以提前丢弃这些片段。

这里是paper from AMD/ATI that talks about such tests。我记得读过规范允许早期测试,只要在着色器产生与之后的结果相同的结果之前进行测试,这就是为什么您不想在着色器中修改深度或丢弃片段的原因。这thread on OpenGL forums有一些有趣的讨论。

除了碎片深度修改之外,还有一些其他的东西可以防止在片段着色器之前发生深度/模板测试。如果启用了z-writes,则任何在着色器中放弃片段的方法都会执行此操作,例如alpha测试或着色器指令。

如果GPU想要在与z /模板写入相同的操作中执行模板/ z测试,则必须等到片元着色器执行后才知道允许片段写入z-缓冲。尽管这可能会因不同的卡而有所不同至少应该很容易判断它是否是你当前的问题。

正如你所看到的: http://www.opengl.org/wiki/Stencil_Test 模板测试在fragmentShader之后运行。 我知道这对性能不好。

+0

这是答案或评论吗? – 2012-12-18 08:28:32