全局光照:光線追蹤、路徑追蹤與GI技術進化編年史
全局光照(Global Illumination,簡稱 GI), 作為圖形學中比較酷的概念之一,是指既考慮場景中來自光源的直接光照,又考慮經過場景中其他物體反射后的間接光照的一種渲染技術。大家常聽到的光線追蹤,路徑追蹤等同樣很酷的概念,都是全局光照中人氣較高的算法流派。
而這篇文章將圍繞全局光照技術,介紹的要點有:
全局光照的基本概念
全局光照的算法主要流派
全局光照技術進化編年史
光線追蹤 Ray Tracing
路徑追蹤 Path Tracing
光線追蹤、路徑追蹤、光線投射的區(qū)別
環(huán)境光遮蔽 Ambient Occlusion
一、行文思路說明
閱讀過《Real-Time Rendering 3rd》第九章的讀者們都會發(fā)現(xiàn),作為一章關于全局光照的章節(jié),作者講了不少在嚴格意義上全局光照主線以外的內容,如Reflections、Refractions、Shadow等節(jié),而這些內容在《Real-Time Rendering 2nd》中,其實是放在Chapter 6 Advanced Lighting and Shading一節(jié)的。
既然《Real-Time Rendering 3rd》第九章標題就叫全局光照,核心內容也是全局光照,本文即決定脫離原書安排的100來頁的多余內容,以全局光照的主線內容為主,構成一篇包含全局光照基本概念,主要算法流派,以及全局光照技術進化編年史,和全局光照算法中人氣較高的光線追蹤、路徑追蹤等算法的綜述式文章。
二、全局光照
全局光照,(Global Illumination,簡稱 GI), 或被稱為Indirect Illumination, 間接光照,是指既考慮場景中直接來自光源的光照(Direct Light)又考慮經過場景中其他物體反射后的光照(Indirect Light)的一種渲染技術。使用全局光照能夠有效地增強場景的真實感。
?
即可以理解為:全局光照 = 直接光照(Direct Light) + 間接光照(Indirect Light)


上述兩幅圖片來自CMU 15-462/15-662, Fall 2015 Slider,Lecture 14: Global Illumination,當然,細心的朋友也可以發(fā)現(xiàn),它也被《Physically Based Rendering,Second Edition From Theory To Implementation》選作封面。
可以發(fā)現(xiàn),加入了Indirect illumination的圖2,在直接光源(陽光)照射不到的地方,得到了更好的亮度和細節(jié)表現(xiàn),從而使整張渲染效果更具真實感。
雖說實際應用中只有漫反射全局照明的模擬算法被稱為全局照明算法,但其實理論上說反射、折射、陰影都屬于全局光照的范疇,因為模擬它們的時候不僅僅要考慮光源對物體的直接作用還要考慮物體與物體之間的相互作用。也是因為,鏡面反射、折射、陰影一般不需要進行復雜的光照方程求解,也不需要進行迭代的計算。因此,這些部分的算法已經十分高效,甚至可以做到實時。不同于鏡面反射,光的漫反射表面反彈時的方向是近似“隨機”,因此不能用簡單的光線跟蹤得到反射的結果,往往需要利用多種方法進行多次迭代,直到光能分布達到一個基本平衡的狀態(tài)。
三、全局光照的主要算法流派
經過幾十年的發(fā)展,全局光照現(xiàn)今已有多種實現(xiàn)方向,常見的全局光照主要流派列舉如下:
Ray tracing 光線追蹤
Path tracing 路徑追蹤
Photon mApping 光子映射
Point Based Global Illumination 基于點的全局光照
Radiosity 輻射度
Metropolis light transport 梅特波利斯光照傳輸
Spherical harmonic lighting 球諧光照
Ambient occlusion 環(huán)境光遮蔽
Voxel-based Global Illumination 基于體素的全局光照
Light Propagation Volumes Global Illumination
Deferred Radiance Transfer Global Illumination
Deep G-Buffer based Global Illumination
等。
而其中的每種流派,又可以劃分為N種改進和衍生算法。
如光線追蹤(Ray Tracing)派系,其實就是一個框架,符合條件的都可稱為光線追蹤,其又分為遞歸式光線追蹤(Whitted-style Ray Tracing),分布式光線追蹤(DistributionRay Tracing),蒙特卡洛光線追蹤(Monte Carlo Ray Tracing)等。
而路徑追蹤(Path tracing)派系,又分為蒙特卡洛路徑追蹤(Monte Carlo Path Tracing),雙向路徑追蹤(BidirectionalPath Tracing),能量再分配路徑追蹤(Energy Redistribution PathTracing)等。
其中有些派系又相互關聯(lián),如路徑追蹤,就是基于光線追蹤,結合了蒙特卡洛方法而成的一種新的派系。
四、全局光照技術進化編年史
這節(jié)以光線追蹤和路徑追蹤派系為視角,簡單總結一下全局光照技術發(fā)展早期(1968-1997)的重要里程碑。
4.1 光線投射 Ray Casting [1968]
光線投射(Ray Casting),作為光線追蹤算法中的第一步,其理念起源于1968年,由Arthur Appel在一篇名為《 Some techniques for shading machine rendering of solids》的文章中提出。其具體思路是從每一個像素射出一條射線,然后找到最接近的物體擋住射線的路徑,而視平面上每個像素的顏色取決于從可見光表面產生的亮度。

