本文描述的是基于Shadow Mapping的软阴影技术,读者应该对Shadow Mapping 有基本的理解。
(本文同步发表在我的博客)
关于阴影走样
Shadow Mapping 有一个严重的问题就是走样(Aliasing),这一点在我第一次实现Shadow Mapping的时候也非常明显
图中阴影边缘明显的锯齿就是走样
这是一个老生常谈的问题了,多年来,相比于Shadow Volume,Shadow Mapping技术更加流行,而走样问题是由于Shadow Mapping的技术特点产生的,因此在学界近30年都在讨论如何解决,也确实取得了不少的进展。由于篇幅所限,我将介绍一些有代表性的技术。
我们首先还是来分析一下Shadow Mapping产生锯齿的原因。以聚光灯为例,如果光源和遮挡物离场景很远,当我们对场景中的一点找到对应shadow map中的深度,我们会在很大的矩形范围内,得到同样的深度值,这样就形成了锯齿。
除了锯齿的问题,我们发现无论遮挡物有多远,阴影的边界依然很明显,这就是所谓的硬阴影。
综上,我们需要解决两个问题锯齿和明显的阴影边界。
为了更好地分析问题,我们定义一个shadow test function
是摄像机看到的场景中某一点,
是这一点到光源的距离,
是在阴影纹理中遮挡物的位置,
则是遮挡物的深度。
显然,对于标准阴影贴图技术
这个函数是离散的,我们希望对这个函数做一个变换,使其连续化。
我们可以直接对
滤波,达到连续化的目的,然而这样的操作效率并不高,我们希望先一步对z进行滤波处理,这样我们就能在shadow pre-pass阶段进行滤波,不用在光照计算阶段进行重复的fetching和计算(这样效率很低)。
但是如果我们真的直接对z滤波,我们得不到想要的结果。原因很简单:,对
滤波和对
滤波是完全不一样的,这里的
是一个阶跃函数,由卷积定理,下面的式子不成立:
因此,我们看起来只能从
入手,但是有些方法可以先把
稍微变换一下,使其能满足卷积定理,从而应用pre-filtering
软阴影算法概览
软阴影主要解决两个问题,1:如何高效的blur,也就是如何生成一致的软阴影 2:如何利用距离控制阴影软硬程度&#x