我目前正在使用C#开发Direct3D 11渲染引擎。
我已经成功绘制三角形,应用颜色和纹理等。 我现在试图显示的对象是一个旋转的立方体,边长为1,位于世界空间的原点。 但是在应用视图尤其是投影矩阵时,我得到了令人不满意的结果。由于很难解释,我只是告诉你我得到的不同视图/投影组合的结果:
我的顶点着色器的HLSL片段:
float4x4 wvpMatrix = mul(World, mul(View, Projection));
output.Position = mul(input.Position, wvpMatrix);
我使用的世界矩阵:
// Static rotation around all three axes
matrices.World = Matrix.Identity * Matrix.CreateFromYawPitchRoll(0.5f, 0.6f, 1.0f);
测试A
从正z方向的原点开始的简单视图矢量。没有使用投影。 您可以看到正在修剪多维数据集的背面。
matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.Identity;
测试B
视图矩阵保持不变,但现在我正在使用正交投影矩阵。 这次立方体的正面消失了。您可以看到的部分是在测试A中剪切的部分。
matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.CreateOrthographic(2, 2, 0.01f, 100.0f);
测试C
再次没有投影,就像在测试A中一样。这次从负z方向的三个单位观察场景。 当摄像机位置未设置为系统原点时,立方体看起来会失真。我认为还有一些削减。
matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, -3), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.Identity;
测试D
最后,我使用透视投影。到目前为止,我还没有找到可以看到立方体任何部分的摄像机位置。我得到的是全屏矢车菊蓝。
matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, -3), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.CreatePerspectiveFieldOfView(1, 1, 0.1f, 100);
我想要做的第一件事是绘制完整的立方体 - 没有剪裁。我尝试了近/远平面值的不同组合,但我找不到可接受的解决方案。 我的最终目标是进行透视投影。但是你看到我甚至无法获得一个好的orthagonal视图的场景。
答案 0 :(得分:0)
矩阵必须在某个时刻进行转置。
<强>原因:强>
Microsoft.Xna.Framework.Matrix
结构的布局是基于行的。 HLSL中的矩阵是基于列的。
矩阵在XNA Framework中使用行向量布局。
来自Wikipedia article on matrix order:
列主要顺序是将数组展平到的类似方法 线性内存,但列按顺序列出。 [...]着色语言 GLSL和HLSL使用列主要排序。
解决方案A:
在将所有矩阵发送到着色器之前转置所有矩阵:
var projection = Matrix.CreatePerspectiveFieldOfView(1, 1, 0.1f, 100);
projection = Matrix.Transpose(projection);
解决方案B:
将此行放在着色器代码中:
#pragma pack_matrix( row_major )