BK / GRAPHICS NOTES
IMAGE QUALITY / 09

阴影:从光源位置检查可见性

一个点是否在阴影中,本质上只需判断它到光源之间有没有遮挡物。实时渲染用阴影贴图缓存光源看到的最近深度,再从相机视角重复查询这个答案。

阅读约 10 分钟前置:光照、光线追踪难度:进阶

01 / 阴影不是一种材质颜色

局部光照公式假设光源能直接照到表面。阴影项是一个可见性因子:光源可见时为 1,被完全遮挡时为 0,面积光源部分可见时则介于两者之间。

directLighting = visibility × BRDF × incomingLight
光源、遮挡物与阴影区域LIGHTOCCLUDERSHADOW
遮挡物阻断表面到光源的路径;阴影边界取决于光源形状与遮挡关系。

阴影能显著强化物体接触关系和场景尺度,但它只影响对应光源的直接光。间接光、环境光和发光材质仍可能照亮阴影区域。

02 / 阴影贴图做两次观察

  1. 从光源视角渲染场景,只保存每个样本最近的深度。
  2. 从相机视角着色时,把当前世界位置变换到光源裁剪空间。
  3. 用投影坐标查询阴影贴图,比较当前点深度与已存深度。
currentDepth ≤ shadowMapDepth → 光源可见
currentDepth > shadowMapDepth → 被更近表面遮挡

方向光使用正交投影;聚光灯适合透视投影;点光源向所有方向发光,常用立方体贴图保存六个面的深度。

阴影贴图是从光源看到的离散深度图。它不是屏幕空间效果,因此离开相机视野的遮挡物也必须包含在光源渲染范围内。

03 / 深度偏移在两类错误之间权衡

有限精度、纹理分辨率和表面倾斜会让接收面误判为遮挡自身,形成条纹状 shadow acne。比较时加入小偏移可减少自阴影。

visible = currentDepth - bias ≤ storedDepth
bias 可随表面与光线夹角增大

偏移过大又会让阴影与物体底部脱离,形成 Peter Panning。没有适用于所有场景的固定值,应结合场景尺度、法线夹角、阴影分辨率和深度范围调节。

现象常见原因调整方向
表面黑色条纹偏移太小增加深度或法线偏移
阴影漂浮偏移太大减小偏移并收紧范围
边缘块状分辨率不足提高有效纹素密度

04 / 过滤和级联改善阴影质量

PCF 软化比较结果

百分比渐近过滤在阴影贴图周围多次深度比较,再平均可见比例。它能软化锯齿,但固定采样范围并不等同于真实面积光源的半影。

级联阴影贴图

相机附近需要更高阴影细节,远处可接受较低密度。级联阴影把相机视锥按深度分段,每段使用一张方向光阴影贴图;需要处理级联选择、稳定性和过渡。

  • 收紧光源投影范围,让纹素集中在真正可见区域。
  • 让投影随纹素网格稳定移动,减少相机运动时的闪烁。
  • 按重要性分配分辨率,不要只盲目放大整张贴图。

05 / 光线追踪直接查询光源可见性

从着色点向光源采样位置发射阴影光线。若在到达光源前命中几何,该样本被遮挡;面积光源上取多个位置,就能自然得到随距离变化的软阴影。

visibility = 未遮挡光源样本数 / 光源总样本数

光追阴影避免阴影贴图的投影分辨率和偏移问题,但需要相交加速结构、更多采样和降噪。实时项目常让主要光源使用光追阴影,其他光源继续使用阴影贴图。

选型依据:阴影贴图擅长重复利用一次光源深度渲染;光线追踪擅长复杂可见性与真实软阴影。两者都是对同一个问题的不同计算策略。