You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

平行于上向量的平行光阴影投射中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:13