这章介绍了一种渲染软阴影的技术,称为遮挡区间映射(Occlusion Interval Maps),能够正确地在静态场景中渲染出光源沿着预定路径移动时产生的模糊阴影。之所以叫遮挡区间映射,是因为此算法使用纹理贴图来存储这种光源可见、而本身被遮挡的区间。
对于需现实的加油站的Demo,文章一开始本打算使用一种预计算的可见度技术,例如球谐光照(Spherical Harmonic Lighting [Sloan et al.2002])来实现,但可惜的是无法达到目的,因为球谐光照适用的是非常低频的光照,不适用于像太阳那样小面积的光源。所以后来才开发出遮挡区间映射这种新的预计算可见度的技术,它能够支持实时太阳照射的软阴影。通过把问题简化为在固定轨道上的线性光源来达到目的。
该文章采用的算法原理是将影子表达为一个可见度函数,当点在影子中是,它的值时0,当它被照明的时候,它的值是1.在渲染的时候,计算这个可见度函数,再讲结果乘以一个着色计算,得出最终的颜色值。具体看见度函数原理如一下两个图:第一个图是随时间便宜,可见性值的变化,第二个图是第一个图模糊后的结果。
具体实现是将可见性函数的上升部分和下降部分分布存储在两张纹理中,之后在shader中进行计算。
half softshadow(sampler2D riseTexture,sampler2D fallTexture,float2 texCoord,half intervalStart,half intervalEnd,half intervalInverseWidth)
{half4 rise = h4tex2D (riseTexture, texCoord);half4 fall = h4tex2D (fallTexture, texCoord);half4 minTerm = min (fall, intervalEnd);half4 maxTerm = max (rise, intervalStart);return dot (intervalInverseWidth, saturate (minTerm - maxTerm));
}
需要注意,遮挡区间映射(Occlusion IntervalMaps)技术有一些局限性,只对沿固定轨道传播的单条光线的静态场景适用。这意味着它对人物和其他动态物体的阴影无效。但是其适用于静态户外场景中的阴影渲染。并且此技术因为遮挡区间映射对每个通道需要8位的进度,纹理压缩将导致视觉效果失真。因此,必须禁用纹理压缩,从而增加了纹理用量。
使用遮挡区间映射(Occlusion Interval Maps)技术,通过损失一定运行性能来获得在静态场景上实时运行的软阴影算法。遮挡区间映射(Occlusion Interval Maps)可以用作静态光照贴图的替代品,从而实现动态效果,可以得到从日出到日落光照明变化的动态效果。如下图。