必须记下几点,遗忘真是大敌。例子程序在Graphics Resources\SHarmonics\OneOpenglExample中,
已经简单修改一点。源程序只能为面积光,现在可以为direct 光:g_bIsDirectionLight。
Robin Green 的pdf文章好像就是为我写的,看着舒服无比,必须感谢。
一、球谐函数。
球谐函数计算步骤分两步。
1、//Sample a spherical harmonic basis function Y(l, m) at a point on the unit sphere
double SH(int l, int m, double theta, double phi);
band. m: order -l
2、//Evaluate an Associated Legendre Polynomial P(l, m) at x
double P(int l, int m, double x);
//Calculate the normalisation constant for an SH function
double K(int l, int m);
如何表达球谐函数的解析式?例子是用2500个抽样计算而来
bool GenerateSamples(int sqrtNumSamples, int numBands, SAMPLE * samples);
二、球谐函数属性:
1、旋转不变性。比如,如果灯光方向改变,那么不需要重新计算灯光,只需把灯光的球谐函数因子旋转即可。
Robin 文章说旋转矩阵不好求,例子中只提供了band为4的矩阵:16 x 16.
2、A 和 B 积分, 那么只需要用A 和 B 的球谐因子矢量做点集即可。比如band为4的因子有16个,那么A和B这16个因子对应相乘,结果就是积分结果。这是球谐函数大放光彩的原因所在,积分竟然用几个因子相乘就解决掉了,速度无比,才能在实时渲染中获得应用。
三、补注。
抄别人的一点球谐函数光照缺陷。
- 由于球谐变换需要在光照方程中的函数上进行,故而一些需要进行变换的信息首先需要进行参数化,然后再投影并得到SH系数,这就涉及到整个引擎中材质、光源的存储、表述等诸多问题;
- 当前对于球谐参数的存储多是逐顶点进行的,因而对于整个场景要想得到较为平滑、细腻的着色效果需要对场景进行较细粒度的细分。
- 虽然球谐系数的变换是在预处理阶段生成,但是对于较多的离散采样点、较细的场景细分粒度(对应较多的顶点数)整个预处理的时间代价还是很大的。因这其中涉及到光线跟踪等高密度计算,甚至在使用GPU进行加速之后仍是重量级的时间耗费。
- 要想在光照方程重建时获得较高的质量就需要存储较多的SH系数,而这些额外的空间无论是对于传输的带宽,还是设备存储的占用均是劣势所在。
四、乱弹一下。
实际上,球谐函数的结果是比较粗糙的,只能模拟低频信号。高频信号从目前看到的资料来看,似乎小波不错。以后可以尝试球小波,感觉如果应用得当,那么BRDF等都可以采用。
http://blog.sina.com.cn/s/blog_53859e630101gp5n.html