1. 程式人生 > >全局光照:光線追蹤、路徑追蹤與GI技術進化編年史

全局光照:光線追蹤、路徑追蹤與GI技術進化編年史

參考 distrib hot nbsp 算法 iss gin ssd 遮擋

全局光照(Global Illumination,簡稱 GI), 作為圖形學中比較酷的概念之一,是指既考慮場景中來自光源的直接光照,又考慮經過場景中其他物體反射後的間接光照的一種渲染技術。

大家常聽到的光線追蹤,路徑追蹤等同樣很酷的概念,都是全局光照中人氣較高的算法流派。

而這篇文章將圍繞全局光照技術,介紹的要點有:

  • 全局光照的基本概念
  • 全局光照的算法主要流派
  • 全局光照技術進化編年史
  • 光線追蹤 Ray Tracing
  • 路徑追蹤 Path Tracing
  • 光線追蹤、路徑追蹤、光線投射的區別
  • 環境光遮蔽 Ambient Occlusion

一、行文思路說明

閱讀過《Real-Time Rendering 3rd》第九章的讀者們都會發現,作為一章關於全局光照的章節,作者講了不少在嚴格意義上全局光照主線以外的內容,如Reflections、Refractions、Shadow等節,而這些內容在《Real-Time Rendering 2nd》中,其實是放在Chapter 6 Advanced Lighting and Shading一節的。

既然《Real-Time Rendering 3rd》第九章標題就叫全局光照,核心內容也是全局光照,本文即決定脫離原書安排的100來頁的多余內容,以全局光照的主線內容為主,構成一篇包含全局光照基本概念,主要算法流派,以及全局光照技術進化編年史,和全局光照算法中人氣較高的光線追蹤、路徑追蹤等算法的綜述式文章。

二、全局光照

全局光照,(Global Illumination,簡稱 GI), 或被稱為Indirect Illumination, 間接光照,是指既考慮場景中直接來自光源的光照(Direct Light)又考慮經過場景中其他物體反射後的光照(Indirect Light)的一種渲染技術。使用全局光照能夠有效地增強場景的真實感。

即可以理解為:全局光照 = 直接光照(Direct Light) + 間接光照(Indirect Light)

技術分享

圖1 Direct illumination

技術分享

圖2 Global illumination = Direct illumination +Indirect illumination

上述兩幅圖片來自CMU 15-462/15-662, Fall 2015 Slider,Lecture 14: Global Illumination,當然,細心的朋友也可以發現,它也被《Physically Based Rendering,Second Edition From Theory To Implementation》選作封面。

可以發現,加入了Indirect illumination的圖2,在直接光源(陽光)照射不到的地方,得到了更好的亮度和細節表現,從而使整張渲染效果更具真實感。

雖說實際應用中只有漫反射全局照明的模擬算法被稱為全局照明算法,但其實理論上說反射、折射、陰影都屬於全局光照的範疇,因為模擬它們的時候不僅僅要考慮光源對物體的直接作用還要考慮物體與物體之間的相互作用。也是因為,鏡面反射、折射、陰影一般不需要進行復雜的光照方程求解,也不需要進行叠代的計算。因此,這些部分的算法已經十分高效,甚至可以做到實時。不同於鏡面反射,光的漫反射表面反彈時的方向是近似“隨機”,因此不能用簡單的光線跟蹤得到反射的結果,往往需要利用多種方法進行多次叠代,直到光能分布達到一個基本平衡的狀態。

三、全局光照的主要算法流派

經過幾十年的發展,全局光照現今已有多種實現方向,常見的全局光照主要流派列舉如下:

  • Ray tracing 光線追蹤
  • Path tracing 路徑追蹤
  • Photon mapping 光子映射
  • Point Based Global Illumination 基於點的全局光照
  • Radiosity 輻射度
  • Metropolis light transport 梅特波利斯光照傳輸
  • Spherical harmonic lighting 球諧光照
  • Ambient occlusion 環境光遮蔽
  • 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)等。

其中有些派系又相互關聯,如路徑追蹤,就是基於光線追蹤,結合了蒙特卡洛方法而成的一種新的派系。

四、全局光照技術進化編年史

這節以光線追蹤和路徑追蹤派系為視角,簡單總結一下全局光照技術發展早期(1968-1997)的重要裏程碑。

4.1 光線投射 Ray Casting [1968]

光線投射(Ray Casting),作為光線追蹤算法中的第一步,其理念起源於1968年,由Arthur Appel在一篇名為《 Some techniques for shading machine rendering of solids》的文章中提出。其具體思路是從每一個像素射出一條射線,然後找到最接近的物體擋住射線的路徑,而視平面上每個像素的顏色取決於從可見光表面產生的亮度。

技術分享

圖3 光線投射:每像素從眼睛投射射線到場景

4.2 光線追蹤 Ray Tracing [1979]

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

技術分享

