深度贴图阴影:从原理到踩坑
整理一次在 OpenGL 里实现深度贴图(Depth Map)阴影的完整过程,以及透视除法、阴影痤疮这些经典坑。
阴影是让 3D 场景”落地”的关键效果之一。这篇文章整理深度贴图阴影(Shadow Mapping)的实现思路,对应我水下渲染项目里的实际代码。
基本原理
阴影贴图的核心是两次渲染:
- 从光源视角渲染一次场景,只把深度写进一张贴图(Depth Map)
- 从相机视角正常渲染,对每个片元把它的位置变换到光源空间,比较深度
float shadow = 0.0;
if (projCoords.z > texture(shadowMap, projCoords.xy).r + 0.0005) {
shadow = 1.0;
}
深度比贴图里存的更远 → 说明被挡住了 → 处于阴影中。
踩过的坑
阴影痤疮(Shadow Acne)
深度比较存在精度问题,通常加一个偏移(bias)解决。偏移太小满屏条纹,偏移太大阴影会”飘”。我的经验值是随表面坡度自适应。
透视除法不能忘
从光源空间取坐标后要做透视除法,把 [-w, w] 映射到 [0, 1] 的 UV 范围,忘了这步贴图采样全是噪点。
小结
深度贴图阴影实现不复杂,但细节多:偏移、分辨率、级联(CSM)都能单独写一篇。后面有空再展开。
评论
由 Giscus 驱动,需使用 GitHub 账号登录后评论。