基于预计算的全局光照技术
基于預計算的全局光照技術
實時渲染,意味著渲染算法需要在1/30秒甚至更少的時間內(nèi)生成當前場景在當前視角下的一張2D圖像。盡管這看起來只是在時效上的要求不同,實時渲染和離線渲染采用的的確是兩種完全不同的渲染方法和架構(gòu)。
傳統(tǒng)的離線渲染算法基本上都依賴于光線追蹤,狹義的光線追蹤是指根據(jù)一條光線的傳播方向?qū)ふ以摴饩€與場景中表面最近的一個交點,這個過程的計算成本非常昂貴,所以目前的實時渲染算法通常并不能像離線渲染算法那樣計算更完全的光線傳播路徑,而是僅僅只計算所謂的直接光照,然后間接光照通過其它的一些非直接渲染的方法來實現(xiàn)。由于直接光照往往具有比較好的連貫性,因此人們設計出一種高度并行的圖形處理器,用于實現(xiàn)對直接光照的高速實時渲染。
在實時渲染中,直接光照又稱為局部光照(local illumination),它的計算相對比較簡單。相應地,間接光照又稱為全局光照(global illumination, GI),所以通常在實時渲染中我們所說的全局光照其實是指間接光照,實時渲染中的間接光照額計算是相對比較困難的,它們通常會使用一些預計算或者其它一些特殊的近似方法。
對于實時渲染來講,最簡單且高效的方法可能是將光照傳輸過程中的一些計算緩存起來,然后實時渲染可以使用這些預計算的某種形式的數(shù)據(jù)結(jié)果,這些基于預計算的方法仍然是當前階段實時渲染中比較核心的全局光照算法。
根據(jù)其對渲染方程預計算的位置不同,實時渲染中有多種不同的預計算光照技術,他們也分別擁有自己不同的名稱,例如預計算輻射傳輸,輻射照度緩存,輻射照度/亮度體積等等,傳統(tǒng)的教材也大都會對它們進行區(qū)分并給以單獨介紹,在一些實時引擎渲染引擎(如Unreal Engine和Unity等)中它們也表現(xiàn)為看似完全無關的流程和功能。然而從技術從面,它們卻存在著很多聯(lián)系,例如它們大部分都需要基于球協(xié)函數(shù)和乘機屬性來分離出預計算部分,它們也大都需要借助基于圖像的光照技術來實現(xiàn)預計算,并且通過比較對不同渲染方程不同部分的預計算處理,我們可以更深刻地理解這些預計算全局光照技術的思路。所以,我們這里嘗試將所有這些基于預計算的全局光照技術放到一個章節(jié),除了介紹它們的基本算法,我們可以更深刻的洞悉它們之間的聯(lián)系,進而更深刻地理解這些全局光照技術。
10.1 數(shù)學基礎
本章所有預計算光照技術的數(shù)學基礎是基函數(shù)(basis function)的概念及其相關知識。 在數(shù)學中,一個基函數(shù)是函數(shù)空間和(funtion space)中的一個基,就像歐拉(實數(shù)或復數(shù)矢量)空間中的一個坐標軸一樣。在函數(shù)空間中,每個連續(xù)的函數(shù)都可以表示為這些基函數(shù)的一個線性組合,正如矢量空間中的每個矢量都可以表示為各個坐標軸(基矢量)的線性組合一樣。例如,對于所有二次多項式都可以表示為基函數(shù)組{1,t,t^2}的線性組合a1+bt+ct平方,這里a,b和c表示各個基函數(shù)的系數(shù)。此外,傅里葉變換其實也是將一個任意函數(shù)表示為一系列三角函數(shù)的線性組合。
所以,如果已知一組基函數(shù),則我們可以使用一個矢量來表述一個函數(shù),該矢量的各個分量就是對于各個基函數(shù)的線性組合系數(shù)。給定一個定義在T上的函數(shù)f(t)以及一組基函數(shù)Bi(t),該函數(shù)可以通過下面的積分被投影(projection):
然后,原始函數(shù)可通過這些基函數(shù)與其對應系數(shù)乘積(如圖10.1(b)所示)的加和形式(即線性組合)被重建(reconstruction),即:
這里N表示系數(shù)的數(shù)量,一個連續(xù)函數(shù)通常需要無窮多個基函數(shù)的線性組合才能完全被重建,當基函數(shù)的數(shù)量有限,或者N小于基函數(shù)的數(shù)量時,上述基函數(shù)的線性組合只是原始函數(shù)的一個近似,記為。
上面的例子使用了一系列線性(一次)函數(shù)作為基函數(shù),它給出原始函數(shù)的一個分段線性近似。在工程上最常用的是使用一組相互正交的多項式作為函數(shù)基,正交多項式(orthogonal polynomials)是一組具有一些有趣特性的多項式,即任意兩個基函數(shù)之間都是相互正交的,所以當任意兩個基函數(shù)的乘機進行積分時,只有當兩者完全相同時才會取得非零值,例如:
上式使用了更嚴格的限制:兩個多項式乘積的積分必須返回0或者1,這些特定子集的基函數(shù)被稱為標準正交基函數(shù)(orthonormal basis function)。
有了上述的理論基礎,我們便可以使用一個分量為各個基函數(shù)系數(shù)的矢量來表述或近似一個連續(xù)函數(shù)。很顯然,每個表面處的光照傳輸是一個關于BRDF分布函數(shù),可見性及幾何項的函數(shù),因此如果場景是靜態(tài)的,那么該傳輸函數(shù)可以被存儲為一個矢量而被重復使用。
然而,這里存在一個問題是,完整表述一個連續(xù)函數(shù)需要無限多個系數(shù),而光照傳輸發(fā)生于每個表面處,即每個表面位置都需要存儲一個系數(shù)矢量,這顯然面臨巨大的存儲和計算壓力。為此,我們必須對每個表面點使用少量的系數(shù)對原函數(shù)進行近似,相對于由分段函數(shù)構(gòu)成的基函數(shù)(如圖10.1所示),由多項式組成的基函數(shù)還具有另一種特征,不同的基函數(shù)能夠表述原函數(shù)不同頻率域的特征,階數(shù)越高則保留的頻率細節(jié)越多,但是需要的系數(shù)數(shù)量也越多,因此這給出一種可能,即使用少量的低階多項式基函數(shù)來近似原函數(shù)的低頻部分,這即是預計算輻射傳輸算法的核心思想。
本節(jié)首先討論多項式基函數(shù)(如勒讓德多項式)的一些特征,以及基于球面坐標系下的一種多項式基函數(shù)(即球諧函數(shù)),然后將在后面的內(nèi)容中利用這些基函數(shù)的特征來實現(xiàn)預計算輻射傳輸算法。
10.1.1 勒讓德多項式
工程中最感興趣的一類多項式是勒讓德多項式(Legende polynomials),記為Pl(x),其定義域為x屬于[-1,1],伴隨勒讓德多項式Pl,m(x)和Pl,-m(x)是勒讓德多項式的一般化或者說一般勒讓德方程的解,其中l(wèi)是一個非負整數(shù),而m=0,…,l,這些多項式返回實數(shù)(而一般的勒讓德多項式返回復數(shù))值。
對于給定正整數(shù)m,伴隨勒讓德多項式可以表述為一般非伴隨勒讓德多項式的形式,即:
有了式10.8和10.9,便可以推導出任意參數(shù)l和m下的伴隨勒讓德多形式。
伴隨勒讓德多項式德另一個參數(shù)l的意義是什么呢,通過觀察式10.8和10.9,隨著l的增加,變量x的指數(shù)會越來越大,實際上l表示了伴隨勒讓德多項式的次數(shù)(degree of a polynomial),即多項式中所有單項式中指數(shù)次數(shù)和的最大值。由此也可以對于每一個固定的l,必須滿足m<=l,因為m>l時(即倒數(shù)的階數(shù)大于多項式的次數(shù)),Pl,m的值始終為0。
圖10.2展示了開頭一些伴隨勒讓德多項式的圖,不難看出,隨著次數(shù)l的增大,伴隨著勒讓德多項式的頻率變化變得越來越大,因次我們可以使用少數(shù)較低次數(shù)的伴隨勒讓德多項式近似函數(shù)的低頻部分。
10.1.2 球諧函數(shù)
滿足拉普拉斯方程的函數(shù)稱為諧函數(shù)(harmonic function),或者調(diào)和函數(shù),球諧函數(shù)(spherical harmonics, SH)則是將球諧函數(shù)限制于球坐標系(spherical coordinates)下的單位球面(unit sphere)上,即它忽略了球坐標系的半徑r(因為其被固定于球面上),僅取其方向變化thea和fi。因此正如傅里葉級數(shù)(圓上的正弦和余弦函數(shù))是一系列用于表示圓上的方向分布函數(shù),球諧函數(shù)可以用來表述球面上的方向分布,例如表面的BRDF分布函數(shù),環(huán)境貼圖,光照傳輸,可見性分布等,這些都是僅與方向有關(而與位置無關)的函數(shù)。
球諧函數(shù)是定義在單位球面上的正交基,因此可以使用以下的參數(shù)化:
來描述球諧函數(shù),這里s就是單位球面上的一個位置。球諧函數(shù)一般使用符號y表述,其定義為:
這里P正是前面介紹的伴隨勒讓德多項式,而K僅僅是一個用以實現(xiàn)規(guī)則化的縮放系數(shù),其值為:
同伴隨勒讓德多項式一樣,我們使用不同的l和m(滿足-l<=m<=l)的組合來獲取所有的球諧函數(shù),這是一個類似金字塔的數(shù)據(jù)結(jié)構(gòu),如圖10.3所示,為了簡化表述,通常使用特定的順序?qū)⑵滢D(zhuǎn)換為一個平坦的一維矢量,所以我們又可以使用下面的序列定義球諧函數(shù):
乘機投影
在前面的內(nèi)容中,我們已經(jīng)將整個光照計算分為光源(這里僅考慮與位置無關的環(huán)境貼圖)和光照傳輸函數(shù)兩部分,這兩部分均可以看做是僅與方向有關的單位球面上的函數(shù),因此可以分別使用一個球諧函數(shù)系數(shù)矢量進行近似。如果光照交互所處的表面是漫反射表面,則這兩個球面函數(shù)乘機的積分是一個常數(shù),因該表面上光照的計算完全可以使用式10.17所示的兩個矢量的點乘表示,這兩個矢量的分量對應于這兩個方向分布函數(shù)在球面上的球諧函數(shù)投影系數(shù),其中光源的投影系數(shù)可以動態(tài)調(diào)整,而表面上的投影系數(shù)可以預計算并緩存起來,以供每一幀執(zhí)行光照計算,這樣就能提高靜態(tài)場景的計算效率,因為對于靜態(tài)場景,其光照傳輸是不變的。
然而,當表面是光澤面時,光源和傳輸函數(shù)乘積的積分不再是一個常數(shù)積分值,因為攝像機從不同方向觀察到的光照是不一樣的,因此它是另一個方向分布函數(shù),此時式10.17不再適用,新的問題轉(zhuǎn)換為對光影函數(shù)和傳輸函數(shù)的乘積(其結(jié)果為一個方向分布函數(shù))的投影近似,即,設c(s)=a(s)b(s)為兩個方向函數(shù)的乘積,我們需要對函數(shù)c(s)執(zhí)行另一個投影近似。
根據(jù)投影的定義,其投影系數(shù)可表示為目標函數(shù)和球諧函數(shù)乘機的積分,因此函數(shù)c(s)的投影系數(shù)可由下式計算:
在上式的第二行中,a(s)和b(s)分布被其投影系數(shù)近似,是一個三重積分張量(triple product tensor):
是一個3階對稱張量,這意味著如果在每個表面位置處存儲完全的光照傳輸,這需要每個頂點存儲一個三維矩陣,這顯然占用大量的存儲資源。但這里我們可以把光源部分抽取出來,即假設光照傳輸(即a(s)是已知的(固定的)而光源b(s)是未知可變的,那么表面上每個位置處的光源傳輸僅需要一個二維矩陣,該矩陣可以通過下式計算而出:)
卷積的投影
本書前面已經(jīng)討論過卷積的意義,它通常用來對原始信息進行平滑和過濾,在卷積計算中,一個核函數(shù)h分別作用于一個信號函數(shù)f的每一個位置處,其結(jié)果是一個更平滑的函數(shù),記為h*f。
核函數(shù)同樣可以用來平滑一個用球諧函數(shù)表述的方向分布函數(shù),給定一個圓對稱(circular symmetry)的核函數(shù)h(z),通過對一個原始函數(shù)f執(zhí)行卷積計算可以得到一個新的球諧函數(shù),注意,這里的核函數(shù)h(z)必須是圓對稱的,即垂直于z軸的平面上值相同,因此核函數(shù)可以只使用一個變量z表述,這樣才能保證卷積的結(jié)果依然位于球面S上。
在球面上,卷積可以直接作用于方向函數(shù)的頻率域(類似于傅里葉級數(shù),球諧函數(shù)實際上就是方向函數(shù)的頻率域),即:
即函數(shù)f的卷積就是該函數(shù)每個帶l內(nèi)的所有球諧函數(shù)fl,m被核函數(shù)的m=0項hl,0執(zhí)行一個縮放操作,因為核函數(shù)是圓對稱的,所以每個帶l內(nèi)僅只有m=0項(該項球諧函數(shù)又稱為帶諧函數(shù))具有非零值。
該卷積屬性提供了一種快速的方法用于計算環(huán)境貼圖于余弦核函數(shù)h(z)=max(z,0)的卷積計算,該操作可以得到一個輻射照度圖(irradiance map)。此外,卷積計算還可以用于對環(huán)境貼圖執(zhí)行預過濾操作以得到一個更平滑的環(huán)境貼圖。
10.1.3.2 ZXZXZ 旋轉(zhuǎn)
上述的遞推方法不對旋轉(zhuǎn)矩陣的形式做出任何已知的假設,對于每一次旋轉(zhuǎn)的計算,它都從最低的次數(shù)開始遞歸計算,以構(gòu)建整個旋轉(zhuǎn)矩陣的表達式。根據(jù)[xxx],遞推方法構(gòu)建旋轉(zhuǎn)矩陣的計算復雜度約為O(l三次方),對球諧函數(shù)系數(shù)矢量執(zhí)行旋轉(zhuǎn)操作的復雜度也為O(l三次方)。
[xxx]發(fā)現(xiàn),球諧函數(shù)圍繞z軸的旋轉(zhuǎn)具有比較簡單的形式和計算量,因此提出一種稱為ZXZXZ的旋轉(zhuǎn)方法,該方法構(gòu)建旋轉(zhuǎn)矩陣的復雜度約為上述遞推方法的一半,并且ZXZXZ方法直接推導出一個顯示公式然后直接作用于系數(shù)矢量,因此省去了顯式執(zhí)行旋轉(zhuǎn)變換的操作,進一步提高了旋轉(zhuǎn)計算的效率。
該方法首先使用符號積分(symbolic intergration)表述出球諧函數(shù)旋轉(zhuǎn)矩陣中每個元素的函數(shù),即:
上式具有什么意義呢?首先,我們需要解釋以下什么是符號積分?符號積分跟傳統(tǒng)的數(shù)值積分具有類似的含義,唯一的區(qū)別是數(shù)值積分計算的結(jié)果是一個確定的值,而符號積分的結(jié)果是一個函數(shù),也就是說被積函數(shù)中包含除積分變量以外的自變量,可以理解為符號積分就是尋找不定積分的公式形式,一次你上式10.26是一個函數(shù),它給出球諧函數(shù)旋轉(zhuǎn)矩陣Rsh中每個元素的形式;其次,那么旋轉(zhuǎn)矩陣是關于誰的函數(shù)呢?在式10.26中,R是一個使用歐拉角表述的三維旋轉(zhuǎn)矩陣,因此上述旋轉(zhuǎn)矩陣元素就是關于歐拉角的函數(shù);最后,為什么式10.26可以用來求球諧函數(shù)的旋轉(zhuǎn)矩陣呢,這是因為yiR(s)可以看作旋轉(zhuǎn)后的球諧函數(shù)基,回想一個函數(shù)與某個基函數(shù)乘機的積分可以表述為該函數(shù)在該基函數(shù)上的投影,而坐標變換正是關于每個原始坐標軸(函數(shù))在新坐標系各個基函數(shù)上的投影,所以式10.26的積分可以用來表述球諧函數(shù)的旋轉(zhuǎn)矩陣。
因此,如果能夠直接求出式10.26的形式,則可以直接將其用于球諧函數(shù)系數(shù)矢量的旋轉(zhuǎn)操作。例如,對于圍繞z軸的旋轉(zhuǎn),其可以表述為以下的形式:
根據(jù)上式,我們可以得出圍繞z軸的開頭三個帶的9x9旋轉(zhuǎn)矩陣為:
上述的矩陣形式也可以推廣到次數(shù)更高的球諧函數(shù),其中帶l對應的項為lα的正弦和余弦函數(shù)。從上述矩陣的結(jié)構(gòu)也可以看出前面介紹的遞推方法的思路,因此高次數(shù)的旋轉(zhuǎn)矩陣對應的正余弦函數(shù)可以展開為低次數(shù)旋轉(zhuǎn)矩陣對應的正余弦函數(shù)。
上述的矩陣Zα也揭示了一個特征,即圍繞z軸的旋轉(zhuǎn)矩陣具有比較簡潔而稀疏的形式,因此我們可以設想將整個旋轉(zhuǎn)矩陣Rsh分解為Rα與其他基本矩陣的組合,根據(jù)歐拉旋轉(zhuǎn)定理,[xxx]使用了ZXZ的旋轉(zhuǎn)組合,這樣三個基本旋轉(zhuǎn)矩陣的其中兩個都可以使用上述的圍繞z軸的旋轉(zhuǎn)矩陣Rα,剩下的問題只需要計算出圍繞y軸的旋轉(zhuǎn)矩陣即可。[xxx]進一步將該基礎矩陣分解為三個矩陣的組合:首先圍繞x軸旋轉(zhuǎn)90度,然后在圍繞z軸旋轉(zhuǎn)β角度,最后在圍繞x軸旋轉(zhuǎn)-90度。其中,由于圍繞x軸的兩次旋轉(zhuǎn)角度是固定的,因此這兩個旋轉(zhuǎn)矩陣可以被預存起來,即:
根據(jù)上述過程,原始的旋轉(zhuǎn)矩陣被分解為以下ZXZXZ的旋轉(zhuǎn)矩陣的組合:
。
總結(jié)
以上是生活随笔為你收集整理的基于预计算的全局光照技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【备战秋招系列-3】Java高频知识点—
- 下一篇: 线性调频信号及仿真[python]