一、简单总结
阴影实现的方法,目前能够大多数硬件都支持的包括:ShadowVolume和ShadowMap。
关于上述两种阴影的简单介绍,可以通过下面这个ppt的介绍:http://download.csdn.net/detail/junjie020/6760047
ShadowVolume是基于Geometry的方法实现,大致算法是
- 求出ShadowCaster的阴影体
- 然后用这个阴影体与ShadowReceiver求交
- 最后基于Stencil Buffer,计算出阴影(ShadowVolume只是知道大致是这样,没有试过动手实现,可能有错,下面有相关技术介绍的索引)。
优点: 不会走样,因为阴影的计算基于几何体计算的,并且是实现硬阴影的好选择。 (应该还有更多的优点的,水平有限,没有详细研究) 缺点:
- 速度相比起ShadowMap来讲,要慢,因为阴影体计算及求交要耗费大量CPU时间,而且你的物体越复杂,performance下降得就越厉害;
- 实现软阴影的话,比较困难;(这些我都是通过我看过的文章和书籍里面得出的,我自己没有做过benchmark,而且我相信人家的benchmark会做得比我好,哈哈,不过如果我需要用到它的话,我也会去做的,哈哈);
ShadowMap是基于图像空间的,大致的算法是:
- 变换到LightSource的position,即以LightSource>
目前在学习PSM和LiSPSM,下面这个程序是基于Nvidia SDK中的Practical PSM整理得出的(里面包含了PSM,LiSPSM和TSM),工程是VS2012,有兴趣的可以去下载,代码质量尽管一般般,但思路还是很清晰的,值得边学习边拿来对着论文来看的:http://blog.csdn.net/junjie020/article/details/17474903
二、具体的算法
关于PSM
首先需要对某些术语进行解析:Post Perspective Space,其实就是Normalize Device Coordinate,但还没有映射到【-1,1】之间的时候(Clip Coordinate Space,我是这么理解的)。
- 在Post Perspective Space(PPS)上进行ShadowMap。在PPS进行shadow>
- 最后需要处理的是,被裁剪的物体的阴影投射(cast)到场景中去,所以这个时候,虚拟摄像机就是一个非常简单的解决办法了。这个虚拟摄像机会通过判断这个要投射阴影到场景中,但又不会渲染到场景的物体的boundbox,对摄像机进行调整,进而在shadow texture中生成的时候,将这个物体的阴影投射也考虑进去,这个时候问题就能够解决了。但新的问题就产生了,由于摄像机拉后了,必然会导致阴影的质量降低,导致有新的aliasing出现,GPU gems1,14章里面有关于这个虚拟摄像机的解决办法,感觉挺难理解的,只当作思路的参考就好了。
关于LiSPSM
http://cg.tuwien.ac.at/research/vr/lispsm/
关于PSSM
关于CSM
参考资料:
Prespective Shadow Maps 都是论文
LiSPSM 都是论文
GPU Gems 3 Chapter 10. Parallel-Split Shadow Maps on Programmable GPUs——http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html
ShaderX 5 Cascaded Shadow Maps
ShaderX 6 Stabilize Cascaded Shadow Maps