C++ 变换所需的图形矩阵乘矩阵?

C++ 变换所需的图形矩阵乘矩阵?,c++,opengl,matrix,graphics,directx,C++,Opengl,Matrix,Graphics,Directx,在过去的一段时间里,我一直涉猎OpenGL和DirectX,我注意到所有的转换都是通过矩阵对矩阵和矩阵对向量的乘法来完成的。我想我们都可以承认,尤其是矩阵对矩阵的乘法是不直观的,当我了解到矩阵对矩阵的乘法涉及64次乘法和48次加法时,我并没有因为没有很好地理解它们而对自己太苛刻 无论如何,我知道现代系统上的矩阵和向量乘法是用SIMD或SSE指令完成的,减少了运算(或计算)的数量,但我看到程序员进行的许多计算似乎都是不必要的 例如,如果有一个顶点要变换,就说我们要旋转45度,然后局部平移(5,5,

在过去的一段时间里,我一直涉猎OpenGL和DirectX,我注意到所有的转换都是通过矩阵对矩阵和矩阵对向量的乘法来完成的。我想我们都可以承认,尤其是矩阵对矩阵的乘法是不直观的,当我了解到矩阵对矩阵的乘法涉及64次乘法和48次加法时,我并没有因为没有很好地理解它们而对自己太苛刻

无论如何,我知道现代系统上的矩阵和向量乘法是用SIMD或SSE指令完成的,减少了运算(或计算)的数量,但我看到程序员进行的许多计算似乎都是不必要的

例如,如果有一个顶点要变换,就说我们要旋转45度,然后局部平移(5,5,5),我看到的典型方式如下:

1:获取单位矩阵

2:将单位矩阵乘以旋转矩阵

3:将结果矩阵乘以转换矩阵(顺序问题)

4:将结果矩阵乘以要变换的点/向量

如果我想在某个方向上平移一个对象,而不是将其矩阵乘以

{ 1  0  0  translationX }
{ 0  1  0  translationY }
{ 0  0  1  translationZ }
{ 0  0  0      1        }
…难道我不能将翻译添加到适当的矩阵索引,即矩阵[3][0]+=translationX

不同之处是3次加法,而不是64次乘法和48次加法

类似地,假设我想局部平移,而不是在世界空间中,比如说向下平移一个对象的右向量,那么我可以将平移向量乘以对象世界或模型矩阵的左上部分,得到对象的局部右向量?那就是3x3矩阵乘以一个向量

是的,我已经考虑了一段时间了,我只是想知道这些大矩阵对矩阵的乘法是否完全没有必要,至少在某些情况下是这样。另外,我知道缩放增加了一些复杂性,而且我还没有完全理解矩阵的概念。

  • 这是一个过早的优化。小矩阵乘法(即2d或3d图形)在大多数情况下足够便宜,我们不必考虑它

  • 不,矩阵不是表示变换的唯一方法。另一种非常好的表示方法是四元数表示旋转+矢量表示平移。它不包括3x4(或4x4)矩阵可能的一些变换,但它们更紧凑,数值更稳定,更容易插值,有时使用起来更便宜。我很惊讶你称矩阵为“非直观的”,但如果是这样,四元数可能更难理解

  • 这些变换表示(矩阵或四元数)的要点是它们可以组合。IRL所发生的是,您将一些变换计算为多个变换的组合,然后将其应用于模型的每个顶点,例如。考虑一个飞行直升机上的观众用旋转炮塔看坦克的情况。要渲染转台,必须至少应用三次旋转和平移,以将顶点从转台的模型空间变换到查看器坐标。与将整个链预计算为一个矩阵,然后以每个顶点9次加法和9次乘法的成本(这是非投影矩阵向量乘法的成本)将其应用于每个顶点相比,通过单独应用每个变换来实现这一点成本较高

      • 这是一个过早的优化。小矩阵乘法(即2d或3d图形)在大多数情况下足够便宜,我们不必考虑它

      • 不,矩阵不是表示变换的唯一方法。另一种非常好的表示方法是四元数表示旋转+矢量表示平移。它不包括3x4(或4x4)矩阵可能的一些变换,但它们更紧凑,数值更稳定,更容易插值,有时使用起来更便宜。我很惊讶你称矩阵为“非直观的”,但如果是这样,四元数可能更难理解

      • 这些变换表示(矩阵或四元数)的要点是它们可以组合。IRL所发生的是,您将一些变换计算为多个变换的组合,然后将其应用于模型的每个顶点,例如。考虑一个飞行直升机上的观众用旋转炮塔看坦克的情况。要渲染转台,必须至少应用三次旋转和平移,以将顶点从转台的模型空间变换到查看器坐标。与将整个链预计算为一个矩阵,然后以每个顶点9次加法和9次乘法的成本(这是非投影矩阵向量乘法的成本)将其应用于每个顶点相比,通过单独应用每个变换来实现这一点成本较高

      想一想我们都可以承认,尤其是矩阵对矩阵的乘法是不直观的

      我完全不同意。首先也是最重要的是,当考虑线性变换时,将矩阵视为“二维数字数组”是没有意义的。考虑矩阵的正确方法是以一种非常普遍的方式将其视为运算符

      无论如何,我知道现代系统上的矩阵和向量乘法是用SIMD或SSE指令完成的,减少了运算(或计算)的数量,但我看到程序员进行的许多计算似乎都是不必要的

      矩阵乘法的规则及其必要性完全由线性代数的规则决定。你从一些基本的规则开始,向量从一个空间到另一个空间的变换是如何进行的,然后从那里开始
      M = rot((0,0,1), 90°) · translate(1, 2, 3)
      
                          |  0 -1  0  0 |
      rot((0,0,1), 90°) = |  1  0  0  0 |
                          |  0  0  1  0 |
                          |  0  0  0  1 |