全局光照技術進化史1-光線追蹤篇

本來計劃是最近一年專心寫書,不要花心思和精力寫博客的,因爲寫一篇優質的博客文章其實也要花費不少的時間構思的:單篇博客雖然文字少但是你可能需要花費更多的精力在有限的篇幅內包括更多上下文信息,以及更精簡地組織內容,在我看來它的創作付出不亞於圖書內容寫作(當然如果作者對自己要求沒那麼嚴謹的話可能也沒那麼嚴重)。

《遊戲引擎全局光照技術》採取了一種新的出版形式,它從寫作第一章開始,就積極和社區互動並開始宣傳,其方式和遊戲發行的思路一致:即在開發階段不斷推出測試版積極和玩家互動,並收集反饋信息進行持續改進。這樣做的好處是:讀者較早獲得試讀版的信息,瞭解和監督了書的寫作質量,從而可以做出有效判斷是否值得購買,糟糕的圖書質量可能在這一階段就直接被淘汰,甚至失去了出版意義,從而保障讀者利益;同時對於作者,我能夠持續吸收社區反饋意見以改進內容質量,使圖書的質量可以不斷地形成增益,好的內容能夠被社區傳播擴散;這對於讀者和作者都是一件共贏的事情。

爲此,我已經提供了該書1,2,3三章共計157頁正文的試讀內容供所有對該書感興趣的朋友免費下載,如果您還不知道可以從這裏下載。然而儘管如此,從目前社區討論的信息來看,大部分讀者還是不太明白這本書跟其它同類書籍會有什麼不同,儘管我已經使用一個問答的形式來簡要概述這本書的特點,然而我們都知道,這些文字跟你在技術大會上那些廠商遞給你的一個介紹他們公司產品的小冊子上的文字一樣:在你使用它們的產品之前,那些文字通常跟屁沒有什麼差別。

所以我需要寫一點更通俗篇幅相對長一點的文章來解釋這本書的內容和特點,通俗使得您可以像讀其它社交信息一樣很輕鬆地進行閱讀,不需要太多思考和理解,而篇幅需要長到足以介紹這本書覆蓋的內容和特點。正巧在百度貼吧的“孤島危機吧”看到一篇想要了解各種全局光照技術的特點及聯繫的帖子,他所提出的問題正是本書試圖去討論的內容,所以我就想回答了他的問題其實基本上能夠說明這本書的內容和特點。

學習全局光照技術(Global Illumination,以下簡稱GI)比較頭疼的一個因素是它的方法派別太多了,每個算法可能涉及到完全不同的數學方法,而如果我們沒有對方法本身的思路具有一定的理解,在運用方面也不會很順手,尤其涉及到要進行優化或修改以滿足特定需求時,你必須要比較全面的理解該方法:它的起源,歷史,數學模型,新方法的優缺點,它在計算性能和圖像質量方面有着怎樣的折中等等;並且,通常每種方法並不像一個軟件模塊那樣比較獨立很好理解,每種GI算法往往涉及CPU/GPU的數據結構表述,內存佈局以及訪問,和渲染管線其它階段(如Deferred Shading,AA等)的協作,圖形接口的運用,算法處理器級別的優化等,這些因素使得GI的學習並不那麼輕鬆。

所以我在2015年初就萌生了寫作一本圍繞各種GI技術來進行內容組織的書籍,它不像《Real-time Rendering》這類書籍一樣基本上以各個理論知識點爲中心,它以方法爲中心(儘管如此,本書還是包括了將近300頁的基本理論知識的介紹),着重討論各種GI方法背後的思路以及方法之間的聯繫,因此它較偏理論性的書籍擁有更強的實踐性。這種寫作思路其實類似於《Advanced Global Illumination》(簡稱AGI),但是AGI基本上主要圍繞路徑追蹤和輻射度理論兩種方法來講述,其它一些如光子映射等有一定的介紹,但是篇幅極短;本書不但會介紹路徑追蹤和輻射度理論等這些離線全局光照技術,還會介紹時下比較流行的距離場,體素等實時的全局光照技術,並且本書結合Unreal Engine等遊戲引擎來講述,讀者更夠更好地理解這些引擎的功能特性。

