平行于向上向量投射阴影时的 LookAt 矩阵
LookAt matrix when casting shadows parallel to up vector
我正在学习 LearnOpenGL 教程并一直在修补阴影投射。到目前为止,一切正常,但存在一个非常具体的问题,我无法从纯垂直定向光投射阴影。让我们添加一些代码。我的 space 矩阵看起来像这样:
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 a res 由视线和向上矢量指定。第3轴由叉积计算。
这意味着,您必须按 2 Orthogonal 个方向指定矩阵。如果方向向量之间的角度不精确 (90°),则通过 glm::lookAt
进行校正。但如果向量是平行的,则该算法无法做到这一点。
定义视线(方向)矢量和向上矢量,彼此成 90° 角。如果你旋转它们,那么你必须以同样的方式旋转另一个矢量。
例如假设您有一个方向向量(视线)和一个向上向量:
direction: (0, 0, 1)
up : (0, 1, 0)
如果方向向量旋转90°,那么向上向量也必须旋转90°:
direction: (0, -1, 0)
up : (0, 0, 1)
我正在学习 LearnOpenGL 教程并一直在修补阴影投射。到目前为止,一切正常,但存在一个非常具体的问题,我无法从纯垂直定向光投射阴影。让我们添加一些代码。我的 space 矩阵看起来像这样:
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 a res 由视线和向上矢量指定。第3轴由叉积计算。
这意味着,您必须按 2 Orthogonal 个方向指定矩阵。如果方向向量之间的角度不精确 (90°),则通过 glm::lookAt
进行校正。但如果向量是平行的,则该算法无法做到这一点。
定义视线(方向)矢量和向上矢量,彼此成 90° 角。如果你旋转它们,那么你必须以同样的方式旋转另一个矢量。
例如假设您有一个方向向量(视线)和一个向上向量:
direction: (0, 0, 1)
up : (0, 1, 0)
如果方向向量旋转90°,那么向上向量也必须旋转90°:
direction: (0, -1, 0)
up : (0, 0, 1)