我正在使用一个lookAt矩阵,它是在我为LWJGL找到的一个开源数学库中计算出来的,在我的游戏中被称为免费凸轮的JOML。当左右旋转时,它工作得很好,但是向上和向下看似乎会引起与大幅增加FOV类似的重大扭曲问题。
直视:

但当你抬头时:

向下看时:

我还没有找到有类似错误的人,而且没有人使用JOML报告过这个错误。我不是最擅长矩阵数学的,所以我计算自己的lookAt矩阵的所有尝试都失败了。如果有人可以使用JOML制作一个lookAt矩阵,或者说我的任何一个(很可能)错误,那将是非常感谢的,谢谢。
发布于 2015-05-23 16:07:28
好吧,这个库提供的lookAt代码就是这样的(我把实际的源代码放在一边,只保留注释,因为它们很好地解释了已经完成的步骤):
public final static void lookAt(Vector3f position, Vector3f centre, Vector3f up, Matrix4f dest) {
// Compute direction from position to lookAt
// Normalize direction
// Normalize up
// right = direction x up
// up = right x direction
// Set matrix elements
}这个代码就是错的。有趣的是,我以前见过这个错误。实际上,命令页仍然包含相同的错误(实际的glu实现没有错误,只是文档错误)。
这个代码所做的就是建立一个正交的基础。问题是在计算right的交叉乘积之前对up向量进行归一化。假设当建立两个单位长度向量的交叉积时,结果也是一个单位长向量。但这是一个普遍的误解。真正正确的是:
length( cross( a, b) ) == lenght(a) * length(b) * sin(alpha)其中α是a和b之间的角度。因此,只有当向量已经正交时,单位长度假设才成立。由于向量在交叉乘积后从未被重新归一化,因此得到的基不是正交的,而是会引入一些不均匀的尺度。lookAt假设逆旋转可以由转置矩阵来计算,在这种情况下将完全失败。
当观察方向和向上矢量之间的角度从90度移开时,你所看到的失真会变得更严重。
处理这一问题的正确方法就是在另一个点上进行规范化。不要在交叉乘积之前对向上向量进行规范化,而是将其结果规范化。然后,有两个互相正交的单位长向量,第二个交叉积也会像预期的那样工作。因此,实际的lookAt函数应该是:
// Compute direction from position to lookAt
// Normalize direction
// right = direction x up
// Normalize right
// up = right x direction
// Set matrix elementshttps://stackoverflow.com/questions/30409318
复制相似问题