圖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年進一步建立了渲染方程的理論,並使用它來解釋光能傳輸的產生的各種現象。這一方程描述了場景中光能傳輸達到穩定狀態以後,物體表面某個點在某個方向上的輻射率(Radiance)與入射輻射亮度等的關系。

可以將渲染方程理解為全局光照算法的基礎,Kajiya在1986年第一次將渲染方程引入圖形學後,隨後出現的很多全局光照的算法,都是以渲染方程為基礎,對其進行簡化的求解,以達到優化性能的目的。渲染方程根據光的物理學原理,以及能量守恒定律,完美地描述了光能在場景中的傳播。很多真實感渲染技術都是對它的一個近似。渲染方程在數學上的表示如下:

技術分享

技術分享

圖5 渲染方程描述了從x點沿某一方向看的光放射的總額。

4.5 路徑追蹤 Path Tracing [1986]

Kajiya也於1986年提出了路徑追蹤算法的理念,開創了基於蒙特卡洛的全局光照這一領域。根據渲染方程, Kajiya 提出的路徑追蹤方法是第一個無偏(Unbiased)的渲染方法。路徑追蹤的基本思想是從視點發出一條光線,光線與物體表面相交時根據表面的材質屬性繼續采樣一個方向,發出另一條光線,如此叠代,直到光線打到光源上(或逃逸出場景),然後用蒙特卡洛的方法,計算其貢獻,作為像素的顏色值。

4.6 雙向路徑追蹤 Bidirectional Path Tracing [1993,1994]

雙向路徑追蹤(Bidirectional Path Tracing)的基本思想是同時從視點、光源打出射線,經過若幹次反彈後,將視點子路徑( eye path) 和光源子路徑( light path) 上的頂點連接起來(連接時需要測試可見性),以快速產生很多路徑。這種方法能夠產生一些傳統路徑追蹤難以采樣到的光路,所以能夠很有效地降低噪聲。 進一步的, [Veach 1997]將渲染方程改寫成對路徑積分的形式,允許多種路徑采樣的方法來求解該積分。

4.7 梅特波利斯光照傳輸 Metropolis Light Transport [1997]

Eric Veach等人於1997年提出了梅特波利斯光照傳輸(Metropolis Light Transport,常被簡稱為MLT)方法。路徑追蹤( Path Tracing)中一個核心問題就是怎樣去盡可能多的采樣一些貢獻大的路徑,而該方法可以自適應的生成貢獻大的路徑,簡單來說它會避開貢獻小的路徑,而在貢獻大的路徑附近做更多局部的探索,通過特殊的變異方法,生成一些新的路徑,這些局部的路徑的貢獻往往也很高。 與雙向路徑追蹤相比, MLT 更加魯棒,能處理各種復雜的場景。比如說整個場景只通過門縫透進來的間接光照亮,此時傳統的路徑追蹤方法因為難以采樣到透過門縫的這樣的特殊路徑而產生非常大的噪聲。

五、光線追蹤 Ray Tracing

光線追蹤(Ray tracing)是三維計算機圖形學中的特殊渲染算法,跟蹤從眼睛發出的光線而不是光源發出的光線,通過這樣一項技術生成編排好的場景的數學模型顯現出來。這樣得到的結果類似於光線投射與掃描線渲染方法的結果,但是這種方法有更好的光學效果,例如對於反射與折射有更準確的模擬效果,並且效率非常高,所以當追求高質量的效果時經常使用這種方法。

上文已經提到過,Whitted於1979年提出了使用光線跟蹤來在計算機上生成圖像的方法,這一方法後來也被稱為經典光線跟蹤方法、遞歸式光線追蹤方法,或 Whitted-style 光線跟蹤方法。其主要思想是從視點向成像平面上的像素發射光線,找到與該光線相交的最近物體的交點,如果該點處的表面是散射面,則計算光源直接照射該點產生的顏色;如果該點處表面是鏡面或折射面,則繼續向反射或折射方向跟蹤另一條光線,如此遞歸下去,直到光線逃逸出場景或達到設定的最大遞歸深度。

以下這張圖示可以很好的說明光線追蹤方法的思路:

技術分享

圖6 Ray Tracing Illustration First Bounce

技術分享

圖7 光線追蹤渲染出的效果圖1

技術分享

圖8 光線追蹤渲染出的效果圖2

技術分享

圖9 光線追蹤渲染效果圖 @Caustic-Graphics,Inc

技術分享

圖10 典型的光線追蹤渲染效果圖

光線跟蹤的一個最大的缺點就是性能,需要的計算量非常巨大,以至於目前的硬件很難滿足實時光線追蹤的需求。傳統的光柵圖形學中的算法,利用了數據的一致性從而在像素之間共享計算,但是光線跟蹤通常是將每條光線當作獨立的光線,每次都要重新計算。但是,這種獨立的做法也有一些其它的優點,例如可以使用更多的光線以抗混疊現象,並且在需要的時候可以提高圖像質量。盡管它正確地處理了相互反射的現象以及折射等光學效果,但是傳統的光線跟蹤並不一定是真實效果圖像,只有在非常近似或者完全實現渲染方程的時候才能實現真正的真實效果圖像。由於渲染方程描述了每個光束的物理效果,所以實現渲染方程可以得到真正的真實效果,但是,考慮到所需要的計算資源,這通常是無法實現的。於是,所有可以實現的渲染模型都必須是渲染方程的近似,而光線跟蹤就不一定是最為可行的方法。包括光子映射在內的一些方法,都是依據光線跟蹤實現一部分算法,但是可以得到更好的效果。

