如何从视图矩阵获取翻译


11

如何从摄像机的视图矩阵中检索摄像机的世界空间位置?我对这个问题所见的唯一答案表明翻译是在最后一行/列中,但由于矩阵包含[x(右)点,y(向上),z(点)外观),因此该操作无效。

Answers:


10

简短答案

首先反转视图矩阵。然后从最后一行/列获取翻译。

长答案

推导视图矩阵内容的一种方法是,首先将摄像机视为世界上的任何其他对象,然后为其计算世界矩阵:

RightX  RightY  RightZ  0
UpX     UpY     UpZ     0
LookX   LookY   LookZ   0
PosX    PosY    PosZ    1

世界矩阵将坐标从局部空间转换为世界空间。但是在这种情况下,相机的局部空间和视图空间是相同的,因此我们也可以说此矩阵将坐标从视图空间转换为世界空间。

由于我们需要在相反方向上进行转换,因此我们必须将矩阵求逆。结果就是所谓的视图矩阵,该矩阵将坐标从世界空间转换为视图空间:

   RightX        UpX        LookX      0
   RightY        UpY        LookY      0
   RightZ        UpZ        LookZ      0
-(Pos*Right)  -(Pos*Up)  -(Pos*Look)  1      // * = dot product

这就是您所拥有的矩阵。因此,为了从中找回相机的位置,您首先需要将其反转,然后才能从最后一行(或列,具体取决于系统)获取转换。


1
为什么要先对矩阵求逆?如果您(希望)知道自己是行优先还是列优先,那么转换向量的位置应该很明显。
3Dave

7

首先,我强烈建议将位置单独存储为向量,这将使计算变得更容易。无论如何...

[x (dot) right, y (dot) up, z (dot) look]不是实际的视图矩阵。矩阵本身具有以下形式:

1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1

其中左上方的3x3矩阵表示旋转,比例等。所有相机的方向都在此完成。其余的行和列用于翻译以及一些我现在不打算讨论的其他复杂的透视图。

当您获得矩阵(假设它是4x4矩阵)时,转换将始终存储在最后一行或最后一列中,具体取决于您的矩阵类是行优先还是列优先。

您可能会感到困惑的是,您需要点积。发生的事情是简化了矩阵数学运算,在此堆栈溢出问题中还有更详细的答案:https : //stackoverflow.com/questions/349050/calculating-a-lookat-matrix

可以在这里找到解决方案,您需要对矩阵求逆并得到其转换结果:

Vector3 ViewTrans = Matrix.Invert(ViewMatrix).Translation;
Position = ViewTrans;

5

此处的其他答案说明了如何从相机矩阵逆获得相机位置。

如果照像机矩阵的3x3部分像通常那样只有旋转(没有缩放或剪切),则可以通过将照像机矩阵平移与照像机旋转的转置相乘来优化计算。然后,将摄影机位置乘以转换后的平移矢量乘以-1。在GLSL中,这是:

vec3 cameraPosition = -transpose(mat3(worldToCameraMatrix)) * worldToCameraMatrix[3].xyz;

要么

vec3 cameraPosition = -worldToCameraMatrix[3].xyz * mat3(worldToCameraMatrix);

如果我不想以统一的方式计算和传递相机位置,这就是我在顶点着色器中一直使用的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.