在DirectX C+;中尝试矩阵转换时,顶点着色器的输出错误+;

在DirectX C+;中尝试矩阵转换时,顶点着色器的输出错误+;,directx,matrix-multiplication,hlsl,Directx,Matrix Multiplication,Hlsl,我正在尝试通过矩阵平移来移动3D对象的位置。我知道矩阵乘法是如何工作的,但我使用的是我的大学为我提供的图形框架,所以可能在着色器中发生了我不完全理解的其他事情。着色器代码如下所示: PixelInputType output; float4 worldPosition; // Change the position vector to be 4 units for proper matrix calculations. input.position.w = 1.0f; // Rotate

我正在尝试通过矩阵平移来移动3D对象的位置。我知道矩阵乘法是如何工作的,但我使用的是我的大学为我提供的图形框架,所以可能在着色器中发生了我不完全理解的其他事情。着色器代码如下所示:

PixelInputType output;
float4 worldPosition;


// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;

// Rotate model and move to correct position
input.position = mul(input.position, rotate);
input.position = mul(input.position, modelPosition);

// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

// Store the texture coordinates for the pixel shader.
output.tex = input.tex;

// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);

// Normalize the normal vector.
output.normal = normalize(output.normal);

// Calculate the position of the vertex in the world.
worldPosition = mul(input.position, viewMatrix);

// Determine the viewing direction based on the position of the camera and the position of the vertex in the world.
output.viewDirection = cameraPosition.xyz - worldPosition.xyz;

// Normalize the viewing direction vector.
output.viewDirection = normalize(output.viewDirection);

return output;
当我尝试使用它时,它如下所示

奇怪的是,当我只是简单地传递一个矢量3并在之前这样做时,它工作得很好:

 PixelInputType output;
float4 worldPosition;


// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;

// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, rotate);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

output.position.x = output.position.x + modelPosition.x;
output.position.y = output.position.y + modelPosition.y;
output.position.z = output.position.z + modelPosition.z;

// Store the texture coordinates for the pixel shader.
output.tex = input.tex;

// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);

// Normalize the normal vector.
output.normal = normalize(output.normal);

// Calculate the position of the vertex in the world.
worldPosition = mul(input.position, viewMatrix);

// Determine the viewing direction based on the position of the camera and the position of the vertex in the world.
output.viewDirection = cameraPosition.xyz - worldPosition.xyz;

// Normalize the viewing direction vector.
output.viewDirection = normalize(output.viewDirection);

return output;

所以我不完全确定我错在哪里。所有值都被正确地传递到着色器中。

您可能使用的是列主矩阵而不是行主矩阵,在这种情况下,所有矩阵都被转置。这意味着通常位于最后一列(主列)的平移偏移量将位于底部一行。最后一行中非0 1的值的效果是,矩阵不再是笛卡尔坐标,而是以旋转和缩放因子结束,这就是在输出中产生收缩效果的原因

解决方案是在乘法之前转置矩阵,或者对于向量/矩阵乘法,可以对顶点进行预乘而不是后乘(反之亦然)。这是一个很好的解释


在glsl(OpenGL)中,您将使用列主矩阵并编写v'=Mcm*v。我不经常使用DirectX,但它在代码中使用行主矩阵,而hlsl使用列主矩阵。在将矩阵传递到着色器中时,转置矩阵是很常见的。

您可能使用的是列主矩阵而不是行主矩阵,在这种情况下,所有矩阵都被转置。这意味着通常位于最后一列(主列)的平移偏移量将位于底部一行。最后一行中非0 1的值的效果是,矩阵不再是笛卡尔坐标,而是以旋转和缩放因子结束,这就是在输出中产生收缩效果的原因

解决方案是在乘法之前转置矩阵,或者对于向量/矩阵乘法,可以对顶点进行预乘而不是后乘(反之亦然)。这是一个很好的解释


在glsl(OpenGL)中,您将使用列主矩阵并编写v'=Mcm*v。我不经常使用DirectX,但它在代码中使用行主矩阵,而hlsl使用列主矩阵。在将矩阵传递到着色器中时,转置矩阵是很常见的。

这通常意味着您的矩阵在底行(主列)或右列(主列)中有虚假值。请尝试转置矩阵或使用mul(M,v)而不是mul(v,M)啊!StarShine,你完全正确。我应该做‘input.position=mul(modelPosition,input.position);’而不是“input.position=mul(input.position,modelPosition);”谢谢我不知道如何将你的答案标记为正确,否则我会。这通常意味着你的矩阵在最下面一行(主列)或最右边一列(主列)中有虚假值。请尝试转置你的矩阵或使用mul(M,v)而不是mul(v,M)啊!StarShine,你完全正确。我应该做‘input.position=mul(modelPosition,input.position);’而不是“input.position=mul(input.position,modelPosition);”谢谢我不知道如何将您的答案标记为正确,否则我会这样做。HLSL编译器默认使用column major,而大多数Direct3D编程都是row major。看见这由D3DCOMPILE API的
/Zpc
/Zpr
开关打开
FXC.EXE
D3DCOMPILE\u PACK\u MATRIX\u ROW\u MAJOR
D3DCOMPILE\u PACK\u MATRIX\u COLUMN\u MAJOR
标志控制。通常Direct3D应用程序会将其保留为默认值,并在将矩阵写入常量缓冲区时对其进行转置。@ChuckWalbourn啊,感谢您将其清除。此外,我相信如果您选择使用/Zpr,DirectX驱动程序会在内部重新转换回column major。HLSL编译器默认使用column major,而大多数Direct3D编程都是row major。看见这由D3DCOMPILE API的
/Zpc
/Zpr
开关打开
FXC.EXE
D3DCOMPILE\u PACK\u MATRIX\u ROW\u MAJOR
D3DCOMPILE\u PACK\u MATRIX\u COLUMN\u MAJOR
标志控制。通常Direct3D应用程序会将其保留为默认值,并在将矩阵写入常量缓冲区时对其进行转置。@ChuckWalbourn啊,感谢您将其清除。此外,我相信如果您选择使用/Zpr,DirectX驱动程序会在内部重新转换回column major。