为什么我的 WorldViewProj 矩阵需要这个 Transpose()?

Why is this Transpose() required in my WorldViewProj matrix?

给定一个超级基本的顶点着色器,例如:

output.position = mul(position, _gWorldViewProj);

我遇到了很多麻烦,因为我按如下方式设置 _gWorldViewProj;我都试过了(有点乱)以确保它不只是倒退。

mWorldViewProj = world * view * proj;
mWorldViewProj = proj * view * world;

我的解决方案原来是:

mWorldView = mWorld * mView;
mWorldViewProj = XMMatrixTranspose(worldView * proj);

有人可以解释为什么需要这个 XMMatrixTranspose 吗?我知道 XNA 和 HLSL 之间存在矩阵差异(我认为)但普通 C++ 和 HLSL 之间没有差异,尽管我可能是错的。

问题是我不知道是我错了还是我错了什么!所以如果有人能准确地告诉我为什么需要转置,我希望不会再犯同样的错误。

在CPU上,二维数组一般按行优先顺序存储,所以内存中的顺序是x[0][0]x[0][1],...在HLSL中,矩阵声明默认为 column-major ordering,因此顺序为 x[0][0]x[1][0]、...

为了将内存从 CPU 上定义的格式转换为 HLSL 中预期的顺序,您需要在将 CPU 矩阵发送到 GPU 之前对其进行转置。或者,您可以在 HLSL 中使用 row_major 关键字将矩阵声明为行主要矩阵,从而消除了转置的需要,但会导致 HLSL 中的代码生成不同(您通常会得到 mul-adds 而不是点积) .