簡介
之前在一篇實(shí)時深度圖優(yōu)化的論文中看到球諧光照(Spherical Harmonics Lighting)的應(yīng)用,在查閱了許許多多資料之后還是無法完全理解,我個人覺得如果之前對實(shí)時渲染技術(shù)不是很了解的話,球諧光照還是有一定難度的。大多數(shù)的資料都是從原理上描述球諧函數(shù)及其光照過程,而沒有對具體的應(yīng)用做解釋,我直到真正動手實(shí)現(xiàn)了一遍球諧光照之后,才完全理解球諧光照具體的過程以及作用。
球諧光照實(shí)際上是一種對光照的簡化,對于空間上的一點(diǎn),受到的光照在各個方向上是不同的,也即各向異性,所以空間上一點(diǎn)如果要完全還原光照情況,那就需要記錄周圍球面上所有方向的光照。注意這里考慮的周圍環(huán)境往往是復(fù)雜的情況,而不是幾個簡單的光源,如果是那樣的話,直接用光源的光照模型求和就可以了。
如果環(huán)境光照可以用簡單函數(shù)表示,那自然直接求點(diǎn)周圍球面上的積分就可以了。但是通常光照不會那么簡單,并且用函數(shù)表示光照也不方便,所以經(jīng)常用的方法是使用環(huán)境光貼圖,比如像這樣的:
上面的圖是立方體展開得到的,這種貼圖也就是cubemap,需要注意的是一般的cubemap是從里往外看的。
考慮一個簡單場景中有個點(diǎn),他周圍的各個方向上的環(huán)境光照就是上面的cubemap呈現(xiàn)的,假如我想知道這個點(diǎn)各個方向的光照情況,那么就必須在cubemap對應(yīng)的各個方向進(jìn)行采樣。對于一個大的場景來說,每個位置點(diǎn)的環(huán)境光都有可能不同,如果把每個點(diǎn)的環(huán)境光貼圖儲存起來,并且每次獲取光照都從相應(yīng)的貼圖里面采樣,可想而知這樣的方法是非常昂貴的。
利用球諧函數(shù)就可以很好的解決這個問題,球諧函數(shù)的主要作用就是用簡單的系數(shù)表示復(fù)雜的球面函數(shù)。關(guān)于球諧函數(shù)的理論推導(dǎo)與解釋可以參考wiki(https://en.wikipedia.org/wiki/Spherical_harmonics)。如果只是要應(yīng)用和實(shí)現(xiàn)球諧光照,不會涉及到推導(dǎo)過程,不過球諧基函數(shù)卻是關(guān)鍵的內(nèi)容,球諧基函數(shù)已經(jīng)有人在wiki上列好了表格,參考(https://en.wikipedia.org/wiki/Table_of_spherical_harmonics),前3階的球諧基函數(shù)如下:
這里值得注意的是很多資料用這張圖來描述球諧基函數(shù):
我剛開始看到這張圖的時候簡直覺得莫名其妙,實(shí)際上這里面每個曲面都是用球坐標(biāo)系表示的,球諧基都是定義在球坐標(biāo)系上的函數(shù),r(也就是離中心的距離)表示的就是這個球諧基在這個方向分量的重要程度。我是用類比傅里葉變換的方法來理解的,其實(shí)球諧函數(shù)本身就是拉普拉斯變換在球坐標(biāo)系下的表示,這里的每個球諧基可以類比成傅里葉變換中頻域的各個離散的頻率,各個球諧基乘以對應(yīng)的系數(shù)就可以還原出原來的球面函數(shù)。一個復(fù)雜的波形可以用簡單的諧波和相應(yīng)系數(shù)表示,同樣的,一個復(fù)雜的球面上的函數(shù)也可以用簡單的球諧基和相應(yīng)的系數(shù)表示。
由于球諧基函數(shù)階數(shù)是無限的,所以只能取前面幾組基來近似,一般在光照中大都取3階,也即9個球諧系數(shù)。
實(shí)驗(yàn)
我們先考慮簡單的情況,比如說定義一個光照函數(shù):
在球坐標(biāo)系下,將該函數(shù)的值當(dāng)做光照強(qiáng)度值,可以畫出光照在球面上的分布情況: