1. 级联阴影贴图(CSM)的核心思想解析
1.1 从摄影视角理解CSM
想象你是一名专业摄影师,接到一个极具挑战性的拍摄任务:需要在一张照片中同时清晰呈现脚下草地的露珠和远处山脉的轮廓。这个场景的亮度范围(动态范围)超过普通相机传感器的捕捉能力。你会怎么做?
专业摄影师会采用HDR(高动态范围)技术:
- 用不同曝光参数拍摄多张照片
- 高曝光照片保留暗部细节
- 低曝光照片保留亮部细节
- 最后合成一张完整的HDR图像
级联阴影贴图采用了完全相同的思路:
- 近景使用"微距镜头"(高分辨率阴影贴图)
- 中景使用"标准镜头"(中等分辨率阴影贴图)
- 远景使用"广角镜头"(低分辨率阴影贴图)
- 最终合成完整的场景阴影
1.2 传统阴影贴图的局限性
在标准阴影贴图技术中,主要存在三个关键问题:
-
像素分配不均:
- 2048x2048贴图覆盖200米场景
- 每平方米仅约100像素
- 近处物体在屏幕上占大量像素却只有少量阴影像素
- 远处物体在屏幕上占少量像素却有过多阴影像素
-
透视走样(Perspective Aliasing):
math复制\text{屏幕空间阴影精度} = \frac{\text{阴影贴图分辨率}}{\text{物体在屏幕上的大小}}这个比值在场景中变化极大,导致近处锯齿明显
-
资源浪费:
- 约70%的阴影贴图像素被分配给只占屏幕10%的远景
- 而占屏幕90%的近景只分到30%的资源
1.3 CSM的解决方案架构
CSM通过分层处理解决上述问题:
| 层级 | 覆盖范围 | 贴图分辨率 | 精度/cm | 适用对象 |
|---|---|---|---|---|
| 0 | 0-10m | 1024x1024 | 1 | 角色、道具 |
| 1 | 10-40m | 1024x1024 | 3 | 建筑、树木 |
| 2 | 40-100m | 1024x1024 | 6 | 地形、远景 |
| 3 | 100-200m | 1024x1024 | 10 | 山脉、天空盒 |
这种分配方式使得:
- 总像素数减少25%(从4x2048²降到4x1024²)
- 近处精度提升10倍(从10cm到1cm)
- 远处精度仅降低60%(从10cm到16cm)
2. CSM关键技术实现细节
2.1 视锥体分割策略
对数分割算法
cpp复制float CalculateSplitDistance(float near, float far, int i, int n) {
return near * pow(far/near, (float)i/n);
}
这个公式确保每个级联在屏幕空间具有相同的纹理分辨率,但会导致:
- 最近级联范围过小(可能只有1-2米)
- 级联间过渡明显
实用混合分割
实际工程中采用线性对数混合:
cpp复制float lambda = 0.5f; // 混合系数
float logSplit = CalculateSplitDistance(near, far, i, n);
float linearSplit = near + (far-near)*(i/n);
float practica
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容