矩阵乘法在我的顶点着色器中不起作用
Matrix multiplication does not work in my vertex shader
目前,我正在我的应用程序而不是 GPU 中计算 世界视图投影矩阵。我想把这个计算移到 GPU 上,但我目前做不到。
情况 1(见下文)工作得很好,但情况 2 没有,我不知道我做错了什么。
在我的相机 class 中,我计算 View 和 Projection 矩阵,如下所示:
ViewMatrix = SharpDX.Matrix.LookAtLH(_cameraPosition, _lookAtPosition, SharpDX.Vector3.UnitY);
ProjectionMatrix = SharpDX.Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, renderForm.ClientSize.Width / (float)renderForm.ClientSize.Height, 0.1f, 500.0f);
然后,我在渲染过程中为每个模型计算 World 矩阵:
SharpDX.Matrix worldMatrix = SharpDX.Matrix.Translation(_position);
案例一:我的应用中矩阵的计算
渲染模型时,我这样计算世界视图投影矩阵:
SharpDX.Matrix matrix = SharpDX.Matrix.Multiply(worldMatrix, camera.ViewMatrix);
matrix = SharpDX.Matrix.Multiply(matrix, camera.ProjectionMatrix);
matrix.Transpose();
在我的顶点着色器中,我通过调用计算顶点的最终位置:
output.pos = mul(input.pos, WVP);
一切正常!
案例二:HLSL中矩阵的计算
我没有在我的应用程序中计算任何东西,我只写了三个矩阵 World、View 和 Projection 进入我的顶点着色器的常量缓冲区并计算 HLSL 中的所有内容:
matrix mat = mul(World, View);
mat = mul(mat, Projection);
mat = transpose(mat);
output.pos = mul(input.pos, mat);
确实有效。我在我的场景中没有看到任何东西。所以我假设一些计算是错误的。我检查了我的代码好几次。
要么,我瞎了,要么傻了。我做错了什么?
在 hlsl 中你不需要计算转置。您还应该使用 float4x4,因此很容易看出您使用的尺寸。
您的矩阵应该如下所示:
float4x4 worldViewProj = mul(world, mul(view, proj));
float4 pos = mul(input.pos, worldViewProj);
请记住,点来自 float4(x,y,z,1) 类型,向量是 float4(x,y,z,0)。
在线性代数中向量的乘法是
′=⋅
所以你需要转置来改变 M 的边
′=pT⋅(T表示转置)
HLSL 有点不同。
对于最简单的方法,只需将所有矩阵从左到右相乘,然后将 mul 函数与左侧的向量一起使用,就像我上面的示例一样。
有关更多信息,请阅读:HLSL mul()
我用了几天时间来试验 HLSL 着色器和我的渲染函数。事实证明,我转置了一个我不应该做的矩阵。结果,我的整个场景都搞砸了。调试起来不是很有趣,但现在可以了! :-)
目前,我正在我的应用程序而不是 GPU 中计算 世界视图投影矩阵。我想把这个计算移到 GPU 上,但我目前做不到。
情况 1(见下文)工作得很好,但情况 2 没有,我不知道我做错了什么。
在我的相机 class 中,我计算 View 和 Projection 矩阵,如下所示:
ViewMatrix = SharpDX.Matrix.LookAtLH(_cameraPosition, _lookAtPosition, SharpDX.Vector3.UnitY);
ProjectionMatrix = SharpDX.Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, renderForm.ClientSize.Width / (float)renderForm.ClientSize.Height, 0.1f, 500.0f);
然后,我在渲染过程中为每个模型计算 World 矩阵:
SharpDX.Matrix worldMatrix = SharpDX.Matrix.Translation(_position);
案例一:我的应用中矩阵的计算
渲染模型时,我这样计算世界视图投影矩阵:
SharpDX.Matrix matrix = SharpDX.Matrix.Multiply(worldMatrix, camera.ViewMatrix);
matrix = SharpDX.Matrix.Multiply(matrix, camera.ProjectionMatrix);
matrix.Transpose();
在我的顶点着色器中,我通过调用计算顶点的最终位置:
output.pos = mul(input.pos, WVP);
一切正常!
案例二:HLSL中矩阵的计算
我没有在我的应用程序中计算任何东西,我只写了三个矩阵 World、View 和 Projection 进入我的顶点着色器的常量缓冲区并计算 HLSL 中的所有内容:
matrix mat = mul(World, View);
mat = mul(mat, Projection);
mat = transpose(mat);
output.pos = mul(input.pos, mat);
确实有效。我在我的场景中没有看到任何东西。所以我假设一些计算是错误的。我检查了我的代码好几次。
要么,我瞎了,要么傻了。我做错了什么?
在 hlsl 中你不需要计算转置。您还应该使用 float4x4,因此很容易看出您使用的尺寸。 您的矩阵应该如下所示:
float4x4 worldViewProj = mul(world, mul(view, proj));
float4 pos = mul(input.pos, worldViewProj);
请记住,点来自 float4(x,y,z,1) 类型,向量是 float4(x,y,z,0)。
在线性代数中向量的乘法是
′=⋅
所以你需要转置来改变 M 的边
′=pT⋅(T表示转置)
HLSL 有点不同。 对于最简单的方法,只需将所有矩阵从左到右相乘,然后将 mul 函数与左侧的向量一起使用,就像我上面的示例一样。
有关更多信息,请阅读:HLSL mul()
我用了几天时间来试验 HLSL 着色器和我的渲染函数。事实证明,我转置了一个我不应该做的矩阵。结果,我的整个场景都搞砸了。调试起来不是很有趣,但现在可以了! :-)