Math 聚光灯圆锥体方向旋转和方向反转

Math 聚光灯圆锥体方向旋转和方向反转,math,opengl,Math,Opengl,我正在OpenGL中开发聚光灯转换系统。众所周知,聚光灯默认具有位置和圆锥体方向。但在我的实现中,它也必须具有旋转和方向。在这种情况下,旋转-灯光圆锥体的局部旋转,而方向-应用局部旋转后圆锥体的世界旋转 在这项工作中,我遇到了各种各样的轴翻转问题,部分原因是glm::lookAt方法反转了输出矩阵的“眼睛”向量。现在一切正常,除了我必须反转最终方向向量y和z部分,以便获得聚光灯圆锥体面,而不是反向: lookatMatr[2].y =- lookatMatr[2].y;

我正在OpenGL中开发聚光灯转换系统。众所周知,聚光灯默认具有位置和圆锥体方向。但在我的实现中,它也必须具有旋转和方向。在这种情况下,旋转-灯光圆锥体的局部旋转,而方向-应用局部旋转后圆锥体的世界旋转

在这项工作中,我遇到了各种各样的轴翻转问题,部分原因是glm::lookAt方法反转了输出矩阵的“眼睛”向量。现在一切正常,除了我必须反转最终方向向量y和z部分,以便获得聚光灯圆锥体面,而不是反向:

            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”,它会朝向正确的方向。有什么想法吗?嗯,也许这是正确的行为,因为我的模拟源是左手坐标系。谢谢。如果你的矩阵基本上是旋转和平移,那么用手不起作用。翻转必须由任何矩阵引起。检查其中一个是否包含负比例因子。顺便说一句,如果回答了问题,请接受答案。这也适用于你的许多其他问题。