在后期处理中从Float纹理获取深度

时间:2014-09-29 16:44:19

标签: opengl webgl

我在获取我存储在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时,我原本以为我会从相机前面的平滑过渡到它的绘制距离。然而,这就是我所看到的: enter image description here

当我将fogNear设置为0.995时,我会得到更像我期待的东西:

enter image description here

这是对的,它对我来说似乎不对吗? (几何尺度不是很小/太大,相机也不会太大或太大。所有值都非常合理)

1 个答案:

答案 0 :(得分:3)

您的方法存在两个问题:

  1. 您假设深度在[0,1]的范围内,您使用的是clipPos.z / clipPos.w,这是[-1,1]范围内的NDC z坐标。通过直接将窗口空间z坐标写入深度纹理(可能是[0,1]并且只是gl_FragCoord.z),您可能会更好。

  2. 您假设线性深度映射的更严重问题。但事实并非如此。 NDC和窗口空间z值不是到相机平面的距离的线性表示。您在屏幕截图中看到的任何内容都非常接近于1并不奇怪。典型的雾计算是在眼睛空间进行的。但是,由于此处只需要z坐标,因此您只需存储剪辑空间 w 坐标 - 因为通常情况下,这只是-z_eye(请查看最后一行你的投影矩阵)。但是,结果值不会在任何规范化的范围内,而是在投影矩阵中使用的[near,far] - 但是在眼睛空间单位中指定雾距离(通常与世界空间单位不同)更直观