我正在尝试从延迟渲染器中的深度值中重建3D世界坐标,但是时间太长了。我在网上找到的大多数示例都假设标准的透视变换,但是我不想做这个假设。
在我的几何图形通过顶点着色器中,我使用以下公式计算gl_Position:
gl_Position = wvpMatrix * vec4(vertexLocation, 1.0f);
在我的光照通过片段着色器中,我尝试使用以下方法获取世界坐标:
vec3 decodeLocation()
{
vec4 clipSpaceLocation;
clipSpaceLocation.xy = texcoord * 2.0f - 1.0f;
clipSpaceLocation.z = texture(depthSampler, texcoord).r;
clipSpaceLocation.w = 1.0f;
vec4 homogenousLocation = viewProjectionInverseMatrix * clipSpaceLocation;
return homogenousLocation.xyz / homogenousLocation.w;
}
我以为我做对了,确实,照相机附近的物体似乎被正确照明。但是我最近意识到,当我走得更远时,物体被照亮,好像它们离摄像机比实际距离更远。我一直在玩我的照明通行证,并验证了我的世界坐标是唯一被错误计算的东西。
我忍不住以为我的clipSpaceLocation.z和clipSpaceLocation.w是问题的根源,但是我已经尝试了我能想到的所有变化来计算它们,并且上面的代码产生了最正确的结果。
有什么想法或建议吗?
最佳答案
我只需要做一个小小的修正。该行:
clipSpaceLocation.z = texture(depthSampler, texcoord).r;
应该读:
clipSpaceLocation.z = texture(depthSampler, texcoord).r * 2.0f - 1.0f;
据我了解,投影矩阵的设计使其可以将近平面和远平面映射到[-1,1],而不是像我一直假设的那样[0,1]。然后,OpenGL将它们标准化为[0,1]范围(也称为“窗口空间”),因此我需要执行该标准化的逆操作。
所有这些都假设glDepthRange(0,1),默认情况下是默认值,没有什么理由更改它。
关于opengl - 从深度缓冲区和任意 View 投影矩阵重建世界坐标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22360810/