4.2 光線追蹤 Ray Tracing [1979]
1979年,Turner Whitted在光線投射的基礎上,加入光與物體表面的交互,讓光線在物體表面沿著反射,折射以及散射方式上繼續(xù)傳播,直到與光源相交。這一方法后來也被稱為經典光線跟蹤方法、遞歸式光線追蹤(Recursive Ray Tracing)方法,或 Whitted-style 光線跟蹤方法。
光線追蹤方法主要思想是從視點向成像平面上的像素發(fā)射光線,找到與該光線相交的最近物體的交點,如果該點處的表面是散射面,則計算光源直接照射該點產生的顏色;如果該點處表面是鏡面或折射面,則繼續(xù)向反射或折射方向跟蹤另一條光線,如此遞歸下去,直到光線逃逸出場景或達到設定的最大遞歸深度。

圖4 經典的光線追蹤: 每像素從眼睛投射射線到場景,并追蹤次級光線((shadow, reflection, refraction),并結合遞歸
4.3 分布式光線追蹤 Distributed Ray Tracing [1984]
Cook于1984年引入蒙特卡洛方法(Monte Carlo method)到光線跟蹤領域,將經典的光線跟蹤方法擴展為分布式光線跟蹤算法(Distributed Ray Tracing),又稱為隨機光線追蹤(stochasticray tracing),可以模擬更多的效果,如金屬光澤、軟陰影、景深( Depthof Field)、運動模糊等等。
4.4 渲染方程 The Rendering Equation [1986]
在前人的研究基礎上,Kajiya于1986年進一步建立了渲染方程的理論,并使用它來解釋光能傳輸?shù)漠a生的各種現(xiàn)象。這一方程描述了場景中光能傳輸達到穩(wěn)定狀態(tài)以后,物體表面某個點在某個方向上的輻射率(Radiance)與入射輻射亮度等的關系。
可以將渲染方程理解為全局光照算法的基礎,Kajiya在1986年第一次將渲染方程引入圖形學后,隨后出現(xiàn)的很多全局光照的算法,都是以渲染方程為基礎,對其進行簡化的求解,以達到優(yōu)化性能的目的。渲染方程根據(jù)光的物理學原理,以及能量守恒定律,完美地描述了光能在場景中的傳播。很多真實感渲染技術都是對它的一個近似。渲染方程在數(shù)學上的表示如下:


