根因1(致命):光源位置写成 lightDir*30。lightDir 是光的传播方向 (指向场景),乘 30 后光源跑到场景下方——从地面下方向上打光, 地面永远是光线第一个交点,物体永远不可能遮挡地面,影子恒不存在。 修复:光源位置 = -lightDir * 30(逆传播方向退回)。 根因2:垂直光(direction≈(0,-1,0))时 lookAt 的 up=(0,1,0) 与视线 平行,叉积为零 → 矩阵 NaN → shadow map 全垃圾。修复:|dir.y|>0.99 时改用 (0,0,1) 作为 up。 场景:地面 quad(Model::CreatePlane 程序化构造,AssetManager 缓存) + 主光调平让影子落在相机视野内。已截图验证影子可见。