我正在尝试编写一个简单的GLSL着色器,将一个片段的真实(未标准化)深度呈现为浮点值。
到目前为止,我已经想出了如何获得顶点的深度,并且只是插入片段,但是我开始意识到这不会给我每个片段的正确深度,是吗?
以下是我到目前为止:
顶点着色器:
uniform mat4 world; uniform mat4 view; uniform mat4 projection; attribute vec3 position; attribute vec3 color; varying float distToCamera; void main() { vec4 cs_position = view * world * vec4(position, 1.0); distToCamera = -cs_position.z; gl_Position = projection * cs_position; }
片段着色器:
varying float distToCamera; void main() { gl_FragColor = vec4(distToCamera, distToCamera, distToCamera, 1.0); }
是的,您的Z值distToCamera在每个三角形的顶点都是正确的,但由于线性插值的原因,将不会在其他任何地方(Z值匹配的顶点之间除外)。
编辑:在当前的GLSL中,默认插值是“透视”,其中gl_Position / gl_FragCoord被考虑用于插值。 这可以被覆盖(你不会想要为你的情况)作为types限定符,如:
noperspective out float distToCamera; // vertex shader noperspective in float distToCamera; // fragment shader
或者,你可以得到它从gl_FragCoord恢复…
在片段着色器中, gl_FragCoord
在窗口坐标中包含(x, y, z, 1/w)
。 x,y和z已经被w除。
所以,你可以恢复你的顶点着色器输出, gl_Position.z
,在3D中正确插值,如
float originalZ = gl_FragCoord.z / gl_FragCoord.w;
(取决于你如何完成顶点着色器投影matrix,当然这可能不是你的世界Z.)