来源:http://www.sunnycrystal.net/showdocs.aspx?id=14
ShadowVolume技术是增强场景真实感的重要保证,常用技术是基于Z-Pass算法的ShadowVolume。一般情况下,该算法能正确、真实的渲染出场景物体的阴影,但是,一旦眼睛进入ShadowVolume体、或者ShadowVolume体和视锥发生剪切的时候将产生错误,原本非阴影区就变成了阴影区,原本的阴影区变成了非阴影区。如何避免这个Bug呢?Carmack提出了一种基于Z-Fail算法的ShadowVolume技术,并通过3D游戏《Doom3》进行了成功的应用。
Z-Fail的要点有两个:
1、ShadowVolume体和Z-Pass的不同,Z-Pass只需将轮廓侧边沿光线方向拉伸形成两头不封口的套子状物体即可,而Z-Fail算法则还需要将这个套子的两端封闭起来,也就是添加盖子(Cap),形成一个闭合的模型。盖子如何建立呢?有两种方式:方式A:最常用的直接利用原产生阴影的物体的受光面作为遮光盖;方式B:手动计算生成遮光盖。前一种模式算法较简单,缺点是所需存储空间比较大,后一种则相反。
2、Render的差异,Z-Fail的不同处在Render的时候很明显的可以看出来:第一步:Render Volume的背光面,如果STENCILZFAIL则 增加 像素摸板值,如果StencilPass则Keep模板值保持不变;第二步:Render Volume的受光面,如果STENCILZFAIL则 减少 像素摸板值,否则保持不变。如此下来阴影就被正确的剪裁到了模版中。最后需要注意的是:当在要点1中使用方式A生成遮光盖,则存在Volume体的遮光盖与产生阴影的物体受光面共面的问题,这样会导致部分阴影嵌入物体中的错误,解决方法是通过设置 D3DRS_ZBIAS。
Z-FAIL ShadowVolume结构图:
Z-FAIL SV效果图: