c++ - 平行于向上 vector 转换阴影时的 LookAt 矩阵

标签 c++ opengl glm-math

我正在关注 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 是一个 vector ,方向当然是定向光的方向。在将该方向 vector 设置为 (0,-1,0) 之前一切正常,因为它平行于向上 vector (0,1,0)。要构造 lookAt 矩阵,glm正在执行向上 vector 与中心和眼睛之间的差异之间的叉积(因此在这种情况下,它基本上是方向),但是叉积不会给出任何结果,因为这两个 vector 是平行的。

了解所有这些后,我的问题是:当向上 vector 和光的方向平行时,我的 lookAt View 矩阵应该如何?

编辑:感谢您的回答,我将代码更改为:

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; 

现在一切正常!

最佳答案

当向上 vector 和视线平行时,则 View 矩阵未定义,因为Cross product是 (0, 0, 0)。
View 矩阵是一个 Orthogonal matrix ,这意味着 3 个轴中的每一个都垂直于由另外 2 个轴形成的平面。轴线之间的夹角分别为90°。
View 矩阵是定义 View 位置和方向的矩阵的逆矩阵。该矩阵由 glm::lookAt 的参数定义.轴的 2 a res 由视线和向上 vector 指定。第三轴由叉积计算。

这意味着,您必须通过 2 Orthogonal 指定矩阵方向。如果方向 vector 之间的角度不精确 (90°),则可以通过 glm::lookAt 进行校正。但如果 vector 是平行的,则该算法无法做到这一点。 定义视线(方向) vector 和向上 vector ,彼此成 90° 角。如果在其中一个 vector 上旋转,则必须以相同的方式旋转另一个 vector 。

例如假设您有一个方向 vector (视线)和一个向上 vector :

direction: (0, 0, 1)
up       : (0, 1, 0)

如果方向 vector 旋转 90°,则向上 vector 也必须旋转 90°:

direction: (0, -1, 0)
up       : (0,  0, 1)

关于c++ - 平行于向上 vector 转换阴影时的 LookAt 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58459722/

相关文章:

c++ - 我制作的类的简单调用 vector "does not name a type"

c++ - 带有纹理的卡通着色器。这个可以优化吗?

c++ - SDL 3D 平台一致性

c++ - 转换 OpenGL 中的应用顺序让我感到困惑

c++ - OpenGL 使用 glm::rotate 绕全局轴旋转

c++ - 我如何在 C++ 类的构造函数中给出结构体 vector 作为参数?

c++ - 如何读取 C++ 中 system() 调用的结果?

c++ - 通过引用遍历节点的惯用方式

c++ - 在帧缓冲区内渲染多采样和单采样纹理

c++ - GLSL 和 GLM 之间的矩阵数学不一致,或者是否存在诸如 "bad" View 矩阵之类的东西