虚幻3引擎不仅在模型上有着出色的特性,其阴影效果也是非常优秀的。
虚幻3引擎完全支持现在流行的3中阴影模式:Shadow Mapping, Projected planar, Shadow Volume。而其中Shadow Mapping和Shadow Volume都是现在比较常用的阴影算法。
Shadow Mapping是一种基于阴影映射图的阴影生成方法。其原理是先以光源为视点对场景进行渲染,得到一副所有可渲染物体相对于光源的Shadow Map(也叫depth map),在这幅Shadow Map中所有的像素值的灰度(Shadow Map图本身的像素只有灰度值,也就是说他是一幅黑白图)不代表颜色,而是代表他相对于光源的距离。然后在以原来的视点渲染整个场景并计算每个像素到光源的距离,通过将这个距离与刚才得到的Shadow Map中记录的距离相比对,从而得出这个物体是不是在阴影中的结果,然后根据结果采用不同的光照渲染。这种方法比较容易理解但是其缺点就是在有动态光源出现的场景中效率非常低下,因为每次光源移动都需要重新计算新的Shadow Map,而只要光源不发生位移,那么以前生成的Shadow Map就可以重复使用。所以这种技术通常用于静态光源比较多的场景中。而且这种方法除了处理移动光源时效率低下之外,其另外一个重大的缺陷就是其阴影的锯齿问题。其主要原因是,在很多情况下以光源为视点所生成的Shadow Map包含太多物体而且这张Shadow Map的分辨率不够,所以造成每个物体的阴影边缘会产生很多锯齿。要解决这种问题,有两个方法可供选择,一是增大Shadow Map的分辨率,二是采用更精确的以光源为视点的生成Shadow Map的方法;由于Shadow Mapping算法的本身将消耗大量的计算资源,所以第一种方法显然在效率上是不可取的。人们开发了新的以光源为视点的算法,用以生成更精确的Shadow Map。其方法是设法在不降低分辨率和造成阴影失真的情况下设法拉近光源视点相对阴影物件的距离。其效果我们可以在下图中看到。
左上图是以光源为视点用透视法生成的Shadow Map.右上图是以左上图为基础生成的最终渲染结果(我们可以看到阴影满是狗牙,非常难看)。
左下图是用改进的透视方法生成Shadow Map(同样是以光源为视点)。右下图是以左下图为基础生成的最终渲染效果(阴影相对上面好了很多)。
虽然下面的效果相对于老式的Shadow Mapping算法可以生成更精确的阴影轮廓,但是我们知道,由于光的波粒二项性阴影的边界在实际情况中是虚的而不是实的。这个问题在现阶段还无法通过各种算法来一步实现,所以为了得到真实的柔化阴影,虚幻引擎采用了对阴影的边界进行超级16X采样的算法,这是现阶段人们能够采用的唯一手段来得到柔化阴影。而具体的效率就要看各家的显卡的效率了。而就虚幻3图像引擎本身而言,支持这样的"16X采样"本身就是一个非常大的进步。
Shadow Volume同样是一种阴影映射图的阴影生成方法。但是在渲染动态光源的效率方面他有着先天的优势。其原理是先从光源向可渲染的每一个边缘引一条直线,从而在场景中形成一个个的阴影锥。然后在从视点向要被渲染的物体引一条直线,通过计算这条直线穿过阴影锥边缘的次数而得到被渲染物体是否在阴影之内的结果。这种方法由于不需要生成Shadow Map所以在处理动态光源的时候其开销相比Shadow Mapping要小的多。
具体方法是对从视点到物体引一条直线,并对这条直线进行赋Stencil值,当直线进入一个阴影锥时Stencil值就加一,当直线从一个阴影锥中出来时Stencil值就减一。那么如果这条直线最后的值为0那么说明物体不在阴影中。
当Stencil值不为一时,那么就可以断定这个物体在阴影之中。
但是这种算法存在一个致命的缺陷,那就是当视点位于阴影锥当中的时候就会产生不正确的渲染。如上图所示,物体在阴影中但是其Stencil却为零。
于是id的Carmark对这种算法进行了改进。将视点到像素的直线延长,看看其是否与阴影锥产生进出的关系,并将这种进出的关系同样华为Stencil值的加减,从而得出正确的阴影渲染结果。
这种方法的好处是在处理动态光源时,其效率比传统的Shadow Mapping方法效率高很多,而且由于这种方法的精度相对于Shadow Mapping很高(因为不涉及到从光源视点生成的Shadow Map),所以也就不会产生恼人的锯齿问题。在虚幻3引擎中,这种阴影生成方法同样支持通过16X超级采样来生成柔和的软阴影。
虚幻3引擎支持的第三种阴影生成方法是Projected planar,是一种基于模板缓冲的阴影投射技术。这种技术相对前两种技术可以说是小弟弟了,1988年才由Blinn提出其原始算法。这是一种通过将三维物体通过数学算法得到他在平面上的投射图来生成阴影的方法。
其数学算法是这样的:
M*v=P
我们可以通过上面的图来了解一下Projected planar阴影的生成过程。左上图是没有阴影的正常视点渲染结果。右上图是以光源为视点的没有阴影的渲染结果。中左是以光源为视点的shadow map (depth map)。而中右是将前面的shadow map (depth map)中的物体投射(投影)放在以正常视点为基础的平面上。左下是正常视点的shadow map (depth map)。右下图是经过最后处理(通过对比前面的第四和第五张图)的带有阴影的渲染结果。但是在计算机处理的正常过程中是没有第一步和第二步的。
通过上面的过程解释我们可以知道,这种方法实现起来相比前两种方法来说并不简单。但是这种阴影生成方法有一个的天独厚的优势,那就是Projected planar可以进行离线处理。也就是说计算机可以预先将各种物体的阴影投射计算好,然后再贴到阴影物体的下面,这样就可以把游戏进行时宝贵的时间和处理资源让给其他的操作。同样,虚幻3引擎也支持对这种阴影生成方法进行16X超级采样,用来实现软阴影。
虚幻3由于支持3种阴影技术并可以将他们结合起来应用所以可以在不同的场景中调用不同的阴影处理方法,可以在很大程度上节省系统资源