4.5 路徑追蹤 Path Tracing [1986]
Kajiya也于1986年提出了路徑追蹤算法的理念,開創(chuàng)了基于蒙特卡洛的全局光照這一領域。根據(jù)渲染方程, Kajiya 提出的路徑追蹤方法是第一個無偏(Unbiased)的渲染方法。路徑追蹤的基本思想是從視點發(fā)出一條光線,光線與物體表面相交時根據(jù)表面的材質屬性繼續(xù)采樣一個方向,發(fā)出另一條光線,如此迭代,直到光線打到光源上(或逃逸出場景),然后用蒙特卡洛的方法,計算其貢獻,作為像素的顏色值。
4.6 雙向路徑追蹤 Bidirectional Path Tracing [1993,1994]
雙向路徑追蹤(Bidirectional Path Tracing)的基本思想是同時從視點、光源打出射線,經過若干次反彈后,將視點子路徑( eye path) 和光源子路徑( light path) 上的頂點連接起來(連接時需要測試可見性),以快速產生很多路徑。這種方法能夠產生一些傳統(tǒng)路徑追蹤難以采樣到的光路,所以能夠很有效地降低噪聲。 進一步的, [Veach 1997]將渲染方程改寫成對路徑積分的形式,允許多種路徑采樣的方法來求解該積分。
4.7 梅特波利斯光照傳輸 Metropolis Light Transport [1997]
Eric Veach等人于1997年提出了梅特波利斯光照傳輸(Metropolis Light Transport,常被簡稱為MLT)方法。路徑追蹤( Path Tracing)中一個核心問題就是怎樣去盡可能多的采樣一些貢獻大的路徑,而該方法可以自適應的生成貢獻大的路徑,簡單來說它會避開貢獻小的路徑,而在貢獻大的路徑附近做更多局部的探索,通過特殊的變異方法,生成一些新的路徑,這些局部的路徑的貢獻往往也很高。 與雙向路徑追蹤相比, MLT 更加魯棒,能處理各種復雜的場景。比如說整個場景只通過門縫透進來的間接光照亮,此時傳統(tǒng)的路徑追蹤方法因為難以采樣到透過門縫的這樣的特殊路徑而產生非常大的噪聲。
五、光線追蹤 Ray Tracing
光線追蹤(Ray tracing)是三維計算機圖形學中的特殊渲染算法,跟蹤從眼睛發(fā)出的光線而不是光源發(fā)出的光線,通過這樣一項技術生成編排好的場景的數(shù)學模型顯現(xiàn)出來。這樣得到的結果類似于光線投射與掃描線渲染方法的結果,但是這種方法有更好的光學效果,例如對于反射與折射有更準確的模擬效果,并且效率非常高,所以當追求高質量的效果時經常使用這種方法。
上文已經提到過,Whitted于1979年提出了使用光線跟蹤來在計算機上生成圖像的方法,這一方法后來也被稱為經典光線跟蹤方法、遞歸式光線追蹤方法,或 Whitted-style 光線跟蹤方法。其主要思想是從視點向成像平面上的像素發(fā)射光線,找到與該光線相交的最近物體的交點,如果該點處的表面是散射面,則計算光源直接照射該點產生的顏色;如果該點處表面是鏡面或折射面,則繼續(xù)向反射或折射方向跟蹤另一條光線,如此遞歸下去,直到光線逃逸出場景或達到設定的最大遞歸深。
以下這張圖示可以很好的說明光線追蹤方法的思路:





光線跟蹤的一個最大的缺點就是性能,需要的計算量非常巨大,以至于目前的硬件很難滿足實時光線追蹤的需求。傳統(tǒng)的光柵圖形學中的算法,利用了數(shù)據(jù)的一致性從而在像素之間共享計算,但是光線跟蹤通常是將每條光線當作獨立的光線,每次都要重新計算。但是,這種獨立的做法也有一些其它的優(yōu)點,例如可以使用更多的光線以抗混疊現(xiàn)象,并且在需要的時候可以提高圖像質量。盡管它正確地處理了相互反射的現(xiàn)象以及折射等光學效果,但是傳統(tǒng)的光線跟蹤并不一定是真實效果圖像,只有在非常近似或者完全實現(xiàn)渲染方程的時候才能實現(xiàn)真正的真實效果圖像。由于渲染方程描述了每個光束的物理效果,所以實現(xiàn)渲染方程可以得到真正的真實效果,但是,考慮到所需要的計算資源,這通常是無法實現(xiàn)的。于是,所有可以實現(xiàn)的渲染模型都必須是渲染方程的近似,而光線跟蹤就不一定是最為可行的方法。包括光子映射在內的一些方法,都是依據(jù)光線跟蹤實現(xiàn)一部分算法,但是可以得到更好的效果。
用一套光線追蹤的偽代碼,結束這一節(jié)的介紹:
六、路徑追蹤 Rath Tracing
路徑追蹤(Rath Tracing)方法由Kajiya在1986年提出,是第一個無偏(Unbiased)的渲染方法。
路徑追蹤方法的基本思想是從視點發(fā)出一條光線,光線與物體表面相交時根據(jù)表面的材質屬性繼續(xù)采樣一個方向,發(fā)出另一條光線,如此迭代,直到光線打到光源上(或逃逸出場景),然后用蒙特卡洛方法,計算光線的貢獻,作為像素的顏色值。而使用蒙特卡洛方法對積分的求解是無偏的,只要時間足夠長,最終圖像能收斂到一個正確的結果。
?
簡單來說,路徑追蹤 = 光線追蹤+ 蒙特卡洛方法。
?
這里有一個用99行代碼實現(xiàn)路徑追蹤算法的一個簡易全局光照渲染器,有興趣的朋友可以進行了解:
http://www.kevinbeason.com/smallpt/




