0

我一直在研究游戏引擎,最近到了可以轻松创建 Camera 类来管理视图矩阵(或允许轻松切换到另一个)的地步。我从概念上知道它必须做什么,但是我遇到的麻烦是弄清楚如何围绕本地原点旋转(对于视图矩阵,它与乘以旋转矩阵的平移矩阵相同)。

我知道在直接模式下,你会

glTranslatef(x, y, z);   //move back to origin
glRotatef(angle, x_rot, y_rot, z_rot);   //turn using a quaternion
glTranslatef(-x, -y, -z);   //move back to original location

但我不确定这将如何转化为更现代的应用程序。你会做同样的事情,让一个平移矩阵回到原点,旋转,然后平移回来吗?对于您要旋转的每个对象?从我目前测试的结果来看,该方法适用于查看,但在 3D 空间中控制它很笨拙(我不确定如何不断调整旋转。将运动组件转换为单个 vec4,乘以旋转,应用于翻译,然后进行实际旋转?)

似乎有一种比我缺少的三个或更多 4x4 矩阵乘法更有效的方法。

这是尝试建议的解决方案后的特定部分。

4

2 回答 2

3

您可以做与您发布的序列基本相同的事情,而无需在运行时进行完整的矩阵乘法。由于转换矩阵非常简单,您可以手动进行乘法运算。作为R一个 3x3 旋转矩阵,并且p是您想要旋转的位置,您可以通过以下方式构建 4x4 矩阵:

  1. 存储R在 4x4 矩阵的旋转部分。
  2. 计算p - R * p,并将结果存储在 4x4 矩阵的平移部分。

这会将其减少为一个矩阵 * 向量乘法和一个向量减法。您可能想仔细检查我的数学,因为我只是在纸上得出它。

另一种方法是在 CPU 代码中保持旋转和平移分开,根据需要更新它们,并且仅在更新制服时将它们组合成 4x4 矩阵。

由于您可以控制着色器代码,因此您甚至不必使用 4x4 矩阵来包含整个转换。例如,如果在旋转之前应用平移更方便,您可以将 mat3 旋转矩阵和 vec3 平移向量输入着色器,并将平移向量添加到与旋转矩阵相乘之前的位置。如果您更新其中一个比另一个更频繁,则将两者分开也可能是有益的。

于 2014-04-27T04:49:15.087 回答
0

我认为您通过考虑旧管道将其过度复杂化。

形成新的变换矩阵 T。假设您有现有的相机矩阵 C。您需要 C',即修改后的相机矩阵。

真的只有两种选择。任何一个:

C' = CT, or
C' = TC

因为你还有什么其他信息?

在实践中,您选择的是在现有相机矩阵“之前”生效的新变换,在这种情况下它将在世界坐标中起作用,或者在“之后”在这种情况下它将在相机坐标中发生。

你似乎想要预乘法。所以用那个。然后转换将在全局坐标空间中生效。

旧的 OpenGL 例程总是后乘。

于 2014-04-27T04:59:17.863 回答