如何使用 glm::lookAt() 旋转对象?

Posted

技术标签:

【中文标题】如何使用 glm::lookAt() 旋转对象?【英文标题】:How to rotate an object using glm::lookAt()? 【发布时间】:2016-12-12 16:05:25 【问题描述】:

我正在处理一个涉及一些圆锥网格的场景,这些圆锥网格将用作延迟渲染器中的聚光灯。我需要缩放、旋转和平移这些锥形网格,使它们指向正确的方向。根据我的一位讲师的说法,我可以旋转锥体以与方向向量对齐,并通过将其模型矩阵乘以由此返回的矩阵将它们移动到正确的位置,

glm::inverse(glm::lookAt(spot_light_direction, spot_light_position, up));

但是这似乎不起作用,这样做会导致所有锥体都放置在世界原点上。如果我随后使用另一个矩阵手动平移锥体,似乎锥体甚至没有面向正确的方向。

有没有更好的方法来旋转对象以使其面向特定方向?

这是我当前为每个圆锥执行的代码,

//Move the cone to the correct place
glm::mat4 model = glm::mat4(1, 0, 0, 0,
                            0, 1, 0, 0,
                            0, 0, 1, 0,
                            spot_light_position.x, spot_light_position.y, spot_light_position.z, 1);

// Calculate rotation matrix
model *= glm::inverse(glm::lookAt(spot_light_direction, spot_light_position, up));

float missing_angle = 180 - (spot_light_angle / 2 + 90);

float scale = (spot_light_range * sin(missing_angle)) / sin(spot_light_angle / 2);

// Scale the cone to the correct dimensions
model *= glm::mat4(scale, 0,     0,                 0,
                   0,     scale, 0,                 0,
                   0,     0,     spot_light_range,  0,
                   0,     0,     0,                 1);

// The origin of the cones is at the flat end, offset their position so that they rotate around the point.
model *= glm::mat4(1, 0, 0, 0,
                   0, 1, 0, 0,
                   0, 0, 1, 0,
                   0, 0, -1, 1);

我已经在 cmets 中注意到了这一点,但我会再次提到锥体原点位于锥体平端的中心,我不知道这是否会有所不同,我只是想我' d 提出来。

【问题讨论】:

lookAt 已包含翻译。你不需要再这样做了。 IE。以model = glm::inverse(glm::lookAt(... 开头(不要相乘)。 @NicoSchertler 正如我在帖子中所说,如果我不手动包含翻译,那么模型将被放置在世界原点。我做错了什么吗? 你把lookAt的参数弄混了。见the documentation。另外,我不相信剩余矩阵的顺序。 【参考方案1】:

您的矩阵顺序似乎正确,但 lookAt 函数需要:

glm::mat4 lookAt ( glm::vec3 eye, glm::vec3 center, glm::vec3 up )

这里 eye 是相机的位置, center 是您正在查看的对象的位置(在您的情况下,如果您没有该位置,您可以使用 光点方向 + 光点位置)。

所以改变

glm::lookAt(spot_light_direction, spot_light_position, up)

glm::lookAt(spot_light_position, spot_light_direction + spot_light_position, up)

【讨论】:

非常感谢!这就是问题所在,我认为该功能在用于此目的时的使用方式有所不同,但我可能应该考虑尝试一下。

以上是关于如何使用 glm::lookAt() 旋转对象?的主要内容,如果未能解决你的问题,请参考以下文章

相机 旋转

相机 旋转

相机 旋转

相机 旋转

如何为 LookAt 转换获得正确的向上向量?

如何缩放使用 glm::lookat() 获得的矩阵?