我正在关注LearnOpenGL教程,并且一直在修补阴影投射。到目前为止,一切工作正常,但是存在一个非常具体的问题,我无法从纯垂直定向光投射阴影。让我们添加一些代码。我的光空间矩阵看起来像这样:
glm::mat4 view = glm::lookAt(-direction, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
return glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f) * view;
当然,direction是一个矢量,其方向是定向光的方向。在该方向向量设置为(0,-1,0)之前,一切工作都很好,因为它与向上向量(0,1,0)平行。为了构造lookAt
矩阵,glm执行上向量和中心与眼睛之间的差(因此,基本上是方向)之间的叉积,但该叉积不会给出任何结果因为两个向量是平行的。
知道了所有这些,我的问题是:当向上矢量和光的方向平行时,我的lookAt
应该如何查看矩阵?
编辑:谢谢您的回答,我将代码更改为:
if(abs(direction.x) < FLT_EPSILON && abs(direction.z) < FLT_EPSILON)
view = glm::lookAt(-direction, glm::vec3(0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
else
view = glm::lookAt(-direction, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
return glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f) * view;
现在一切正常!
当向上矢量和视线平行时,则视图矩阵不确定,因为Cross product为(0,0,0)。视图矩阵是Orthogonal matrix,这意味着3个轴中的每个垂直于由2个其他轴形成的平面。轴之间的角度分别为90°。视图矩阵是定义观察位置和方向的那个矩阵的逆矩阵。该矩阵由glm::lookAt
的参数定义。视线和上矢量指定的轴2的分辨率。第三轴由叉积计算。
全部表示,您必须通过2个glm::lookAt
方向指定矩阵。如果方向矢量之间的角度不完全(90°),则可以通过Orthogonal进行校正。但是,如果向量是并行的,该算法将无法做到这一点。定义视线(方向)向量和向上向量,彼此之间成90°角。如果旋转它们,则必须以相同的方式旋转另一个向量。
例如假设您有一个方向矢量(视线)和一个上矢量:
glm::lookAt
如果方向矢量旋转了90°,那么上矢量也必须旋转90°:
direction: (0, 0, 1)
up : (0, 1, 0)