這篇文章,我們就來看看全局光照技術的進化史。遵循通俗的原則,本文不會包含數學公式,全部內容是以文字和配圖描述,當然這樣的方式肯定不可能包含很多細節,它更注重的是思路描述,更具體的信息還請您參考《遊戲引擎全局光照技術》圖書內容。

我們從光線追蹤算法開始。光線追蹤算法的起源可以早至1968年,Arthur Appel在一篇名爲《Ray-tracing and other Rendering Approaches》的論文中提出的Ray Casting的概念,我們稱爲光線投射,如下圖所示,光線投射其實只是一根單一的從一個點向一個方向發射出光線,它與場景中的物體相交時停止,Appel的算法中使用了View Ray和Shadow Ray兩條光線,這計算出來的其實就是光照方程中的直接光照部分。

Ray Casting

1979年,Turner Whitted在光線投射的基礎上,加入光與物體表面的交互,是光線在物體表面沿着反射,折射以及散射方式上繼續傳播,直到與光源相交。如下圖所示,這種算法形成了一個遞歸的光線穿梭,因此此時不再是一根單一的光線,而是形成了一個光傳輸的路徑,此時的算法稱爲遞歸光線追蹤(Recursive Ray Tracing,或者Whitted-style ray tracing);顯然,光線在多個表面上反射或折射,間接光被考慮進來,光在經過每一個表面的時候,通過該表面的反射/折射率的“過濾”,它將物體的顏色***到鄰近物體的表面上,這就是我們所說的Bleeding。

Recursive Ray Tracing

然而Whitted的模型是基於純高光反射的,它假設物體表面絕對光滑,這顯然和大自然中大部分物質的表面屬性不相符。在計算機圖形學中,一個像素的尺寸遠遠大於光的波長,在這個微觀尺寸(Microfacet)下,物體表面是不光滑的,也就是說進入一個像素的多個光線可能分別被反射到不同的方向上,根據表面粗糙度的不同,這些散射的方向呈現不同的分佈,非常粗糙的表面可能比較均勻地周圍反射,而比較光滑的表面反射光則集中在光滑表面的反射方向附近。在現代渲染技術中,這些反射特性通常被使用Microfacet BRDF公式表述出來,它基本上使用一個簡單的粗糙度方向就可以模擬出比較真實的光反射分佈。結合金屬性等一些參數,這就是目前流行的基於物理的渲染模型。

ray-optics-6

通常這些不同的分佈被使用漫反射和高光反射兩種分佈來表述,如上圖所示。1984年,Cook提出了分配光線追蹤(Distribution ray tracing),他使得原來一束單一的反射光變爲圍繞一個空間中漫反射或高光反射範圍內的積分計算,如下圖所示。爲了計算積分方程,蒙特卡洛方法被引入,所以Cook的方法又稱爲隨機光線追蹤(stochastic ray tracing)。

  • Stochastic ray tracing

  • Stochastic ray tracing

然而,Cook的模型計算代價非常高,每一條從攝像機發出的光線在表面點是被反射至多個不同的方向,分散成多束光線,以此遞歸,每條光線最終形成一個光線樹(a tree of rays),尤其對於間接漫反射光,它幾乎要反射至整個可見空間。

Cook的模型是由光照公式遞歸的特性決定的,光照公式中每個入射光的值來源於其它許多表麪點反射的計算結果。1986年,Kajiya統一了光照公式,並推導出了光照公式的路徑表述形式,使得光照公式由一個遞歸的結構,變成一個路徑函數的積分,因此蒙特卡洛的每個隨機數只要產生一條路徑即可,這些路徑不需要是遞歸的,因此每條路徑可以隨機生成,然後每個路徑的值作爲一個隨機數用於計算最終的光照結果。這種新的形式稱爲路徑追蹤(Path tracing),如下圖所示。在路徑追蹤算法中,首先在場景中物體的表面隨機產生一些點,然後將這些點和光源以及攝像機鏈接起來形成一條路徑,每個路徑就是一個路徑函數的隨機值。這樣的路徑,根據場景的複雜度,每幀可能包括上億條光線,因此傳統的路徑追蹤算法很難運用到實時渲染領域。

  • path tracing

  • path tracing

