如何使用 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() 旋转对象?的主要内容,如果未能解决你的问题,请参考以下文章