球谐函数SH与PRT
函数分解和SH
对于任意函数 $f(x)$,不管是连续的还是不连续的,我们可以展开成一系列基函数(每项都带某个系数)的线性组合:
比如傅里叶变换是利用不同频率余弦波近似一个函数的,还有一种球谐的方法,听到他的球字我们就知道它非常适合拟合球面内容,这非常适合拟合环境光贴图或者其他球形分布的内容。
SH有不同阶数,阶数越高拟合程度越高,但是其很难拟合高频信息,我们一般用三阶(1+3+5=9个基函数)拟合环境光照。
- 在第0阶(l=0)有1个基函数(m=0)
- 在第1阶(l=1)有3个基函数(m=-1,0,1)
- …
- 在第n阶(l=n)有2n+1个基函数(m=-n,…,0,…,n)。
我们转换到实数形式:
到此我们获得了基函数,对于不同的环境光照前三阶SH基函数都是一样的,那是靠什么来拟合出不同环境光照的呢?是SH系数!
我们了解下这些SH基函数到底有什么特点:
正交性,基函数之间相乘在球面积分是0
求SH系数很方便,我们刚才说到SH系数一求出来就直接可以表达环境光了:相当于把环境光和基函数方向做卷积,落实到代码中就是对于每个bi,采样环境光和bi做积分。
最后通过系数向量组与基函数组的点积(前n阶的基函数/系数共有 n*n 个)可以很方便重建球面函数!
回到PRT
如何shading一点在环境光照中?
我们分两部分考虑,光照和光传输
Light部分就是我们刚才一直在推导的环境光,直接算出球谐表达:
下面考虑光照传输部分,对于漫反射和镜面反射要分开解决:
Diffuse部分
漫反射部分传输方程如下:
我们也用SH表示可以:
带入整理:注意利用基函数正交性
这也体现了正交性可以很棒的帮我们简化了公式,这也是利用SH的主要原因。
我们只需要求出$l$和$T$就可以很好的解决了问题!
Glossy部分
由于Glossy部分不再是漫反射,镜面反射是有方向的,这就相当于增加了一个维度:
环境光照部分还是一样:
对于传输光照部分:
我们需要考虑brdf的高光项,这会代来一个新的维度即出射方向
如果我们固定r方向,还是可以预计算:
我们考虑对$T_i(r)$也做一个球谐:
现在除了l预计算,还要预计算$T_{ik}$这个二维信息,不过我们还是可以接受的.
但是由于 Glossy 物体需要每个顶点存储三个矩阵 T(RGB颜色每个通道对应1个矩阵),这使得空间开销略大,因此不太实用。
PRT旋转/SH旋转
SH旋转的两种情况
SH可以旋转吗?球基函数看起来天生就适合做这个,我们来看看怎么做到。
最简单的就是,环境光旋转和物体旋转在 PRT 渲染中是等价的。我们也可以对输入向量来进行反向旋转,来获得等同于环境光正向旋转的效果;只是如果考虑每次对输入向量进行旋转操作比较费的话,可以考虑一次性旋转完 SH lighting,就避免了输入向量旋转的操作了。
我们总结下:
- 如果单个物体旋转,场景其他物体不旋转,我们可以就只对该物体计算SH系数时采样向量做一个旋转即可。
- 如果整个天空盒旋转,每个物体旋转会有一些开销,不妨考虑对SH系数求一个旋转矩阵,一次计算后获得新的SH系数,所有物体都用这个新SH系数的即可。
怎么计算SH系数旋转矩阵
现在来想想如何计算SH系数旋转矩阵:
计算示例
这样每一阶的SH系数都可以算出一个旋转矩阵,分别计算即可。
n的选取有说法吗?
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!