投影和裁剪问题?

发布于 2025-01-02 00:15:53 字数 2020 浏览 1 评论 0原文

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

Cube with front Cornped


测试 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);

没有立方体的可见部分


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

I am currently developing a Direct3D 11 rendering engine using C#.

I have already succeded in drawing triangles, applying color and textures, etc.
The object I am trying to display now is a rotated cube with a side length of 1 placed at the origin of the world space.
But I am getting unsatisfying results when applying the view and especially the projection matrix. As it is difficult to explain, I just show you what result I get for different view/projection combinations:


HLSL snippet from my vertex shader:

float4x4 wvpMatrix = mul(World, mul(View, Projection));
output.Position = mul(input.Position, wvpMatrix);

The world matrix I use:

// Static rotation around all three axes
matrices.World = Matrix.Identity * Matrix.CreateFromYawPitchRoll(0.5f, 0.6f, 1.0f);

Test A

Simple view vector from origin in the positive z direction. No projection used.
You can see that the back of the cube is being clipped.

matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.Identity;

Cube with back corners clipped


Test B

View matrix stays the same, but now I am using an orthographic projection matrix.
This time the front of the cube vanishes. The parts you can see are those which were clipped in Test 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);

Cube with front corner clipped


Test C

Again no projection, just like in Test A. This time the scene is being viewed from a point three units in the negative z direction.
The cube looks distorted when the camera position is not set to the origin of the system. I think there is also some clipping.

matrices.View = Matrix.CreateLookAt(new Vector3(0, 0, -3), new Vector3(0, 0, 1), Vector3.Up);
matrices.Projection = Matrix.Identity;

Distorted cube


Test D

Finally, I use a perspective projection. Up to now I have not found a camera position from which any part of the cube is visible. All I get is fullscreen cornflower blue.

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);

No visible parts of the cube


First thing I want to do is drawing the full cube - no clipping. I tried different combinations of near/far plane values but I could not find an acceptable solution.
My final goal would be to have a perspective projection. But as you see I can't even get a good orthagonal view of the scene.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-残月青衣踏尘吟 2025-01-09 00:15:53

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

原因

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 )

The matrices must be transposed at some point.

Reason:

The layout of the Microsoft.Xna.Framework.Matrix struct is row-based. Matrices in HLSL are column-based.

From the XNA Documentation:

Matrices use a row vector layout in the XNA Framework.

From the Wikipedia article on matrix order:

Column-major order is a similar method of flattening arrays onto
linear memory, but the columns are listed in sequence. The [...] shading languages
GLSL and HLSL use column-major ordering.


Solution A:

Transpose all matrices before they are sent to the shader:

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

Solution B:

Put this line in your shader code:

#pragma pack_matrix( row_major )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文