为什么 gl_FragCoord.z 与 ((pos.z / pos.w) + 1.0) * 0.5 不同?

Why differs gl_FragCoord.z from ((pos.z / pos.w) + 1.0) * 0.5?

本文关键字:pos 不同 gl FragCoord 为什么      更新时间:2023-10-16

>有谁知道为什么"深度"(vertShader(与"gl_FragCoord.z"(从opengl渲染(不同?特别是随着z的减小,差异变得更大。"深度"是否有可能在更高的z值上更精确?

.vsh
out float depth;
void main (void) {
vec4 pos = mvpMatrix * vertex;
depth = ((pos.z / pos.w) + 1.0) * 0.5;
gl_Position = pos;
}
.fsh
in float depth;
void main(void) {
gl_FragDepth = depth;// or gl_FragCoord.z;
}

您的方法存在几个问题,重点是:

  1. gl_FragCoord.z是双曲线扭曲的窗口空间 z 值。但是,每个顶点的双斜z/w值只是在每个顶点的屏幕空间中线性插值。但是当你使用一个变化的out float depth = (pos.z / pos.w)时,GL将进行非线性的透视校正插值。您可以使用flat out float depth来解决此问题。

  2. (pos.z/pos.w)甚至没有意义。想一想:如果点在相机所在的平面上,你会得到pos.w=0,并且没有有效的结果。gl_FragCoord.z没有这个问题,因为裁剪是在分割之前完成的,它将对位于近平面上的新顶点进行分割,并且您永远不会看到(没有顶点着色器调用(。

    当点位于相机后面时,也存在问题,它们最终会镜像到相机前面。如果你有一个基元,其中顶点位于相机的两侧,无论你选择哪种插值方法,你都会得到完全的废话作为你的插值depth值。