使用3d图形时,样本着色器 USUALLY 使用以下操作进行矢量位置转换:
result = mul(matrix, vector);
这显然意味着:
result = mul(vector, matrix_transposed);
另外,为了简单起见,大多数线性代数库更愿意只留下vector * matrix
乘法运算。
现在: 假设我想使用一些具体矩阵转换一些vector
(位置,例如) em>(具体来说,让我们使用D3DX
矩阵运算)。因此,我构建了简单的 world-view-projection 矩阵,然后将其传递给我的着色器。
D3DXMatrixRotationX(&world, 0.05f);
D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(400.0f, 80.0f, 0.0f),
&D3DXVECTOR3(0.1f, 0.1f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXMatrixPerspectiveFovLH(&projection, 0.5f, 800.0f / 600.0f, 1.0f, 1500.0f);
D3DXMATRIX wvp = world * view * projection;
Set Shader Parameter (wvp); // Pseudocode here
这是我无法理解的部分 - 如果这样做,着色器代码应为
result = mul(vector, wvp)
让这个转换起作用(向量从矩阵的左侧相乘)。
为什么会这样?大多数样本着色器如何在其中进行result = mul(wvp, vector)
转换(并且在将其设置为参数之前不转置矩阵?)
我哪里错了?
谢谢。
更多信息 - D3DX
矩阵有行主对齐,我正在使用相应的函数,它将 row-major 矩阵作为参数(在我的特定情况下为cgSetMatrixParameterfr
)。
当然,我可以通过调用函数cgSetMatrixParameterfc
来“转置”该矩阵,该函数将输入数据视为列主矩阵(并“自动”转置它) ,但这太荒谬了。
答案 0 :(得分:2)
数学中的惯例(以及编程中的惯例)是将向量乘以右边的线性变换:matrix * vector == transformed vector
。所以我不明白你的抱怨。矩阵已设置为正确的矩阵。如果你想将左边的矢量乘以然后,你需要转置矩阵:result = mul(vector, transpose(wvp))
编辑:好的,Direct3D实际上正好相反。它将左侧的向量相乘(将它们视为行而不是列)。例如,OpenGL就像正常人那样从右边增加。所以你需要将转置矩阵加载到cg程序中。
答案 1 :(得分:0)
如果两个矩阵都是对角线,正方形且大小相同,则乘法是可交换的。