图形矩阵由矩阵乘法变换所必需的

Graphics matrix by matrix multiplication necessary for transformations?

本文关键字:图形 变换      更新时间:2023-10-16

在过去的一段时间里,我一直在涉足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        }

…我就不能把平移加到相应的矩阵指标上吗?, matrix[3][0] += translationX;

区别在于3个加法而不是64个乘法和48个加法。

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

是的,我已经思考了一段时间了,我只是想知道这些大矩阵乘矩阵的乘法是否完全没有必要,至少对某些东西来说。另外,我知道缩放会增加一些复杂性,而且我还没有很好地理解矩阵的概念。

认为我们都可以承认特别是矩阵乘矩阵是不直观的

我完全不同意。首先,当考虑线性变换时,将矩阵视为"二维数字数组"是没有意义的。考虑矩阵的正确方法是将运算符视为非常一般的方法。

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

矩阵乘法的规则及其必要性完全由线性代数的规则决定。你从一些基本规则开始,从一个空间到另一个空间的向量变换是如何表现的,从这些规则开始,矩阵乘法的规则就上升了。

重要的是,当串联一系列变换时,最终结果可以合并到一个矩阵中。这就是这些东西的美妙之处。无论您的转换设置有多复杂,一个矩阵就可以完成任务。矩阵给你预计算的机会!

…我就不能把平移加到相应的矩阵指标上吗?, matrix[3][0] += translationX;

一般不是。只有当左上角是恒等变换时。当这部分是非恒等的时候,翻译也会被修改。

我建议你每手写一次结果

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 |

是的,我已经思考了一段时间了,我只是想知道这些大矩阵乘矩阵的乘法是否完全没有必要,至少对某些东西来说。

有趣的是,一旦你达到一定深度的变换层次,矩阵很快就胜过了链接单个基向量操作。

但问题是:不要把矩阵想象成二维的数字数组。这是线性变换的一种写法

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

  • 不,矩阵不是表示变换的唯一方法。另一个非常好的表示,唉,不太流行,是四元数旋转+向量平移。它不包括3x4(或4x4)矩阵的一些变换,但它们更紧凑,更稳定,更容易插值,有时更便宜。我很惊讶你说矩阵"不直观",但如果是这样的话,四元数可能更难掌握。

  • 这些变换表示(矩阵或四元数)的重点是它们可以组成。IRL中发生的是,你计算一些变换作为多个变换的组合,然后把它应用到一个模型的每个顶点。考虑这样一种情况:一名观看者从飞行的直升机上观看一辆带有旋转炮塔的坦克。要渲染炮塔,你必须应用至少三次旋转和平移,以将炮塔的模型空间的顶点转换为查看器坐标。与将整个链预先计算为一个矩阵,然后将仅为每个顶点9次加法和9次乘法(这是非投影矩阵-向量乘法的成本)的应用于每个顶点相比,单独应用每个变换成本高。