平行于上向量的平行光阴影投射中LookAt矩阵构建问题
解决LearnOpenGL中纯垂直平行光的阴影投射问题
我在学习LearnOpenGL的阴影投射功能时,遇到了一个特定场景的问题:当平行光为纯垂直方向(比如方向向量为(0,-1,0))时,阴影投射完全失效。
我的光照空间矩阵原本是这么写的:
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)时,它和我们传入lookAt的上向量(0,1,0)完全平行。而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;
核心思路是:当检测到平行光方向是纯垂直(x和z分量都趋近于0)时,我们改用(0,0,1.0f)作为上向量,这样就能保证和方向向量不再平行,lookAt可以正常构建出有效的视图矩阵。修改后,垂直方向的平行光阴影投射功能已经完全正常了!
内容的提问来源于stack exchange,提问作者Jambon
相关产品推荐
相关产品推荐

