点光锥方向旋转和方向反转

时间:2013-04-17 12:41:28

标签: math opengl

我正在研究OpenGL中的聚光灯变换系统。众所周知,聚光灯默认位置和锥形方向。但在我的实现中,它还必须具有旋转和方向。在这种情况下,旋转< / strong> - 方向时光锥的局部旋转 - 应用局部旋转后圆锥的世界旋转。

在这项工作中我遇到了各种轴翻转问题,部分原因是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的一部分设置为零,现在这样做:

_dirOut=World * Transform().GetOrientationMatrix() *  rotMatr *   glm::vec4( _lightDir,0);

它正确显示光锥,但其方向现在在X轴上翻转。

1 个答案:

答案 0 :(得分:1)

你必须记住的一件事是lookAt产生一个倒置矩阵。该矩阵是将矢量从世界空间转换到相机空间的系统变换。这等于将相机从其在世界空间中的位置移动到原点的模型转换。反之亦然。

描述路线的矢量必须在其w分量中为0。这导致跳过矩阵的平移部分。更正worldDirworldUp的定义。

但是,你真的不需要外观矩阵。相反,您应该只使用worldDir并对此向量执行转换。所以整体方向是:

_dirOut = 
    WorldMatr * OrientationMatrix * LocalRotationMatrix * glm::vec4(_lightDir, 0);

您可以预乘矩阵,然后对矢量执行一次变换,也可以将矢量变换三次(首先使用LocalRotationMatrix等等)。