Math 聚光灯圆锥体方向旋转和方向反转
我正在OpenGL中开发聚光灯转换系统。众所周知,聚光灯默认具有位置和圆锥体方向。但在我的实现中,它也必须具有旋转和方向。在这种情况下,旋转-灯光圆锥体的局部旋转,而方向-应用局部旋转后圆锥体的世界旋转 在这项工作中,我遇到了各种各样的轴翻转问题,部分原因是glm::lookAt方法反转了输出矩阵的“眼睛”向量。现在一切正常,除了我必须反转最终方向向量y和z部分,以便获得聚光灯圆锥体面,而不是反向:Math 聚光灯圆锥体方向旋转和方向反转,math,opengl,Math,Opengl,我正在OpenGL中开发聚光灯转换系统。众所周知,聚光灯默认具有位置和圆锥体方向。但在我的实现中,它也必须具有旋转和方向。在这种情况下,旋转-灯光圆锥体的局部旋转,而方向-应用局部旋转后圆锥体的世界旋转 在这项工作中,我遇到了各种各样的轴翻转问题,部分原因是glm::lookAt方法反转了输出矩阵的“眼睛”向量。现在一切正常,除了我必须反转最终方向向量y和z部分,以便获得聚光灯圆锥体面,而不是反向: lookatMatr[2].y =- lookatMatr[2].y;
lookatMatr[2].y =- lookatMatr[2].y;
lookatMatr[2].z =- lookatMatr[2].z;
我想不出两件事:
1.如何做才能使我不需要在最后做倒装。
2.为什么反转只需要Y轴和Z轴
以下是转换的完整代码:
glm::vec4 worldPos = WorldMatr * _pos ;
glm::vec4 worldDir = WorldMatr * glm::vec4( _lightDir,1) ;
glm::vec4 worldUp = WorldMatr * glm::vec4(Y_AXIS,1) ;
//first construct lookat matrix to get direction vector
glm::mat4 lookatMatr = glm::lookAt(glm::vec3(worldPos),glm::vec3(worldDir),glm::vec3(worldUp)) ;
//rotate locally :
lookatMatr = glm::rotate(lookatMatr,30.0f,X_AXIS) ;
lookatMatr = glm::rotate(lookatMatr,0.0f,Y_AXIS) ;
lookatMatr = glm::rotate(lookatMatr,0.0f,Z_AXIS) ;
//Orient :
lookatMatr = Transform().GetOrientationMatrix() * ( lookatMatr );
_posOut= worldPos ;
// lookatMatr[2].x =- lookatMatr[2].x;//why only Y and Z to be inverted?
lookatMatr[2].y =- lookatMatr[2].y;
lookatMatr[2].z =- lookatMatr[2].z;
_dirOut= ( lookatMatr[2]) ;
更新:
好的,正如下面所建议的,我将_lightDir的w部分设置为零,现在这样做:
_dirOut=World * Transform().GetOrientationMatrix() * rotMatr * glm::vec4( _lightDir,0);
它正确地显示了光锥,但现在它的方向在X轴上翻转。您必须记住的一件事是,
lookAt
生成一个反转矩阵。该矩阵是将向量从世界空间变换到摄影机空间的系统变换。这等于将摄影机从其在世界空间中的位置移动到原点的模型变换。反之亦然
描述方向的向量的w分量必须为0。这将导致跳过矩阵的转换部分。更正您对worldDir
和worldUp
的定义
然而,你真的不需要看矩阵。相反,您应该只使用worldDir
并对该向量执行变换。因此,总体方向将是:
_dirOut =
WorldMatr * OrientationMatrix * LocalRotationMatrix * glm::vec4(_lightDir, 0);
您可以对矩阵进行预乘,然后对向量执行一次变换,也可以对向量进行三次变换(首先使用LocalRotationMatrix等)。您的解决方案不起作用。在这种情况下,局部旋转不是局部的。例如,如果我绕Z轴旋转(局部),圆锥体的方向不应该改变。但是按照你指定的方法,它确实会改变。好吧,我用四元数进行局部旋转计算,但它不起作用。现在改为常规旋转,它起作用了。但是它在X轴上翻转。所以如果我翻转“\u dirOut.X”,它会朝向正确的方向。有什么想法吗?嗯,也许这是正确的行为,因为我的模拟源是左手坐标系。谢谢。如果你的矩阵基本上是旋转和平移,那么用手不起作用。翻转必须由任何矩阵引起。检查其中一个是否包含负比例因子。顺便说一句,如果回答了问题,请接受答案。这也适用于你的许多其他问题。