Matrix 为什么在我的WorldViewProj矩阵中需要这个转置()?

Matrix 为什么在我的WorldViewProj矩阵中需要这个转置()?,matrix,direct3d,matrix-multiplication,hlsl,Matrix,Direct3d,Matrix Multiplication,Hlsl,给定超级基本顶点着色器,例如: output.position = mul(position, _gWorldViewProj); 我遇到了很多麻烦,因为我正在如下设置gWorldViewProj;我尝试了两种方法(有点鞭笞),以确保它不仅仅是向后的 mWorldViewProj = world * view * proj; mWorldViewProj = proj * view * world; 我的解决方案是: mWorldView = mWorld * mView; mWorldVi

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

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上,2D数组通常按行主顺序存储,因此内存中的顺序是
x[0][0]
x[0][1]
。。。在HLSL中,矩阵声明默认为,因此顺序为
x[0][0]
x[1][0]


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

你能解释一下是什么症状让你相信你需要转置矩阵吗?所以说,每当我提取XMMATRIX并将其存储在float4x4常量缓冲区时,我总是需要先转置它,这是正确的吗?@Dave通常,但不一定。按照惯例,大多数数学库(例如XNAMath/DirectXMath)将生成行主矩阵数据,因此当库生成投影矩阵时,它将位于行主矩阵中,需要进行转置。但您也可以将库输出设置为列主格式,从而消除转置的需要。请记住,您最多只需要一次转置操作,就在上载到常量缓冲区之前-不要转置CPU上的中间矩阵。HLSL不需要它,它只是默认为column major。这在DirectXMath程序员指南中的“使用D3DXMath”一节中的“将DirectXMath与Direct3D结合使用”中有明确介绍,并提供了相关链接。简而言之:DirectXMath支持左手或右手查看坐标,但所有矩阵都是行主坐标。您可以告诉HLSL使用row-major,但它默认为column-major,这稍微快一点。因此,在设置CB之前进行转置。