如何为 LookAt 转换获得正确的向上向量?
Posted
技术标签:
【中文标题】如何为 LookAt 转换获得正确的向上向量?【英文标题】:How to get right Up vector for LookAt transformation? 【发布时间】:2017-11-08 19:20:30 【问题描述】:我确实了解 glm::LookAt 的工作原理以及它需要哪些参数。 我不明白如何提供正确的向上向量。
例如,这个:
glm::mat4x4 transformation = glm::lookAt(cameraPosition, targetPosition, glm::vec3(0.f, 1.f, 0.f));
如果我想让相机直下观看:
mat4x4 transformation = glm::lookAt(vec3(0.f, 1.f, 0.f), vec3(0.f, 0.f, 0.f), vec3(0.f, 1.f, 0.f));
这行不通。矩阵将包含 NaNs(非数字)值! 那么如何为 Up 向量获取正确的值呢?
【问题讨论】:
【参考方案1】:你得到 NaN 的原因是 除以零。
引用this post:
向上向量基本上是定义世界“向上”的向量 方向。在几乎所有正常情况下,这将是向量 (0, 1, 0)即朝向正Y。眼睛是相机的位置 视点,中心是您正在查看的位置(位置)。
设置如何工作?下图说明:
u
是向上向量(第三个参数)
p
是目标位置(第二个参数)
c
是相机位置(第一个参数)
d
是方向向量 (= p - c
)
r
是正确的向量
lookAt
返回视图矩阵,其格式如下:
(“帽子”的意思是 标准化 - 长度为 1)
由于您只提供向上向量和(实际上,因为d = p - c
)方向向量,我们必须使用叉积计算正确的向量:
(注意以上是归一化之前)
现在说明为什么您的示例无法按预期工作。论据如下:
u = (0, 1, 0)
p = (0, 0, 0)
c = (0, 1, 0)
因此d = (0, -1, 0)
以上给出r = d * u = (0, 0, 0)
!这是因为方向和上向量是反平行的,而它们之间应该有一个角度才能使例程工作(理想情况下为 90 度)。当r
被归一化时,会被零除,因此矩阵的整个第一行都应该被 NaN 占据。
(作为一种可能的解决方法,请改用up = (0, 0, 1)
。)
【讨论】:
非常感谢您部署的答案!但我正在寻找的是一种在任何情况下都能获得正确向上矢量的方法,如何自动确定相机的正确向上方向?也许有一种方法可以让它与 glm::vec3(1, 0, 0) (正确的方向)相乘?或者我应该使用四元数吗?如果通常我的相机位于 (0, 0, 0) 向前 (0, 0, 1) 并且我将相机放置在 cameraPosition 的某个位置并试图让它看起来到 targetPosition i> 如何获得不围绕相机 Z 轴旋转的旋转以转向目标? @overwriter 当然,您可以从 right 计算 up。但这提出了如何获得正确的问题。一般来说,没有自动的方法,因为有无限多的解决方案。没有什么可以使一种解决方案比另一种更好。因此,最终程序员或场景设计师必须做出决定。 这也让我感到困惑。我最终只是检查了它的特殊情况,并使其成为有条件的。感觉真的很不雅,像个 hack,但它适用于我的函数在实践中的使用方式。以上是关于如何为 LookAt 转换获得正确的向上向量?的主要内容,如果未能解决你的问题,请参考以下文章