这两种计算 LookAt 矩阵的方法有什么区别?
What's the difference between these two ways of computing a LookAt matrix?
我一直在尝试了解如何在给定相机位置、要查看的点和向上矢量的情况下构建视图矩阵。
我找到了两个教程,here and here,解释了这一点。但是,它们在构建视图矩阵的方式上有所不同。在前者中,他们创建平移和旋转,然后将它们相乘以获得视图矩阵。不过,在后者中,他们只是将翻译放在最后一行(列,取决于约定 row/col-major)。
所以我的问题是,为什么是这两种方式? lookAt 矩阵不是唯一的吗?以我的理解,经过大量阅读和思考,在我看来,第一篇博客的方法是正确的。我错过了什么吗?
(假设行优先顺序,因为这是我通常使用的顺序)
这样想:首先,你有一个未变换的世界,在某个位置有一个旋转的相机。你知道,为了从那个世界到达相机位于原点并指向 +z 或 -z 或你有什么的转换后的世界,你需要进行某种转换(因为相机是'在中心)和某种旋转(因为相机可以指向任何方向)。
由于当您围绕(相机)旋转的点位于原点时执行旋转最容易,因此您首先要平移相机以使其位于原点。矩阵如下所示:
1 0 0 -camera_x
0 1 0 -camera_y
0 0 1 -camera_z
0 0 0 1
执行此旋转后,相机位于中心。现在您可以旋转它,使其指向您想要的方向。旋转可以通过多种方式完成,所以我只给出一个占位符,而不是写一个实际的矩阵:
a b c 0
d e f 0
g h i 0
0 0 0 1
现在,我们如何组合这些矩阵来得到我们的视图矩阵?规则是将所有矩阵相乘,按从右到左的顺序。所以计算看起来像这样:
view = rotation * translation
因为你先平移,然后再旋转。
回答你的问题:如果你先旋转,然后平移,就像这样:
view = translation * rotation
那么 view
将等于:
a b c -camera_x
d e f -camera_y
g h i -camera_z
0 0 0 1
这是因为,当您使用纯平移矩阵变换矩阵时,您会得到原始矩阵,其中 xyz 偏移量添加到最后一列的前三个值。这可能是第二个教程试图做的。
但是,矩阵乘法不是可交换的。当以更简单的方式组装视图矩阵时(先平移,然后旋转),您不能只从旋转矩阵中减去相机位置,因为您正在旋转平移而不是平移旋转,这只是一件更复杂的事情用手做。在这种情况下,您需要将两个矩阵相乘。
我一直在尝试了解如何在给定相机位置、要查看的点和向上矢量的情况下构建视图矩阵。
我找到了两个教程,here and here,解释了这一点。但是,它们在构建视图矩阵的方式上有所不同。在前者中,他们创建平移和旋转,然后将它们相乘以获得视图矩阵。不过,在后者中,他们只是将翻译放在最后一行(列,取决于约定 row/col-major)。
所以我的问题是,为什么是这两种方式? lookAt 矩阵不是唯一的吗?以我的理解,经过大量阅读和思考,在我看来,第一篇博客的方法是正确的。我错过了什么吗?
(假设行优先顺序,因为这是我通常使用的顺序)
这样想:首先,你有一个未变换的世界,在某个位置有一个旋转的相机。你知道,为了从那个世界到达相机位于原点并指向 +z 或 -z 或你有什么的转换后的世界,你需要进行某种转换(因为相机是'在中心)和某种旋转(因为相机可以指向任何方向)。
由于当您围绕(相机)旋转的点位于原点时执行旋转最容易,因此您首先要平移相机以使其位于原点。矩阵如下所示:
1 0 0 -camera_x
0 1 0 -camera_y
0 0 1 -camera_z
0 0 0 1
执行此旋转后,相机位于中心。现在您可以旋转它,使其指向您想要的方向。旋转可以通过多种方式完成,所以我只给出一个占位符,而不是写一个实际的矩阵:
a b c 0
d e f 0
g h i 0
0 0 0 1
现在,我们如何组合这些矩阵来得到我们的视图矩阵?规则是将所有矩阵相乘,按从右到左的顺序。所以计算看起来像这样:
view = rotation * translation
因为你先平移,然后再旋转。
回答你的问题:如果你先旋转,然后平移,就像这样:
view = translation * rotation
那么 view
将等于:
a b c -camera_x
d e f -camera_y
g h i -camera_z
0 0 0 1
这是因为,当您使用纯平移矩阵变换矩阵时,您会得到原始矩阵,其中 xyz 偏移量添加到最后一列的前三个值。这可能是第二个教程试图做的。
但是,矩阵乘法不是可交换的。当以更简单的方式组装视图矩阵时(先平移,然后旋转),您不能只从旋转矩阵中减去相机位置,因为您正在旋转平移而不是平移旋转,这只是一件更复杂的事情用手做。在这种情况下,您需要将两个矩阵相乘。