在DirectX C ++中尝试Matrix转换时,Vertex Shader的输出错误

时间:2017-10-26 16:38:57

标签: 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 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;

当我尝试使用它时,它看起来像以下jagged chaos

奇怪的是,当我简单地传入Vector3并在此之前执行此操作时,它工作正常:

 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;

所以我不完全确定我哪里出错了。所有值肯定都正确地传递到着色器。

1 个答案:

答案 0 :(得分:0)

您可能正在使用column-major而不是row-main矩阵,在这种情况下,所有矩阵都会被转置。这意味着通常在最后一列(column-major)中的转换偏移将改为在底行。在最后一行中使用0 0 0 1以外的值的效果是您的矩阵不再是笛卡尔坐标,而是最终得到旋转和缩放因子,这就是输出中的捏合效果。

解决方案是在乘法之前转置矩阵,或者对于矢量/矩阵乘法,您可以预先乘法而不是后乘(反之亦然)与顶点相乘。 Here是一个非常好的解释。

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