这让我困惑了很长时间。为什么大多数图形API(带有HLSL和OpenGL的DirectX)通常表示位置和法向量是行向量?这与数学课中的典型形式相反。两者在数学上都是正确的,我只是好奇为什么图形人选择这种表示。让我解释一下......
在我看来,行向量x
和变换矩阵'A'乘以x*A
,这导致'y = x * a'正在
y[0] = x[0]*M[0][0] + x[1]*M[1][0] + x[2]*M[2][0] + x[3]*M[3][0];
y[1] = x[0]*M[0][1] + x[1]*M[1][1] + x[2]*M[2][1] + x[3]*M[3][1];
y[2] = x[0]*M[0][2] + x[1]*M[1][2] + x[2]*M[2][2] + x[3]*M[3][2];
y[3] = x[0]*M[0][3] + x[1]*M[1][3] + x[2]*M[2][3] + x[3]*M[3][3];
请注意,要获取y[0]
,必须读取矩阵的第一列。这不是比读第一行效率低吗?矩阵通常存储为“行主要”。 我会认为由于记忆中的位置,A*x
比x*A
更有效率。这是错的吗?
为了进一步复杂化,创建转换矩阵的典型方法(例如使用DirectX Math库)以表格形式填充矩阵
| R00 R01 R02 0 |
| R10 R11 R12 0 |
| R20 R21 R22 0 |
| T0 T1 T2 1 |
其中R
表示旋转/缩放项,T
表示翻译术语。此表单用于x*A = y
形式的乘法。 为什么数学库不提供此矩阵的转置,以便可以在不手动转置数学库矩阵构造结果的情况下计算A*x = y
?
由directx数学库创建的矩阵似乎建立了比所述矩阵的转置效率低的转换。我在这个结论中是错的还是有一个重叠的原因?
答案 0 :(得分:3)
OpenGL实际上使用列主矩阵。您描述的所有内容都是D3DX特有的。甚至HLSL默认使用列主矩阵。
为解决您的其他问题,向量在HLSL中被视为行或列,具体取决于它们出现在mul (x,y)
语句的哪一侧(如果x
则为行向量,如果为{{1}则为列向量})。它在GLSL中是相同的,除了GLSL实际上有一个y
运算符用于矩阵乘法。
GLSL 4.50 Specification - 5个运算符和表达式 - p。 103
运算符是乘法(*),其中两个操作数都是矩阵,或者一个操作数是一个向量和 其他矩阵。右向量操作数被视为列向量,左向量操作数被视为 行矢量。在所有这些情况下,要求左操作数的列数相等 到右操作数的行数。然后,乘法(*)操作是线性的 代数乘法,产生一个与左操作数和行数相同的行数 与右操作数相同的列数。第5.10节“矢量和矩阵运算” 更详细地解释了矢量和矩阵是如何操作的。
答案 1 :(得分:1)
行主要顺序允许从基本变换以从左到右的顺序创建仿射变换。例如这样:
M = Scale * Rotation * Translation
同意执行顺序。 当然,必须转换基本变换与线性代数的定义。在数学中使用的列主要顺序中,执行转换的顺序是反向的,违反直觉。 两个approches的效率可能相同(它取决于表存储在内存中的顺序)。 因此,在图形中使用列主矩阵只是线性代数标准的结果。