首页 > 代码库 > 《CSM and PCF》
《CSM and PCF》
在进行阴影绘制的时候,除了blur整张shadow map之外,实现软阴影的方法还有CSM和PCF。
CSM(Cascaded Shadow Map)即级联shadow map,它的做法是把相机从近裁剪面到远裁剪面分割成N个子视锥,每个视锥渲染一张shadow map。
一般而言,级联shadow map的几级大小是一样的,比如四级,可以在整张shadow map中分成四份,只是一级的shadow map里面的可视区域最小,阴影边缘锯齿也最不明显;第四级的shadow map可视区域最大,用它做出来的阴影的边缘锯齿也就最明显,但是由于使用到这一级的shadow map的物体都是比较远的物体所以可以这种效果。
在分级的时候,比如分4级,原来相机只有一个远裁剪面,现在会分成4个,可以进行线性等分,也可以不等分:
下图中,C0是近裁,Cm是远裁,Ci代表分割线,假如我们想要分割出N个子视锥,那我们就需要求出N-1个Ci。
通用算法是:
使用混合因子λ将平均切分和指数切分融合起来。
其中,指数切分公式是:
平均切分的公式是:
其中,n为近裁,f为远裁,i为切分线,m为子视锥总数。
代入最上面的公式,就能得到最终的切分公式。
利用级联CSM的算法实现shadow map,生成级联的shadow map之后,后面的步骤即和传统的shadow map原理相差不大,不同的是,在传统的shadow map算法中,将当前pixel的坐标转换到light space后,等到的深度值仅仅和唯一的一张shadow map进行比较,现在,在级联shadow map的算发现,是有多张shadow map的,应该根据之前在light space中得到的深度来判断应该使用哪张级联shadow map中的那个,再进行深度比较,其中要注意UV的偏移不要采样到错误的shadow map中的像素,得到错误的比较结果,导致阴影效果出问题。
关于一些CSM的优化;如果camera不动,角色在场景中走动,穿过两级shadow map的时候会发现阴影效果有明显改变,为了解决这种问题,可以让两级shadow map之间有重叠部分,比如重叠20%,然后对两张shadow map产生的阴影进行混合,这样的好处是完成了两级阴影效果之间的平滑过渡,但是坏处是发现当前pixel的深度位于light space的两级视锥之间的时候需要采样两张shadow map,具有额外的矩阵计算和采样消耗。
PCF是Percentage Closer Filtering的缩写;传统算法里,在shadow map里面采样出来的值和depth value进行比较的时候二者是一一对应的,在PCF算法中,可以对shadow map的周边进行采样,然后都和depth value进行比较,比如采样shadow map4次,每确定这次采样处于阴影中就为最终计算的值累计0.25,这样最终得到的值的可能性是0.0,0.25,0.50,0.75,1.0,该值用于与阴影颜色相乘,以此来决定该pixel处于阴影的程度,实现软阴影效果。
《CSM and PCF》