在DirectX C+;中尝试矩阵转换时,顶点着色器的输出错误+;
我正在尝试通过矩阵平移来移动3D对象的位置。我知道矩阵乘法是如何工作的,但我使用的是我的大学为我提供的图形框架,所以可能在着色器中发生了我不完全理解的其他事情。着色器代码如下所示:在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
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。