1

我目前正在使用 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);

立方体没有可见部分


我要做的第一件事是绘制完整的立方体 - 没有剪裁。我尝试了近/远平面值的不同组合,但找不到可接受的解决方案。我的最终目标是进行透视投影。但正如你所见,我什至无法很好地看到场景的正交视图。

4

1 回答 1

0

矩阵必须在某个点进行转置。

原因:

Microsoft.Xna.Framework.Matrix结构的布局是基于行的。HLSL 中的矩阵是基于列的

来自XNA 文档

矩阵使用 XNA 框架中的行向量布局。

来自关于矩阵顺序的维基百科文章

列优先顺序是一种将数组展平到线性内存上的类似方法,但列是按顺序列出的。[...] 着色语言 GLSL 和 HLSL 使用列优先排序。


解决方案 A:

在将所有矩阵发送到着色器之前转置所有矩阵:

var projection = Matrix.CreatePerspectiveFieldOfView(1, 1, 0.1f, 100);
projection = Matrix.Transpose(projection);

解决方案 B:

将此行放入您的着色器代码中:

#pragma pack_matrix( row_major )
于 2012-02-03T19:01:00.020 回答