用一套光線追蹤的偽代碼,結束這一節的介紹:

[cpp] view plain copy
  1. for each pixel of the screen
  2. {
  3. Final color = 0;
  4. Ray = { starting point, direction };
  5. Repeat
  6. {
  7. for each object in the scene
  8. {
  9. determine closest ray object/intersection;
  10. }
  11. if intersection exists
  12. {
  13. for each light inthe scene
  14. {
  15. if the light is not in shadow of anotherobject
  16. {
  17. addthis light contribution to computed color;
  18. }
  19. }
  20. }
  21. Final color = Final color + computed color * previous reflectionfactor;
  22. reflection factor = reflection factor * surface reflectionproperty;
  23. increment depth;
  24. } until reflection factor is 0 or maximumdepth is reached
  25. }

六、路徑追蹤 Rath Tracing

路徑追蹤(Rath Tracing)方法由Kajiya在1986年提出,是第一個無偏(Unbiased)的渲染方法。

路徑追蹤方法的基本思想是從視點發出一條光線,光線與物體表面相交時根據表面的材質屬性繼續采樣一個方向,發出另一條光線,如此叠代,直到光線打到光源上(或逃逸出場景),然後用蒙特卡洛方法,計算光線的貢獻,作為像素的顏色值。而使用蒙特卡洛方法對積分的求解是無偏的,只要時間足夠長,最終圖像能收斂到一個正確的結果。

簡單來說,路徑追蹤 = 光線追蹤+ 蒙特卡洛方法。

這裏有一個用99行代碼實現路徑追蹤算法的一個簡易全局光照渲染器,有興趣的朋友可以進行了解:

http://www.kevinbeason.com/smallpt/

技術分享

圖11 基於路徑追蹤渲染的效果圖

技術分享

圖12 基於路徑追蹤實現的次表面散射渲染效果圖 ©Photorealizer

技術分享

圖13 基於路徑追蹤渲染的效果圖 ©http://www.pathtracing.com

技術分享

圖14 基於路徑追蹤渲染的效果圖 ©NVIDIA

七、Ray Casting , Ray Tracing,PathTracing區別

初學者往往會弄不明白光線投射(Ray Casting ),光線追蹤(Ray Tracing),路徑追蹤(Path Tracing)三者的的區別,龔大@龔敏敏 在https://www.zhihu.com/question/29863225這個答案中的回答已經很精辟,本文就直接引用了過來:

  • Ray Tracing:這其實是個框架,而不是個方法。符合這個框架的都叫raytracing。這個框架就是從視點發射ray,與物體相交就根據規則反射、折射或吸收。遇到光源或者走太遠就停住。一般來說運算量不小。
  • Ray Casting:其實這個和volumetric可以脫鉤。它就是ray tracing的第一步,發射光線,與物體相交。這個可以做的很快,在Doom 1裏用它來做遮擋。
  • Path Tracing:是ray tracing + 蒙特卡洛法。在相交後會選一個隨機方向繼續跟蹤,並根據BRDF計算顏色。運算量也不小。還有一些小分類,比如Bidirectional path tracing。

文末,簡單聊一下環境光遮蔽,AO。

八、環境光遮蔽 Ambient Occlusion

環境光遮蔽(Ambient Occlusion,簡稱AO)是全局光照明的一種近似替代品,可以產生重要的視覺明暗效果,通過描繪物體之間由於遮擋而產生的陰影, 能夠更好地捕捉到場景中的細節,可以解決漏光,陰影漂浮等問題,改善場景中角落、鋸齒、裂縫等細小物體陰影不清

晰等問題,增強場景的深度和立體感。

可以說,AO 特效在直觀上給玩家的主要感覺體現在畫面的明暗程度上,未開啟 AO 特效的畫面光照稍亮一些;而開啟環境光遮蔽特效之後, 局部的細節畫面尤其是暗部陰影會更加明顯一些。

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實現。

接下來貼一些和AO相關的圖,結束這篇文章。

技術分享

圖15 Scene without Ambient Occlusion ©NVIDIA

技術分享

圖16 Ambient Occlusion Only

技術分享

圖17 Scene with Ambient Occlusion

技術分享

圖18 使用環境光遮蔽制作人物的步驟

技術分享

圖19 一張典型的環境光遮蔽的渲染圖

技術分享

圖20 有無環境光遮蔽渲染效果對比圖示

九、其他參考

[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技術進化編年史