因此,我正在编写自己的自定义 3D 转换管道,以便更好地了解它是如何工作的。我可以将所有内容正确地渲染到屏幕上,现在我要回去看看剪裁了。
根据我的理解,如果透视分割后的 x 或 y 值超出 [-1, 1] 的范围,并且在我的情况下,如果 z 值超出 [0, 1] 的范围,我应该裁剪一个顶点.
但是,当我实现它时,我的 z 值始终为 -1.xxxxxxxxxxx,其中 xxxxxxx 是一个非常小的数字。
这有点长,我很抱歉,但我想确保我提供了所有我能提供的信息。
第一个约定:
我正在使用一个左手系统,其中一个矩阵看起来像这样:
[m00, m01, m02, m03]
[m10, m11, m12, m13]
[m20, m21, m22, m23]
[m30, m31, m32, m33]
我的向量是这样的列:
[x]
[y]
[z]
[w]
我的相机设置为:
PI/4 弧度的垂直 FOV。
纵横比为 1。(方形视口)
接近剪辑值 1。
远剪辑值为 1000。
初始世界 x 位置为 0。
初始世界 y 位置为 0。
-500 的初始世界 z 位置。
相机向下看位置 Z 轴 (0, 0, 1)
给定一个顶点,管道的工作方式如下:
第 1 步:将顶点乘以相机矩阵。
第 2 步:将顶点乘以投影矩阵。
投影矩阵为:
[2.41421, 0, 0, 0]
[0 2.41421, 0, 0]
[0, 0, 1.001001, 1]
[0, 0, -1.001001, 0]
第 3 步:将 x、y 和 z 分量乘以 1/w。
第 4 步: [这就是问题所在] 如果超出边界,则剪裁顶点。
步骤 5:转换为屏幕坐标。
我拥有的一个示例顶点是
(-100, -100, 0, 1)
乘以相机矩阵后,我得到:
(-100, -100, 500, 1)
这是有道理的,因为相对于相机,该顶点向左和向下 100 个单位,向前 500 个单位。它也在 1 的近剪辑和 1000 的远剪辑之间。W 仍然是 1。
乘以投影矩阵后,我得到:
(-241.42135, -241.42135, 601.600600, -600.600600)
我不确定这是否有意义。x 和 y 似乎是正确的,但我对 z 和 w 不确定,因为下一步的透视划分很奇怪。
在透视划分之后,我得到:
(0.401966, 0.401966, -1.001665, 1)
x 和 y 再次有意义,它们都在 [-1, 1] 的范围内。但是 z 值显然超出了界限,即使我认为它仍然应该在截锥体之内。W 又回到了 1,这又是有意义的。
再次为小说道歉,但我希望有人能帮助我弄清楚我做错了什么。
谢谢!