上述這樣的產生隨機路徑的方式有一個問題,有相當部分的路徑組合由於表面間可能被遮擋而形成無效的路徑,對最終光照沒有任何貢獻,因此大部分實現都是以增量的形式,在每個有效的反射或折射方向上進行隨機採樣,已形成更多有效的路徑;

另一個問題是由於光源面積相對於整個場景很小,由攝像機出發的路徑最終落在光源面積內的機率很小,因此雙向路徑追蹤(Bidirectional path tracing)被提出,它分別從光源和攝像機兩個方向出發,分別經過一定的路徑之後,將該兩條路徑的終點鏈接起來形成一條完整的路徑,這樣大大增加了光源的有效貢獻,可以從下圖看出兩者之間的區別。

untitled

當前大部分高質量的離線渲染器基本上都是基於路徑追蹤算法實現的,然而路徑追蹤的計算成本仍然非常高昂。現代路徑追蹤算法的發展主要有兩大方向:其一是圍繞提升上億光線之間的連貫性(coherence)來提升處理器的利用率從而大幅提升計算效率,其二是微軟Metropolis算法來使採樣的隨機路徑更接近最終圖像的真實顏色分佈,後者稱爲MLT(Metropolis Light transfer)。

光線/路徑追蹤算法高昂的計算成本不僅來源於蒙特卡洛積分使用的大數定律要求的巨大的光線數量,另一方面重要的因素還在於路徑追蹤算法及其使用的數據結構不能適應現代CPU/GPU使用的執行模型。首先是內存執行模型,由於處理器計算單元的速度和內存數據存取的速度存在巨大差異,計算單元從內存中獲取數據存在巨大的延遲(Latency),現代處理器非常嚴重地依賴於緩存技術,即將較大一塊的內存數據緩存在具有更高讀取速度的緩存中,如下圖所示,緩存系統通常設計爲多層機構,每一層比下一層具有更高的訪問速度,但是更高速度的緩存硅片的成本更高,所以更高速度的緩存往往存儲的數據量更小,這樣頂層的一級緩存的速度跟寄存器的訪問速度比較接近,通過緩存系統,計算單元到內存的數據訪問延遲就被掩藏了。

path-14

緩存系統是根據傳統應用程序的特點設計的,通常,相鄰指令使用的數據在內存區域也是相鄰的,所以相對寄存器更大一塊的數據能夠被多條指令使用。當指令從上一級緩存獲取不到需要的數據時,就會從下一級緩存一次性獲取另一塊數據,並替換原來的數據,這種情況稱爲緩存失效。因此應用程序必須在數據上保持一定的連貫性,才能充分利用緩存特性,以提高計算性能。而路徑追蹤算法顯然不符合這樣的條件,每一條光線可能隨機穿向任意一個方向,從而與環境中任意表面進行相交,所以相鄰的指令使用的數據往往分散在內存中的各個區域,大大減少緩存命中的機率。

處理器架構的另一個特點是稱爲單指令多數據(SIMD)的計算模型,在SIMD中,寄存器一次性讀取多個數據變量,這些數據被同一條指令執行,例如傳統的CPU環境中SIMD寄存器可以讀取128位數據,分別可以表示4個32位的數據,如下圖所示,而在GPU環境下,每個GPU線程束可以一次性計算32個線程,當這32個線程所需要的數據在內存結構上相鄰時,它們可以被一次性存儲,大大減少每個線程獲取線程帶來的事務開銷。

path-16-2

所以,基於連貫性(coherence)的路徑追蹤技術將這些數據分組成一些小的數據包,稱爲光線包(ray packet),這些數據包包含多個內存相鄰的數據,並能能夠被同一個指令執行。傳統的基於光線包的技術主要是針對主要光線(Primary rays),即攝像機向場景發射出的光線,之後的光線可能向場景隨處發射,並且對性能影響更大。

