CSM阴影算法

大场景的阴影算法一直以来是个比较麻烦的问题,一般来说都是使用级联阴影算法,将视锥体进行从近到远的划分,整个场景的物体可以更均匀的分布在几张ShadowMap上,但可以明显看出这种情况视角平视才可以,如果视角俯视,那么算法打很大折扣。

 

 

ShadowMap和阴影体是常见的两种实时阴影算法,阴影体由于需要模型是流型等严格要求其实也较少用,反而都用在体积光等渲染技术上,所以一般来说实时阴影用ShadowMap的居多。实时阴影技术一书中对各种阴影技术都总结的很全面,里面介绍了ShadowMap的各种变种技术,如级联阴影,光源空间阴影算法等,PCF,VSM各种等,之前也试验了其中不少方法,就我个人的经验总结如下:

阴影边缘的过滤最普通的是PCF方法,但会对阴影边缘有一些模糊,如果要比较好的模糊效果,可以Jitter采样多次,模糊的效果较好,有种环境光情况下,阴影边缘模糊的样子,可以参考Unigine引擎,但多次采样特别是在移动端损失效率。类似的在阴影边缘做文章的例子可以参考英伟达SDK,D3DSDK等,像啥HARD,PCSS等算法,在像素着色器中使用了DXDY等高级函数。感觉这方面的例子挺多的,效果也不错,但性能堪忧啊,用这种方法渲染场景中少量物体还行。

PeterPaning偏移是另一个问题,但只要在Z方向压紧光源包围盒问题则不大。

VSM使用概论不等式方法,得到边缘较清楚,需要使用32位浮点精度,在移动端的16位浮点精度下,效果很差。

LiPSM光源空间阴影算法,是书中介绍的阴影包装算法中比较典型的一种,这类算法都是想办法从物体空间到光源空间的变换上做文章,以此高效利用ShadowMap。LiPSM光源空间阴影算法在光源是视角平行时则表现同标准的ShadowMap算法,不理想。

还有就是多张ShadowMap了,有CSM,PSSM等,但大体意思一样,目前发表的各种论文,很多都是在分析怎样切分视锥体,这个其实在GPU精粹3的一篇文章中已经介绍很清楚了,分析了特殊视角下精度的问题,但在实践中发现大概符合近处距离小的原则就可以了,没必要搞那么严格,特别是场景视角在不停变化,一般论文也都像GPU精粹3中一样只是分析了特殊视角下精度问题,对任意视角完全没有考虑到,个人感觉从数学理论上也很难分析清楚了。这个算法存在的特点和问题前面已经介绍了,在此不赘言了。

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/

以上这个链接中介绍的龚大的SDSM阴影算法,预先算一遍场景深度,在这个深度范围内进行切分,避免了无效的视锥体对应的ShadowMap,算是对原有算法的一种改进,但如果场景范围已知,比如场景中都是大型地面上各种建筑物,则在CPU端直接可以严格的计算出包围盒大小,压紧视锥体Z值,不仅可以用于ShadowMap切分,更可以缓解ZFighting现象。这种算法依然同之前CSM算法一样在处理俯视大场景问题中的缺陷一样。

 

posted @ 2017-04-17 14:52  LHZ593  阅读(2828)  评论(0编辑  收藏  举报