我在获取我存储在Float纹理中的深度值时遇到了一些麻烦(或者我不理解这些值)。基本上我正在创建一个deffered渲染器,并且在其中一个传递中,我将深度存储在浮点渲染目标的alpha分量中。该着色器的代码看起来像这样
将剪辑位置定义为变化
varying vec4 clipPos;
... 在顶点着色器中指定位置
clipPos = gl_Position;
现在在片段着色器中我存储了深度:
gl_FragColor.w = clipPos.z / clipPos.w;
这个大体上的作品。当我在任何后续着色器中访问此渲染目标时,我可以获得深度。我是这样的:
float depth = depthMap.w;
我是否正确地假设0.0正好在相机前面且1在远处?因为我正在做一些基于此的雾计算,但它们似乎不正确。
fogFactor = smoothstep( fogNear, fogFar, depth );
fogNear和fogFar是我发送到着色器的制服。当fogNear设置为0时,我原本以为我会从相机前面的平滑过渡到它的绘制距离。然而,这就是我所看到的:
当我将fogNear设置为0.995时,我会得到更像我期待的东西:
这是对的,它对我来说似乎不对吗? (几何尺度不是很小/太大,相机也不会太大或太大。所有值都非常合理)
答案 0 :(得分:3)
您的方法存在两个问题:
您假设深度在[0,1]的范围内,您使用的是clipPos.z / clipPos.w
,这是[-1,1]范围内的NDC z坐标。通过直接将窗口空间z坐标写入深度纹理(可能是[0,1]并且只是gl_FragCoord.z
),您可能会更好。
您假设线性深度映射的更严重问题。但事实并非如此。 NDC和窗口空间z值不是到相机平面的距离的线性表示。您在屏幕截图中看到的任何内容都非常接近于1并不奇怪。典型的雾计算是在眼睛空间进行的。但是,由于此处只需要z
坐标,因此您只需存储剪辑空间 w 坐标 - 因为通常情况下,这只是-z_eye
(请查看最后一行你的投影矩阵)。但是,结果值不会在任何规范化的范围内,而是在投影矩阵中使用的[near,far] - 但是在眼睛空间单位中指定雾距离(通常与世界空间单位不同)更直观