2013年,迪斯尼的Christian Eisenacher等在一篇名爲《sorted deferred shading for production path tracing》的論文中提出了一種改進方法,這種方法的核心思想是在實際計算之前對光線進行排序,如下圖所示。

path-10

在實際處理中,這主要分爲三步(如上圖左邊的流程):首先,在每次增量計算光線與場景相交時,首先對光線進行排序,並將這些經過排序的光線按照方向以及數量大小分成多個包,然後以這些包爲單位進行計算;其次,對場景建立一個BVH的加速結構,經過打包後的光線是連貫的,所以其相交計算涉及的場景表面在空間上也是連續的,因此能夠比較友好地使用緩存和SIMD處理器特性;最後,由於來自各個方向光線可能與同一表面進行相交,所以在相交計算時直接計算光照反射並不是很高效,所以迪斯尼將着色分離出來,在相交計算的時候,所有相交點與紋理信息進行關聯,紋理被劃分成一些區域,然後着色計算以紋理區域爲單位進行計算。通過以上這些優化,如下圖所示,Disney新的路徑追蹤渲染器渲染性能得到極大提高,這些技術連同Disney的BSDF等技術一同被首次運用在《超能陸戰隊》以及後續的電影中。

path-12

基於連貫性的路徑追蹤算法的思想能夠很好地利用現代處理器的架構特徵,不管什麼樣的路徑追蹤算法基本上都可以在這方面進行改善,這也是傳統路徑追蹤技術走向實時的方向。

基於Metropolis算法的MLT方法則着重於更準確地對路徑進行採樣,以計算更高品質的圖像,畢竟傳統的路徑追蹤算法很多路徑採樣的貢獻率可能很低。Metropolis算法的核心思想是使用馬爾可夫鏈(Markov Chain),它對當前隨機數進行一個適當尺度的擾動(perturbation)以產生一個新的隨機數,然後使用逼近真實分佈函數的概率來對新的隨機點進行取捨,這樣使得新的採樣點滿足實際分佈函數的分佈。

qq20161106-02x

由於路徑追蹤算法每個隨機數產生的是一個路徑計算的光照結果,因此MLT中的每一個隨機數是一個路徑,這個新的路徑根據一定的策略對前一路徑的某些部分進行擾動,以產生一條新的路徑,然後計算出的該路徑的光照結果就是每個隨機數計算出的光照數值。

由於MLT中的每個隨機數是一個路徑的結果,整個路徑的分佈就是整個圖像的顏色分佈,因此MLT計算出的是整個圖像的結果,然後每個像素點需要使用過濾器對每個像素周圍的顏色值按照一定的權重比例進行加權平均。

qq20161106-12x

原始的MLT算法直接在路徑空間(Path space)對路徑中的頂點進行擾動,這樣新產生的路徑可能存在被遮擋的可能,因此產生非常多的無效的被捨棄的隨機數,Csaba Kelemen等於2012年的論文《A Simple and Robust Mutation Strategy for the Metropolis Light Transport Algorithm》中提出在一個超立方體(hypercube)作用域內,即所謂的Primary space對路徑進行擾動,超立方體內的每個隨機數是[0,1]範圍內的均勻分佈產生的隨機數,這個隨機數使用BRDF等分佈的逆向變換算法求出實際的方向或者點燈隨機數,這些隨機數用於產生新的路徑,這樣的基於Primary space產生的隨機路徑具有較高的接受率。

qq20161106-22x

更新的基於MLT的算法基於路徑求導來產生更好的符合表面光照分佈的擾動,例如對於高光,它能夠在高光方向上選擇更多的方向,以使MLT計算的結果更接近於真實圖像的分佈,如上圖所示。關於路徑求導,以及其它如基於梯度的MLT算法等這種使馬爾可夫鏈產生的隨機數分佈更加接近圖像真實分佈的思路,是路徑追蹤技術方向目前比較熱門的主題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章