七、Ray Casting , Ray Tracing,PathTracing區(qū)別
學者往往會弄不明白光線投射(Ray Casting ),光線追蹤(Ray Tracing),路徑追蹤(Path Tracing)三者的的區(qū)別,龔大@龔敏敏 在https://www.zhihu.com/question/29863225這個答案中的回答已經很精辟,本文就直接引用了過來:
Ray Tracing:這其實是個框架,而不是個方法。符合這個框架的都叫raytracing。這個框架就是從視點發(fā)射ray,與物體相交就根據(jù)規(guī)則反射、折射或吸收。遇到光源或者走太遠就停住。一般來說運算量不小。
Ray Casting:其實這個和volumetric可以脫鉤。它就是ray tracing的第一步,發(fā)射光線,與物體相交。這個可以做的很快,在Doom 1里用它來做遮擋。
Path Tracing:是ray tracing + 蒙特卡洛法。在相交后會選一個隨機方向繼續(xù)跟蹤,并根據(jù)BRDF計算顏色。運算量也不小。還有一些小分類,比如Bidirectional path tracing。
文末,簡單聊一下環(huán)境光遮蔽,AO。
八、環(huán)境光遮蔽 Ambient Occlusion
環(huán)境光遮蔽(Ambient Occlusion,簡稱AO)是全局光照明的一種近似替代品,可以產生重要的視覺明暗效果,通過描繪物體之間由于遮擋而產生的陰影, 能夠更好地捕捉到場景中的細節(jié),可以解決漏光,陰影漂浮等問題,改善場景中角落、鋸齒、裂縫等細小物體陰影不清晰等問題,增強場景的深度和立體感。
可以說,AO 特效在直觀上給玩家的主要感覺體現(xiàn)在畫面的明暗程度上,未開啟 AO 特效的畫面光照稍亮一些;而開啟環(huán)境光遮蔽特效之后, 局部的細節(jié)畫面尤其是暗部陰影會更加明顯一些。
Ambient Occlusion的細分種類有:
SSAO-Screen space ambient occlusion
SSDO-Screen space directional occlusion
HDAO-High Definition Ambient Occlusion
HBAO+-Horizon Based Ambient Occlusion+
AAO-Alchemy Ambient Occlusion
ABAO-Angle Based Ambient Occlusion
PBAO
VXAO-Voxel Accelerated Ambient Occlusion
一般而言,Ambient Occlusion最常用方法是SSAO,如Unreal Engine 4中的AO,即是用SSAO實現(xiàn)。
接下來貼一些和AO相關的圖,結束這篇文章。





圖19 一張典型的環(huán)境光遮蔽的渲染圖

九、其他參考
[1]?http://15462.courses.cs.cmu.edu/fall2015/lecture/globalillum
[2]?https://docs.unrealengine.com/latest/INT/Engine/Rendering/LightingAndShadows/AmbientOcclusion/
[3]?https://en.wikipedia.org/wiki/Ambient_occlusion
[4]?https://www.ics.uci.edu/~gopi/CS211B/RayTracing%20tutorial.pdf
[5]?http://www.cnblogs.com/hielvis/p/6371840.html
[6]?http://blog.csdn.net/thegibook/article/details/53058206
[7]?http://www.di.ubi.pt/~agomes/cig/teoricas/02-raycasting.pdf
[8]?https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-837-computer-graphics-fall-2012/
全局光照:光線追蹤、路徑追蹤與GI技術進化編年史的評論 (共 條)
