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

时间:2018-05-09 15:04:05

标签: c++ qt opengl opengl-es

有谁知道为什么'depth'(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 个答案:

答案 0 :(得分:1)

您的方法存在一些问题,主要内容是:

  1. gl_FragCoord.z是双曲线失真的窗口空间z值。但是,对于每个framgent,每个顶点的超级z/w值只是在屏幕空间中进行线性插值。但是当你使用变化的out float depth = (pos.z / pos.w)时,GL将进行非线性的透视校正插值。您可以使用flat out float depth

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

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