c++ - 稳定级联阴影映射中的光 View 矩阵

标签 c++ math opengl glm-math shadow-mapping

我最近实现了级联阴影贴图,并按照此 post 使其稳定。 。现在一切正常,除了当我将定向光移动到世界的顶部中间时,阴影突然变成全黑。经过一些调试,我发现光 View 矩阵导致了问题。

这就是我计算 View 矩阵的方法:

glm::mat4 view = glm::lookAt(
    center + lightDirNorm * nearOffset,
    center,
    camera.worldUP
);

center是包围球中心,worldUPvec3(0.0, 1.0, 0.0)的常量值,lightDirNorm 是从世界原点到灯光位置的标准化灯光方向。

当我将灯光位置移动到 vec3(0.0, 20.0, 0.0) 时,lightDirNorm 变为 vec3(0.0, 1.0, 0.0)。在这种情况下, View 方向与 worldUP vector 在同一行。因此,无法进行叉积并计算 vector 。这很麻烦,因为它是常见的光线方向。

由于阴影是稳定的,因此此处使用的 worldUP vector 必须是恒定的。我能想到的唯一解决方法是向 worldUP vector 添加一个小偏移量,使其像 vec3(0.00001, 1.0, 0.0)

我想知道是否有更好的方法来处理这个问题?

最佳答案

“使其稳定”不适用于方向变化的光源。稳定性是指光源静止时相机的运动。因此,您可以选择任何正交的 up vector 作为 lightDirNorm 的函数,它将使您的阴影保持稳定。

我还建议 staying away from any lookAt functions 。相反,通过方位角和高度指定光方向,并使用旋转矩阵来计算 View 矩阵,而不会出现任何奇异点的危险。

关于c++ - 稳定级联阴影映射中的光 View 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68367903/

相关文章:

c++ - VBO 照明和索引

c++ - 可移植显式预取

c++ - 将逗号运算符与条件运算符一起使用

c# - 围绕另一个点旋转 3D 对象 C#

java - Scala 和 Java BigDecimal

c++ - 是否可以在 OpenGL 的同一个调用中渲染两个具有不同索引起点的不同缓冲区?

opengl - Haskell:数据/类型构造函数不在范围内,但数据构造函数在范围内

c++ - 如何向加密狗传递AT指令?

c++ - 放宽对枚举类和 bool 模板参数的 constexpr 要求

c# - 从单个 for 循环生成乘法表