我正在使用片段着色器,使用 discard 关键字丢弃某些片段。我的着色器还使用* early_fragment_tests *(图像存储加载权限)。
编辑: 我没有写gl_FragDepth,我让标准OpenGL处理深度值。
在执行discard关键字之前,我的深度缓冲区是否会更新片段的深度?
编辑: 我的NVidia Quadro 600和K5000上似乎没有 。
我能找到这些信息的任何线索吗?仅供参考,我搜索了http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt。我找到了足够接近但不是那个特别的主题。
答案 0 :(得分:3)
在执行discard关键字之前,我的深度缓冲区是否会使用片段的深度进行更新?
不,在包含discard
或将任意值写入gl_FragDepth
的着色器中明确禁止此类行为。这是因为在这样的着色器中,片段在着色后的深度可能与初始光栅化(预着色)期间生成的位置无关。
无需写入gl_FragDepth
或丢弃,片段的深度实际上早在实际片段着色器执行之前就知道了,这就形成了早期深度测试的基础。如果可以确定在 之前 片段着色器,则可以跳过某些(单个平铺区域)或所有基元的光栅化/着色评估,但如果片段着色器本身是决定片段深度的,那么所有的赌注都会关闭。
DX11 / OpenGL 4.x中的此规则有例外。如果您以这样的方式编写着色器,即可以保证输出深度始终保留深度测试的结果(与光栅化期间生成的深度相同),可以在使用{{1的着色器 - 的着色器中启用早期片段测试或写入discard
。此功能称为 conservative depth ,除非您使用此功能,否则通常会理解gl_FragDepth
将彻底打破早期深度优化。
现在,因为在你知道你正在编写的值是否通过深度测试(discard
可能不同)或者片段是否存活之前你永远不应该写入深度缓冲区({{1}可以使用),你可以看到为什么包含gl_FragDepth
的片段着色器着色的原语在评估着色器之前无法写入深度缓冲区。
答案 1 :(得分:1)
我认为您要查找的信息在该页面上:
如果启用了早期片段测试,则由计算的任何深度值 片段着色器无效。另外,深度缓冲,模板 缓冲区和遮挡查询样本计数甚至可以更新 片段着色器后将丢弃的片段或样本 由于每个片段操作(例如alpha-to-coverage或)而执行 alpha测试。
“深度缓冲区中的”可能“,[等]可能会更新”,意味着它依赖于实现(或完全随机)。