Cascaded Shadow Mapping
背景
大场景阴影的挑战
传统的阴影映射算法适用于小型场景。当渲染包含大量物体的场景时,生成的单个阴影贴图的分辨率无法满足所有物体的需求。远处的网格可能会在阴影贴图上获得与近处物体相同的分辨率,这实际上是没有必要的。换句话说,如果我们希望为靠近摄像机的物体获得高分辨率的阴影效果,我们可能需要使用极其巨大的阴影贴图。
为了说明上述信息,我做了一个简单的例子。在下图的场景中,有7条龙和一个平面。6条龙靠近摄像机,剩下的一条则距离较远。(假设只有龙会投射阴影,平面不会。)
案例 1:只有 6 条靠近摄像机的龙在视锥体内。因此,在进行视锥裁剪后,我们为这 6 条龙构建了一个包围盒,并从光源视角绘制相应的阴影贴图。在这种情况下,我们得到了一个不错的阴影贴图和如下所示的渲染结果。

Left: shadowing result, Right: shadow map
案例 2:所有 7 条龙都在视锥体内。这时,我们需要一个更大的包围盒来包含所有的龙。当然,生成的阴影贴图对于所有投射阴影的物体来说分辨率都很低,因此无法获得良好的阴影效果。在这种情况下,场景过于庞大,以至于在使用生成的阴影贴图进行采样时无法获得有效的阴影。

Left: shadowing result, Right: shadow map
因此,阴影映射无法处理大型场景,例如包含山脉、城市等的场景。
Cascaded Shadow Mapping 介绍
在级联阴影映射(CSM)中,摄像机的视锥体被分成多个子视锥体,每个子视锥体都有其对应的光源视锥体(方向光的情况下为立方体)。然后我们在阴影通道中生成几个不同的阴影贴图,如下图所示。虽然所有阴影贴图的分辨率相同,但靠近摄像机视锥体近平面的阴影贴图具有更高的精度。这大致解释了级联阴影映射如何解决前述的单一阴影映射问题。但需要注意的是,级联阴影映射仅适用于方向光。

From left to right: shadow maps of 1st, 2nd 3th and 4th cascades
案例 3:所有 7 条龙都在视锥体内。我们使用 4 个阴影级联来生成阴影。第一条龙位于第一个子视锥体中,第二条和第三条龙位于第二个子视锥体中,第四条、第五条和第六条龙位于第三个子视锥体中,第七条龙位于最后一个子视锥体中。

Left: shadowing result, Right: visualization of cascade indices
下图展示了在同一个较大场景中,使用普通的Shadow Mapping算法和使用CSM所展现的不同效果,二者均只开了硬阴影,可以看到CSM可以获得更好的硬阴影效果。


CSM实现步骤
切分 Camera Frustum
- 将摄像机的视锥体分成 n 个子视锥体。此处有两种策略,分别为Fit to Scene 和 Fit to Cascade,后续章节有详细介绍。
- 计算 n 个视图矩阵和投影矩阵,并使用它们初始化所有光源摄像机。

Cascade Splitting
生成 Shadow Map
为每个级联生成阴影贴图。可以使用 TextureArray
渲染阴影
- 计算阴影点在摄像机视锥体中的位置。
- 使用上述位置确定具体使用哪一级(Cascade)的Shadow Map,此处有两种策略,分别为Map-Based和Interval-Based,后续章节有详细介绍。
- 根据级联索引选择相应的阴影贴图,并运行传统的阴影算法绘制阴影。
CSM算法中的其他细节
Cascade Seam problem and blend between cascades
在使用级联阴影映射(CSM)时,常见的问题是级联之间的边缘会出现可见的接缝。这是由于不同级联的阴影贴图分辨率不同所导致的。为了解决这个问题,可以在着色器中对靠近级联边缘的像素进行线性插值,将它们从相邻级联中获得的两个阴影因子进行混合。换句话说,设置一个“混合带”可以处理这个问题。示意图如下

Cascade Seam and Blend
Cascade Splitting 策略
一般存在两种Cascade Splitting 策略:Fit to Scene 和 Fit to Cascade,如下图所示。 两种策略各有利弊,Fit to Scene在相机移动时具有更好的稳定性,不容易出现阴影的抖动现象。 而Fit to Cascade能够更充分地利用Shadow Map上的深度信息,能够存储更高精度的 depth。

Left: Fit to Scene, Right: Fit to Cascade
Cascade Selection 策略
Cascade的选择一般有两种策略:Interval-Based Cascade Selection 和 Map-Based Cascade Selection。 两种策略也是各有特点:Interval-Based Cascade Selection的计算速度略快, 而Map-Based Cascade Selection对于Shadow Map的利用率高。 一般情况下Map-Based Cascade Selection更为常见,不过用户需要根据自己的需求选择相应的策略。


Map-Based Cascade Selection


Interval-Based Cascade Selection