透视分割后的Z值始终小于-1

Jon*_*Jon 6 opengl directx 3d projection

所以我正在编写自己的自定义3D转换管道,以便更好地理解它是如何工作的.我可以正确地将所有内容渲染到屏幕上,现在我要回去查看裁剪.

根据我的理解,如果透视分割后的x或y值超出[-1,1]的范围,我应该剪切一个顶点,如果z值超出[0,1]的界限,我应该剪裁一个顶点.

但是,当我实现它时,我的z值始终为-1.xxxxxxxxxxx,其中xxxxxxx是一个非常小的数字.

这有点长,我道歉,但我想确保我提供了所有可能的信息.

第一个惯例:

我正在使用左手系统,其中Matrix看起来像这样:

[m00, m01, m02, m03]
[m10, m11, m12, m13]
[m20, m21, m22, m23]
[m30, m31, m32, m33]
Run Code Online (Sandbox Code Playgroud)

我的矢量是这样的列:

[x]
[y]
[z]
[w]
Run Code Online (Sandbox Code Playgroud)

我的相机设置为:

PI/4弧度的垂直FOV.

方位比1.(方形视口)

近剪辑值为1.

远剪辑值为1000.

初始世界x位置为0.

初始世界y位置为0.

初始世界z位置为-500.

相机向下看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]
Run Code Online (Sandbox Code Playgroud)

步骤3:将x,y和z分量乘以1/w.

第4步: [这就是问题所在]如果外边界,则剪切顶点.

第5步:转换为屏幕坐标.

我有一个示例顶点

(-100, -100, 0, 1)
Run Code Online (Sandbox Code Playgroud)

在乘以相机矩阵后,我得到:

(-100, -100, 500, 1)
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为相对于相机,该顶点是左侧和下侧100个单位,前方500个单位.它也在1的近剪辑和1000的远剪辑之间.W仍然是1.

在乘以投影矩阵后,得到:

(-241.42135, -241.42135, 601.600600, -600.600600)
Run Code Online (Sandbox Code Playgroud)

我不确定它是否有意义.x和y似乎是正确的,但我对于z和w感到不满,因为透视分割的下一步是奇数.

在透视划分后,我得到:

(0.401966, 0.401966, -1.001665, 1)
Run Code Online (Sandbox Code Playgroud)

同样,x和y有意义,它们都在[-1,1]的范围内.但是z值明显超出了界限,尽管我认为它仍然应该在最佳状态之内.W又回到了1,这也是有道理的.

再次为小说道歉,但我希望有人可以帮助我弄清楚我做错了什么.

谢谢!

Jon*_*Jon 3

好吧,看来我知道问题出在哪里了。

我的投影矩阵是:

[2.41421, 0,       0,         0]
[0        2.41421, 0,         0]
[0,       0,       1.001001,  1]
[0,       0,       -1.001001, 0]
Run Code Online (Sandbox Code Playgroud)

但它确实应该转置为:

[2.41421, 0,       0,         0]
[0        2.41421, 0,         0]
[0,       0,       1.001001,  -1.001001]
[0,       0,       1,         0]
Run Code Online (Sandbox Code Playgroud)

使用此矩阵时,我的 x 和 y 值与预期保持相同,现在我的 z 值被限制在 [0, 1] 范围内,只有在远近剪裁平面之外时才会超出该范围。

现在唯一的问题是我很困惑我使用的是右手还是左手系统。

我所知道的是现在它可以工作了......