有人能解释为什么从深度位置重建我的世界是不正确的?

我试图从深度纹理中重构片段着色器中的世界位置。 我通过了世界空间的8个平截点,并将它们插入片段中,然后从近到远插入深度:

highp float depth = (2.0 * CameraPlanes.x) / (CameraPlanes.y + CameraPlanes.x - texture( depthTexture, textureCoord ).x * (CameraPlanes.y - CameraPlanes.x)); // Reconstruct the world position from the linear depth highp vec3 world = mix( nearWorldPos, farWorldPos, depth ); 

CameraPlanes.x是近平面CameraPlanes.y是最远的。

假设我的平凡人的立场是正确的,我的深度看起来是正确的,为什么我的世界位置错了?

(我的深度纹理的格式是GL_DEPTH_COMPONENT32F,如果重要的话)

谢谢! :d

更新:

世界排名http://imgur.com/sSlHd的截图

所以你可以看到它看起来几乎是正确的。 然而,随着相机的移动,颜色(位置)改变,他们不应该。

可以得到这个工作,如果我做到以下几点:

把它写在前面的深度附件中:

 gl_FragDepth = gl_FragCoord.z / gl_FragCoord.w / CameraPlanes.y; 

然后读取深度纹理,如下所示:

 depth = texture( depthTexture, textureCoord ).x 

但是,这将终止硬件z缓冲区优化。

yuumei,我不相信你是计算中的视角鸿沟的原因。 你在第一个方程中正确地确定了图像平面的深度,然后使用一个简单的线性插值(mix())。

见条目12.070在这里 :

12.070为什么在深度缓冲区的前端有更高的精度?

在投影matrix变换剪辑坐标之后,XYZ顶点值除以它们的剪辑坐标W值,这导致归一化的设备坐标。 这一步被称为视角鸿沟。 剪辑坐标W值代表到眼睛的距离。 随着与眼睛的距离增加,1 / W接近0.因此,X / W和Y / W也接近于零,导致渲染的图元占用较less的屏幕空间并且看起来较小。 这就是计算机如何模拟透视图。

这就是为什么当你在另一个实现中除以第四个坐标时,结果是正确的。

顺便说一句,每当我从深度缓冲区计算世界空间位置,我使用的方法是检索图像平面深度(像你一样),然后投射一个光线与每个像素的相机属性,如下所示:

 //Get depth value to resolve depthValue d = depthValues[i]; //Compute clip-space coordinate of pixel float2 screenspace = ( (d.screenposition) / ((float2)(width,height)) ) * 2.0f - 1.0f; //Get direction of ray from camera through pixel float3 ray_direction = normalize(camera_forward.xyz + (camera_right.xyz * screenspace.x) - (camera_up.xyz * screenspace.y)); //Reconstruct world position from depth: depth in z buffer is distance to picture plane, not camera float distance_to_camera = d.depth / dot(ray_direction, camera_forward.xyz); float3 world_position = camera_position.xyz + (ray_direction * distance_to_camera); positions[i] = (float4)(world_position, 1); 

这不像在网上find的一些其他方法那样“简短” 但这总是对我有用,我不一定能说出同样的话!

祝你好运!

过了一会儿,我回到这个问题。 我正在使用OES_depth_texture扩展名。 我发现答案在这里解释得非常好: http : //www.opengl.org/wiki/Compute_eye_space_from_window_space#From_XYZ_of_gl_FragCoord

我用这个方法成功了。 不幸的是所有其他的方法都不起作用 最后,你会得到一个vec4 eyePos,你可以乘以逆视matrix到达世界空间。