(gl_FragCoord.z/gl_FragCoord.w)代表什么?

Eng*_*eer 6 opengl glsl

我想要实际的世界空间距离,我从实验中得到了感觉

(gl_FragCoord.z / gl_FragCoord.w)

是世界空间的深度?但我不太确定.

编辑我刚刚找到了我最初找到这段代码的地方.显然它是相机的实际深度?

Nic*_*las 21

这是(由同一个人)提出并在其他地方回答.我在这里解释和修饰答案:

OpenGL 4.3核心配置文件规范(PDF)的第15.2.2节所述,gl_FragCoord.w1 / clip.w,clip.w剪辑空间位置的W组件(即:您写入的内容gl_Position)在哪里.

gl_FragCoord.z 由以下过程生成,假设通常的变换:

  1. 相机空间到剪辑空间变换,通过顶点着色器中的投影矩阵乘法. clip.z = (projectionMatrix * cameraPosition).z
  2. 转换为规范化设备坐标. ndc.z = clip.z / clip.w
  3. 使用glDepthRangenear/far值转换为窗口坐标.win.z = ((dfar-dnear)/2) * ndc.z + (dfar+dnear)/2.

现在,使用near = 0,far = 1的默认深度范围,我们可以win.z根据剪辑空间来定义:(clip.z/clip.w)/2 + 0.5.如果我们将其除以gl_FragCoord.w,则相当于乘以clip.w,从而给我们:

(gl_FragCoord.z / gl_FragCoord.w) = clip.z/2 + clip.w/2 = (clip.z + clip.w) / 2
Run Code Online (Sandbox Code Playgroud)

使用标准投影矩阵clip.z表示相机空间Z分量的比例和偏移.比例和偏移由相机的近/远深度值定义.clip.w再次在标准投影矩阵中,只是对相机空间Z的否定.因此,我们可以用这些术语重新定义我们的等式:

(gl_FragCoord.z / gl_FragCoord.w) = (A * cam.z + B -cam.z)/2 = (C * cam.z + D)
Run Code Online (Sandbox Code Playgroud)

其中AB代表基于近/远的偏移和比例,C = (A - 1)/2D = B / 2.

因此,gl_FragCoord.z / gl_FragCoord.w将摄像机空间(或世界空间)距离到相机.也不是摄像机空间与摄像机的平面距离.但它相机空间深度的线性变换.您可以将它用作将两个深度值进行比较的方法,如果它们来自相同的投影矩阵,依此类推.

要实际计算相机空间Z,您需要将相机从矩阵附近/远处传递(OpenGL 已经为您提供了近/远的范围)并从中计算这些AB值,或者您需要使用相反的投影矩阵.或者,您可以直接使用投影矩阵,因为片段着色器可以使用顶点着色器可用的相同制服.您可以直接从该矩阵中选择AB术语.A = projectionMatrix[2][2],和B = projectionMatrix[3][2].