我正在尝试在 LWJGL 中使用我自己的矩阵显示一个简单的四边形。我已经环顾四周一段时间,发现了一些透视矩阵实现,特别是这两个:
[cot(fov/2)/a 0 0 0]
[0 cot(fov/2) 0 0]
[0 0 -f/(f-n) -1]
[0 0 -f*n/(f-n) 0]
和:
[cot(fov/2)/a 0 0 0]
[0 cot(fov/2) 0 0]
[0 0 -(f+n)/(f-n) -1]
[0 0 -(2*f*n)/(f-n) 0]
正如预期的那样,这两者都提供了相同的效果(分别从这里和这里获得它们)。 问题在于我理解如何将其乘以模型视图矩阵,然后乘以顶点,然后将每个 x、y 和 z 值除以其 w 值得到屏幕坐标。更具体地说,如果我将它们中的任何一个乘以模型视图矩阵,然后乘以顶点(10, 10, 0, 1),则得到w=0。这本身就是一个很大的打脸。 我的结论要么矩阵是错误的,要么我完全错过了一些东西。在我的实际测试程序中,顶点甚至不会出现在屏幕上,即使摄像机位置在(0,0,0)并且没有旋转会使其如此。我什至尝试了许多不同的 z 值,正值和负值,看看它是否只是一个剪切平面。我在这里错过了什么吗?
编辑:经过大量检查,我已经缩小了我面临的问题。最大的问题是 z 轴似乎没有重新映射到我指定的范围(n 到 f)。当我沿 z 轴平移它时,任何对象都会放大或缩小一点,然后在它移过范围 [-1, 1] 时弹出。我想这也让我更加困惑。我将我的远平面设置为 100,将我的近平面设置为 0.1,它的行为与任何东西都不一样。
正如预期的那样,这两者都提供了相同的效果
虽然第二种投影矩阵形式非常标准,但第一种形式会产生不同的效果。如果您有 z==1
和 w==0
,投影将为:
矩阵1:-f/(f-n) / -f*n/(f-n) = f / f*n = 1 / n
矩阵 2:-(f+n)/(f-n) / -(2*f*n)/(f-n) = (f+n) / (2*f2n)
结果显然不同。您应该始终使用第二种形式。
如果我将它们中的任何一个乘以模型视图矩阵,则乘以顶点 (10, 10, 0, 1),它给出一个 w=0。这本身就是一个很大的打击 脸
对于焦距d
投影的计算方式为(忽略纵横比):
x'= d*x/z = x / w
y'= d*y/z = y / w
哪里
w = z / d
如果您有z==0
这意味着您要投影一个已经在眼睛中的点,并且只有超出d
的点可见。在实践中,这个点将被剪裁,因为z
不在n
(近)和f
(远)(n
预期为正常数)范围内