《CSM and PCF》
Posted DeanWang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《CSM and PCF》相关的知识,希望对你有一定的参考价值。
在进行阴影绘制的时候,除了blur整张shadow map之外,实现软阴影的方法还有CSM和PCF。
CSM:
CSM(Cascaded Shadow Map)即级联shadow map,又称作PSSM,它的做法是把相机从近裁剪面到远裁剪面分割成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,具有额外的矩阵计算和采样消耗。
SDSM:
仅仅按照以上的CSM算法,会在视觉上有一些问题,主要有两个缺点。第一个是,CSM阴影效果影响很大的地方是光锥的集中程度。如果光锥需要包裹整个视锥,那么即便视锥的近平面上有面墙挡住了整个视野,光锥仍然不能集中到可见的pixel上。有一个优化方法是根据视锥内物体的AABB来提高光锥的集中效率,但如果遇上上面说的那面墙,情况并不会得到改善。另一个缺点是,决定区域划分的时候有一个参数,通过对它的调整可以改善近距离屈于或者远距离屈于的阴影质量,但不能两全其美。
以上两个缺点,I3D2011上的Sample Distribution Shadow Maps可以用很很低的代价同时解决掉这些缺点,在最大程度上优化shadow map上sample的分布。
另外针对于以上缺陷,可以使用SDSM方法实现,它能够根据可见pixel来动态分配区域划分,完全解决掉这两个问题。
CSM的两个缺点实际都来自同一个根源:光锥区域是根据视锥的大小,而不是可见pixel的范围来调整。这里所说的pixel范围涉及到两个方面。第一是pixel在view space的深度范围,这会影响到区域的划分。另一个是pixel投影到light space的坐标范围,这影响到scale和bias的计算。很明显最佳情况是,shadow map的sample分布在所有可见pixel上,其他地方不浪费。而这两个方面都可以很简单地通过场景的depth texture得到。
具体的SDSM算法可以归纳为:
1.渲染一遍场景,得到depth texture。
2.统计depth texture,得到最大和最小的depth。
3.把depth的范围根据log的距离分布平均切成几个区域。
4.从pixel的depth求出view space position,投影到light space,得到该区域的scale和bias,组成crop matrix乘到projection matrix之后。
5.对每一区域都生成一张shadow map。
6.在使用的时候,根据像素在view空间的位置确定自己是在哪个区域,以选择shadow map。
SDSM仍然是一种CSM。总体来看,SDSM只是不通过光锥,而是通过可见pixel来划分区域和计算crop,这就解决了PSSM的第一个缺点。另外,由于深度是自动划分的,也就不会存在远近不能两全的缺点,也不需要一个额外参数来手工调整。所以PSSM的两个大缺点在SDSM里都不存在了。
从这里看出,整体程序升级到SDSM不需要改变太多。由于depth texture在deferred rendering里面是必须的,所以1步骤是基本已经有了。对于forward rendering而言,pre-depth也是常用的。
PCF:
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处于阴影的程度,实现软阴影效果。
参考:http://www.klayge.org/2013/05/07/%E5%A4%A7%E8%8C%83%E5%9B%B4shadow-map%EF%BC%88%E4%BA%8C%EF%BC%89%EF%BC%9Asdsm/
以上是关于《CSM and PCF》的主要内容,如果未能解决你的问题,请参考以下文章
IsoAlgo3d - A PCF 3D Viewer for Desktop, Tablet and Smart phone