首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LookAt矩阵在向上或向下查找时会发生畸变

LookAt矩阵在向上或向下查找时会发生畸变
EN

Stack Overflow用户
提问于 2015-05-23 05:44:45
回答 1查看 816关注 0票数 1

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

直视:

但当你抬头时:

向下看时:

我还没有找到有类似错误的人,而且没有人使用JOML报告过这个错误。我不是最擅长矩阵数学的,所以我计算自己的lookAt矩阵的所有尝试都失败了。如果有人可以使用JOML制作一个lookAt矩阵,或者说我的任何一个(很可能)错误,那将是非常感谢的,谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-23 16:07:28

好吧,这个库提供的lookAt代码就是这样的(我把实际的源代码放在一边,只保留注释,因为它们很好地解释了已经完成的步骤):

代码语言:javascript
复制
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向量进行归一化。假设当建立两个单位长度向量的交叉积时,结果也是一个单位长向量。但这是一个普遍的误解。真正正确的是:

代码语言:javascript
复制
length( cross( a, b) ) == lenght(a) * length(b) * sin(alpha)

其中α是ab之间的角度。因此,只有当向量已经正交时,单位长度假设才成立。由于向量在交叉乘积后从未被重新归一化,因此得到的基不是正交的,而是会引入一些不均匀的尺度。lookAt假设逆旋转可以由转置矩阵来计算,在这种情况下将完全失败。

当观察方向和向上矢量之间的角度从90度移开时,你所看到的失真会变得更严重。

处理这一问题的正确方法就是在另一个点上进行规范化。不要在交叉乘积之前对向上向量进行规范化,而是将其结果规范化。然后,有两个互相正交的单位长向量,第二个交叉积也会像预期的那样工作。因此,实际的lookAt函数应该是:

代码语言:javascript
复制
        // Compute direction from position to lookAt
        // Normalize direction
        // right = direction x up
        // Normalize right
        // up = right x direction
        // Set matrix elements
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30409318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档