写入 gl_FragDepth 后执行着色器

Shader execution after writing to gl_FragDepth

给定一个片段着色器修改片段的原始深度并写入gl_FragDepth。 如果此时深度测试失败,写入 gl_Fragdepth 后的代码是否仍会执行?

示例:

in float depth;
layout(depth_less) out float gl_FragDepth;
void main() {
  float newDepth = depth - someModification;
  gl_FragDepth = newDepth;
  A();
}

如果newDepth大于gl_FragDepth中的当前值,是否会执行A

如果是这样,在不使用自定义深度缓冲区的情况下,有什么替代方法可以阻止着色器在 A 中进行不必要的计算?

在您的示例中,只要 A() 对任何输出值有贡献,它就会始终执行,例如一种颜色(否则,编译器会将其作为优化删除)。深度测试是一个每个样本的操作,通常在片段着色器之后执行。 Under special circumstances,在片段着色器之前做这个测试是可以的,但是这需要片段着色器本身不写入gl_FragDepth.

你做的修改是统一的还是每个片段都不一样?如果它是统一的,您可以在几何着色器中进行——只需将深度修改应用于整个图元。然后你可以使用early-z。如果它基于每个片段,您可以尝试将当前深度渲染目标绑定为 readonly image,获取存储的深度值,在着色器中执行手动比较,如果失败则丢弃该片段。但是,我既不知道您是否真的可以将当前绑定的帧缓冲区的渲染目标绑定为图像,即使是只读的,也不知道这是否比仅执行 A() 的性能更高或更低。