GLSL从眼睛深度和屏幕位置计算世界坐标

时间:2014-11-01 15:57:19

标签: opengl glsl

我试图恢复一个点的世界位置,知道它在EYE空间中的深度,计算如下(在顶点着色器中):

float depth = - uModelView * vec4( inPos , 1.0 ) ;

其中inPos是世界空间中的一个点(显然,我不想恢复这一特定点,而是以这种格式表达深度的点)。

它的标准化屏幕位置(在0和1之间),计算如下(在片段着色器中):

vec2 screen_pos = ( vec2( gl_FragCoord.xy ) - vec2( 0.5 ) ) / uScreenSize.xy ;

我可以访问以下信息:

  • uScreenSize:正如它的名字所示,它的屏幕宽度和高度
  • uCameraPos:WORLD空间中的摄像机位置

和标准矩阵:

  • uModelView:模型视图相机矩阵
  • uModelViewProj:模型视图投影矩阵
  • uProjMatrix:投影矩阵

如何计算WORLD空间中某个点的位置(X,Y,Z)? (不在EYE空间)

我无法访问其他人(我无法使用近,远,左,右......)因为投影矩阵不限于透视或正交。

提前致谢。

1 个答案:

答案 0 :(得分:4)

我的问题是正确的,您有xy作为窗口空间(已经转换为规范化设备空间[-1,1]),但是z在眼睛空间中,并希望重新确立世界空间位置。

  

我无法访问其他人(我无法使用近,远,左,右......)   因为投影矩阵不限于透视或   正交的。

实际上,除了正交或投影映射之外没有太多可以通过均匀空间中的矩阵乘法来实现。然而,投影矩阵就足够了,只要它是可逆的(理论上,投影矩阵可以将所有点转换为平面,线或单点。在这种情况下,一些信息会丢失,它永远不会重建原始数据。但那将是一个非常不典型的案例。)

因此,您可以从投影矩阵和2D位置获得的内容实际上是眼睛空间中的 ray 。并且您可以将其与z=depth平面相交以获得回报。

所以你要做的就是计算两点

vec4 p = inverse(uProjMatrix) * vec4 (ndc_x,  ndc_y, -1, 1);
vec4 q = inverse(uProjMatrix) * vec4 (ndc_x,  ndc_y,  1, 1);

将在眼睛空间的光线上标记两个点。不要忘记将pq除以相应的w组件以获取3D坐标。现在,您只需将其与z=depth平面相交,即可获得视线空间xy。最后,您可以使用uModelView矩阵的逆矩阵将该点投影回对象空间。

然而,你说你想要世界空间。但这是不可能的。您需要使用view矩阵来执行此操作,但您尚未将其列为给定矩阵。您所拥有的只是modelview矩阵的 compisition ,您需要至少知道其中一个来重建世界空间位置。 cameraPosition不是enoguh。您还需要方向。