一、Shadow Mapping 概述
Shadow Mapping 基本原理:
1.1 阴影生成 Pass:
- 额外设置一个摄像机在光源位置(Light Camera,光源摄像机),并且朝光照方向看去。
- 用一张 Texture(称为 阴影贴图 Shadow Map)来记录 Light Camera所看到的像素深度(每个像素位置只记录所见最近深度,而不用做别的 shading 计算)来作为遮挡深度。
如图,Shadow Map 记录了 Light Camera 所看到的最近深度图,颜色越深,离摄像机越近:
1.2 渲染 Pass
- 主摄像机需要渲染屏幕每个像素时,该像素对应的世界坐标进行 Light Camera 的MVP变换后能得到在 Light Camera屏幕空间中的对应位置 shadowCoord(x’,y’,z’)?
- Shadow Map 里用(x’,y’)采样得到的遮挡深度depth与深度值z’作比较:若depth < z’(意味着像素被光遮挡),这时就可以对该像素降低可见度(Visibility)。
如图为主摄像机每个像素经过变换后比较深度的结果,其中绿色点意味着深度 depth ≈ z’(没有遮挡光照),非绿色点意味着depth < z’(被遮挡了光照)
1.3 Shadow Bias
直接使用Shadow Map可能会在不应该出现阴影的位置出现一些黑白条纹相间的现象(称为 Shadow Acne):
其本质原因在于,Shadow Map 是一个二维数组,离散的存储方式很难完全表示实际的几何信息。尤其当光照方向不垂直于平面时,遮挡深度的采样会和实际深度产生偏差(如图一个不受遮挡的几何平面,但黑色加粗部分却被Shadow Mapping方法认为是被遮挡的):
解决方法:直接给采样阴影深度加一个 偏移量 Bias(相当于把阴影深度往远处加,从而更不容易产生遮挡)。
1.4 Peter Panning 问题
然而由于增加了Bias,可能会导致 Peter Panning 现象:往往在物体缝隙间发生漏光。
解决方法: 避免使用单薄的几何体(例如薄墙、薄地面);只要几何体厚度大于Bias,影子边界便会产生在几何体内部,从而不易看见影子与几何体的分离现象。
有一种有别于Bias的方法(但实际上也是殊途同归):
不使用Bias,第一个Pass(Light Camera记录深度的那个)设置成仅渲染背面(正面剔除)
这样可以让一些具有厚度的几何体背面作为深度记录,从而部分避免了几何体正面的 Shadow Acne现象。实际上这个跟使用了Bias+加厚几何体思想是差不多的,区别只不过在于:前者是低门限加一个偏移,后者则是直接给出高门限
1.5 Slope Scale Based Depth Bias
通过上面知道,Bias 过小时可能不能解决 Shadow Acne 现象,Bias 过大时又可能导致严重的 Peter Panning问题。
Slope Scale Based Depth Bias :为了尽可能减少由于 Bias 过大过小引起的问题,采取了根据平面倾角的一种自适应 Bias(例如:当光线与平面垂直时,Bias应该为0;当光线与平面的夹角越小,则Bias应越大)。
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
二、Percentage Closer Filtering(PCF)
Shadow Mapping 还存在 阴影锯齿(Shadow Aliasing) 问题: