学习Spherical Harmonics的简记
说的不对请拍砖!Orz
SH是一种特殊的函数,高阶的SH可以还原非常复杂的函数,而低阶的SH比较适合还原低频函数。现代GPU硬件通常支持4个channel的texture,或者支持大顶点格式,这也为4阶以内的SH(需要4^2=16个系数)在GPU上的实现奠定了基础。
很多函数可以近似分解为多个不同相位、不同频率的正弦波,也是傅立叶变换所解决的问题。SH也类似的,由多个基函数叠加合成,对于不同的基函数有不同的系数,使得SH可以模拟很多函数,当然它的特性在图形学的范畴内是比较适合模拟diffuse光照中各向同性的特点。
SH有几个牛逼的特性,一个是rotation invariant,对于旋转,存在一个旋转函数可以把SH旋转过来。还有一个就是dot product,由于正交性,可以把SH函数相乘的积分化解为几个dot product!在我看来这是使用SH的最主要目的了。
在PRT及其变种中,SH对原函数的压缩和还原是作为核心思想直接使用的。而PRT也受到了SH带来的限制,即球谐的特性导致了各向同性,在diffuse情况下工作得很好,而完全不能用在specular的情况下。所以specular的东西还是需要其他的模型去实现。
实现PRT的话,我们这样做:
1)预计算,通过raytracer获得顶点或纹素上的辐射度传递信息,如果你懒得实现一个raytracer的话,你可能只能得到无阴影,无相互反射的N dot L的效果。当然这辐射度信息的部分如果用GPU来加速应该也是可行的。将辐射度信息投影到SH空间,存储辐射度的SH系数。
2)运行时,把球面上的光照向量投影到SH空间,存储为光照SH系数。在shader中通过madd也就是一系列点乘运算将辐射度SH系数和光照SH系数乘起来,就可以得到最终辐射度的效果,将其作为参数加入光照模型即可得到一幅低频的,有软阴影甚至是interreflection的diffuse画面。
当然实际情况远没那么简单,尤其是SH系数的旋转,很烦。目前D3DX中的D3DXSHRotate也只支持最高6阶的SH。
参考资料:
Evaluation of the rotation matrices in the basis of real spherical harmonics
http://www1.elsevier.com/homepage/saa/eccc3/paper48/eccc3.html
Spherical Harmonic Lighting: The Gritty Details
http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf