Vray的全局照明(Global Illumination)算法原理与比较(图文) 引言 即使沒有經過實際統計 但毫無疑問地Vray是國內最多人使用的渲染器。 有些人會說那是因為Vray是最容易學、最簡單的渲染。其實根本不是,Vray是在MentalRay、FinalRender、Brazil、Maxwell…等眾多渲染器中最複雜的渲染器,原因很簡單,因為它除了一般常見的渲染引擎Qusi Monte-Carlo、Photon Mapping、Irrandiance cache (或稱Final gathering)外,Vray又多了Choas Group專利的Light Cache演算法。Vray渲染器明確地把光線反彈分為第一次反彈(Bounce)與第二次反彈,第一次反彈有4種渲染引擎可供選擇,第二次反彈有3中渲染引擎可供選擇,在不考慮原理之下,就有4x3=12中排列組合可供選擇。 雖然Vray預設有第一次渲染是用輻照映射(Irrandiance cache),第二次反彈是用準蒙特卡羅演算法(Qusi Monte-Carlo), 但當要調整渲染引擎時,若不是實際了解這些演算法背後的原理,真的要調整使還是會使人一頭霧水。怎樣針對你的場景特性去調配第一次反彈的引擎與第二次反彈的引擎種類? 這還真是不容易回答的問題。 這篇文章一開始的時候只是翻譯Vray的相關文件,但後來添加如Wikipedia的解釋名詞以及個人的理解,並順便將相關知識補齊,所以最後是翻譯的內容與原創文章混雜在一起。參考文獻放在文章最後。其實Vray用first bounce, second bounce這個用字是很容易誤導,不準確的用字。因為Bounce本身就暗示了演算法是基於光子映射(Photon Mapping)的光子在場景中反彈。一開始總會納悶為何Vray要把渲染搞的這麼麻煩,要提供這麼多選項?其實Vray只是把混合計算法這樣的概念明確寫出來罷了! 就好像是MentalRay可以把Photon mapping與Final Gathering這兩種計算法混合一起使用,Vray也可以在第一次反彈使用Photon mapping 第二次反彈使用irrandiance cache,就本質是上是與MentalRay完全相同。Finalrender則是比較賊的不明確告訴你它是由哪兩種計算法混合的 其實這三個渲染器都是採用混合演算法。為什麼要用混合演算法呢?因為各種算法有其缺點也有其優點。簡單的說,把算法混在一起使用可以截長補短。在後面的翻譯文章會詳細介紹。 |
一、渲染器的歷史:
幾乎所有現代全局照明渲染器都是基於Jim T. Kajiya 在1986年所發表的那篇---渲染方程式(The Rendering Equation)論文之上。這個方程告訴您光是如何在場景中傳播。在那篇論文當中,kajiya還提出了以圖像為基礎,利用蒙特卡羅方法的渲染方程式稱為路徑追蹤(path tracing)。其實,這個方程式已經廣為人知,並使用在計算輻射在環境中的傳播有一段時間了。然而,Kajiya是第一個將這套方程式應用到計算機圖形學當中的人。
這個渲染方程式只是一個“計算電磁學的麥斯威爾(James Clerk Maxwell )方程式的逼近版本"。它並不能模擬所有的光學現象。它只是基於幾何光學,因此無法模擬折射,干涉或兩極分化。不過,這個方程式很容易修改,使其能夠計算與波長有關的效應---例如散射。(譯者注: 這就是為什麼著名的渲染器要命名為Maxwell?)
更哲學一點來說,這個渲染方程式是是一個數學模型用來描述光的行為。雖然對計算機圖形學來說這是一個很好的模型,它並未說明究竟光如何在現實世界中當中運動。例如,渲染方程式假定光線是無窮的薄且認為光的速度是無限的---這兩個假設都不符合真實世界的光線。
因為渲染方程是基於幾何光學的,光跡追蹤(raytracing)是一個用來求解渲染方程非常方便的方法。事實上,大部分渲染器在計算渲染方程式的時候都是用光跡追蹤這個方法。 雖然渲染方程式可能會有不同寫法,但Kajiya提出的方程式看起來像這樣: 這個方程式的意思是:場景中, 光線由x點移動到另外一個點x1等於光線自x2移動到x1並且反射到x點的所有光線總合 |
除了一些簡單的狀況之下,要無限長的計算時間電腦才有可能把這個方程式解出來。不過,我們可以盡量得到接近的結果---在可接受的計算時間裡面。科學家找尋能在合理的時間內完成計算的全局光照演算法。
渲染方程式只有一個。不同的渲染器只是用不同的解法去計算結果而已。如果任何兩個渲染器的計算結果精確度夠的話,那麼就應該渲染出完全一樣的結果才對。理論上是這樣啦,但實際上渲染器往往會截斷或是修改原始渲染方程式,因此可能計算出不同的結果。
二、渲染引擎特性分類:
A. 完全計算法(Exact)與估計值計算法(approximate)
如上所述,我們計算不完每條算式---始終會存在著一些計算誤差,雖然這些物非常小。某些渲染法,可以由使用者自行決定計算的精度(例如 GI的密度,或GI的射線數目,或是光子的數目等。然而這種做法有一個缺點,那就是使用者必須等待整個計算過程完成後才能知道最終的渲染品質是如何。另一個缺點是,使用者必須要經過很多嘗試才能知道如何在最少的時間內達到要求的品質。不過,這種方法有個大優勢,就是可以有效率地控制精度範圍,因為這種演算法能夠專注於困難的計算區塊(將渲染範圍分割成區塊,成為獨立區域,最後在將結果組合起來。
其他方法,是用漸進式(progressively)的方式進行渲染,這種方法在剛開始計算時誤差很大,但在每次新的演算後會把誤差縮小。在任何時間點,我們能獲得完整的渲染結果。因此,我們可以在計算途中終止渲染器的計算。
表一、完全計算法與估計值計算法比較表 |
B. 收集法(Gathering)與發射法(shooting)
發射法:
自燈光開始發射光子到場景中。請注意,這種方法繼可以是完全計算法也可以是近似值計算法。
收集法:
由攝影機方向或是場景中的幾何體開始。請注意,收集法,既可以是完全計算法或是近似值計算法。
混合計算法:
將發射光子法與收集法兩個方法結合在一起使用;混合計算法可以是完全計算或是近似值計算。
表二、收集法與發射法比較表
C. 收集法:
收集方法和某些混合法可以是與視角有關(view-dependent)或是與視角無關(view-independent)的計算法。
表三、視角有關或是與視角無關的計算法比較表
三、Vray當中所支援的GI法
Vray提供您不同的GI計算方法---完全計算法,近似值計算法,光子發射法及收集法。不同場景適合不同方法。
完全(exact)計算法
Vray支持兩種完全計算法:蠻力GI及漸進路徑追蹤法。兩者之間的差異,就是蠻力GI法能與傳統的影像組合演算法(區塊渲染)相互使用,而且是自適應的,而漸進路徑追蹤法,必須一次就把整個影像計算完畢並沒有任何自適應的功能。
近似值(Approximate)計算方法
Vray所有其他的方法(輻照映射,光快取,光子映射)都是近似值方法。
發射(shooting)光子法
光子映射法是Vray當中唯一的發射光子法。焦散效果也可以由光子映射法被計算出來,且能夠與收集計算法搭配使用。
收集(gathering)計算法
Vray所有其他的方法(蠻力GI,輻照映射,光快取法)都屬於收集計算法。
混合法
你可以在V-Ray當中的第一次反彈與第二次反彈中使用不同的計算法,你可以使用完全計算法或近似值計算法,光子發射法及收集計算法,完全依據您的需求。可能的組合列在GI範例中。
V-Ray提供您不同的計算法計算間接照明。讓你在品質和速度之間做取捨:
A. 蠻力法(Brute force)
蠻力法---或是翻譯成暴力法,這是最簡單的解算法;這個方法是經由獨立計算物體表面每一個陰影點(shaded surface point)追蹤每個點上的半球面不同方向的射線所計算出來的間接照明。
蠻力法是一種程式設計的撰寫風格,這種程式並不帶有任何投機取巧的方法來改善計算效能,純粹只是依賴的電腦努力的運算,嘗試所有的可能性,直至最終答案被計算出來。典型的例子是旅行的推銷員難題 (the traveling salesman problem) 。假設推銷員需要到十個城市訪問。請問推銷員要怎樣的走法才能用最短的距離訪問所有的城市呢?蠻力法用的是最簡單的做法來求解---就是實際計算每一條可能的路徑,然後選擇其中最短的一個。這種方法不是很有效率,因為它並不是用有智慧的方法先過濾掉一些不可能的路徑。
雖然蠻力法用起來很愚笨,但它在軟體開發卻有它有用的地方。由於蠻力法最後可以保證得到正確的計算結果---儘管計算速度緩慢---但蠻力法可以用來測試其他快速演算法的精確度。
例如,在考慮八后(eight queens problem)問題時,要求把八個皇后放在一個標準西洋棋棋盤上,而且沒有皇后能夠攻擊其他皇后。蠻力法會研究所有的可能性---64! /56! = 178,462,987,637,760---也就是在64平方的位置上擺8個棋子,在每一個排列組合中,檢查是否沒有皇后能夠攻擊其他皇后。
蠻力法很容易設定,並會一定會找到解答,只要是這個問題是有解的。不過,問題越複雜往往會計算越久,在許多實際問題中,這種狀況往往隨著問題的複雜程度呈現倍數成長。因此,蠻力法通常應用於候選解答較少時,或是問題能有某些提示,可以用來減少候選的答案的數目。這種方法也可以用於速度比答案更重要的問題上。例如當問題的答案錯誤會導致產生非常嚴重的後果的時候。
蠻力法(Brute Forc)在大部分的情況就等於準蒙特卡羅演算法(Quasi Monte-Carlo)也等於直接計算(Direct Computing),雖然它們的本質還是有點不同。準蒙特卡羅演算法指的是一種取巧的隨機採樣的方式,主要是為了不計算所有算式(母群體),而只考慮較少的採樣本。蠻力法要跟像是Photon Mapping、 irrandiance cache這種算法相比較,後者多少有點取巧不計算所有的採樣點,後者是指計算部分採樣點其餘採插值計算。蠻力法則是乖乖地計算所有準蒙特卡羅產生的採樣點。換句話說是直接計算---Direct Computing。
準蒙特卡羅演算法(Quasi-Monte Carlo simulation)跟傳統蒙特卡羅演算法(Monte Carlo)類似,只是與傳統蒙特卡羅演算法不同的是,準蒙特卡羅演算法使用準隨機序列(quasi-random sequences),而不是用隨機序列(random numbers)。這些序列是用來產生與我們要解決的問題有關的機率分布的代表性的採樣。準隨機序列,也被稱為低差異序列(low-discrepancy sequences),在某些情況下可以改善傳統蒙特卡羅演算法計算時間過長的問題,準蒙特卡羅演算法能提供較短的計算時間/或更高的精度。
其實,低差異序列是完全確定性的,因此,準隨機會誤導人以為它是隨機的,其實並不是。低差異序列被用來取代均勻分佈的隨機序列。用“準”這個形容詞,其實是要強調這樣的序列既不是隨機也不是假隨機,但準隨機序列與隨機序列有某些共通性質,這種特性被應用在如準蒙特卡羅方法裡面,這樣的特性是準蒙特卡羅方法一個重要的優勢。
蒙特卡羅法,其實是一種通稱。蒙特卡羅法是一種隨機的技術---這種方法利用隨機率列和機率統計來解決複雜問題。蒙特卡羅法被應用到各行各業中,從經濟學到核子物理,到交通車流調節。當然,不同研究領域的應用方法會不一樣,單就化學研究來說就有數十種不同的蒙特卡羅演算法。
蒙特卡羅法源於美國在第一次世界大戰時研發原子彈的---曼哈頓計畫(Manhattan Project)。該計畫的主持人之一馮·諾伊曼(John von Neumann)用世界馳名的賭城---摩洛哥的蒙地卡羅(Monte Carlo)來替這種方法命名 為它蒙上了一層神秘色彩
使用蒙特卡羅法能讓我們研究相當複雜的物理模型難題,不用這種演算法我們幾呼無法解決的。要求解兩個原子之間的交互作用是相當簡單的;一樣的方程式要解決數百或數千個原子交互作用是不可能算的出來的。使用蒙特卡羅法,我們可以對大系統做隨機採樣,而這些採樣足以描述整個複雜系統的行為。
計算全局光照的蠻力法,由於這種方法會計算每以個採樣點的GI數值,每一個點的計算是獨立的。雖然非常耗時,但這種方法非常準確,特別場景中的小細節都能表現出來。 為了加快蠻力法的計算,您可以與其他方法混合使用(光子映射或光快取)作為第二次GI反彈的計算法,而使用蠻力法作為第一次反彈的計算法。
B. 輻照映射(Irradiance map)
輻照映射---或翻譯成發光貼圖,相當於MentalRay的Final Gathering最終收集。這個方法是基於輻照快取(irradiance caching);基本上就是指計算場景中特定的採樣點,而場景中其餘的點做插值計算。
輻照指的是在3D空間某一點的光線,這個光線是自這個點四面八方反彈過來的。一般來說,場景中不同的點都有不同的輻照。不過,有兩個有用的限制條件,。第一種是表面輻照-這指的是位於物體表面的輻照。這是一個很自然的限制條件,因為我們通常對物體表面的照明有興趣。第二個限制是漫射表面的輻照值---等於光線到達這個點的光總量,不論這些光線是從哪裡來的。簡單來說,其實物體表面的顏色其實就是他的表面輻照數值,如果這個材質是純白且完全的漫射
V-Ray的輻照映射能夠有效地計算場景物體的表面輻照。因為場景中不是所有物體都有相同的間接照明細節,理所當然在有許多細節地方應該要有更精確的計算(例如兩個靠近的物體,或是有銳利陰影的地方,而在沒有細節的地方減低精確度(例如大型均勻的光照區域。因此輻照映射法是自適應的。這是經由多次pass才能實現的,每一次pass(每渲染所謂的及格率)解析度就增加一倍。這種做法就是一開始使用低解析度(例如1/4的最終影像解析度)然後慢慢增加到使用最高解析度。
其實輻照映射就是在3D空間(點雲)中點的集合,這些點包含了間接照明的資訊。在GI那個pass裡面,當一個物體光線擊中,V-Ray會判斷輻照映射裡面是否有其他類似的點具有類似的方向與位置。從那些已經計算點,V-Ray可以提取點裡面的各種資訊(例如: 是否有物體靠近這裡,或是間接照明改變的有很明顯嗎…等)。根據這些訊息,V-Ray可以決定,這個點的間接照明究竟是要其他已經建立好的輻照映射來做內插計算就好呢?還是不要做內插計算。如果不要,那就必須真的去計算這個點的間接照明並將資訊儲存在輻照映射當中。當進行實際渲染時,V-Ray採用非常複雜先進的插值方法得出場景中輻照映射的逼近值。
C. 光子映射(Photon map)
光子映射---或翻譯成光子貼圖(Photon Mapping),這種做法讓光子自光源開始發射出去,在場景中彈跳。這對計算是內或半開放的是內場景很有用。單獨使用光子映射計算法通常不會產生好的結果;但如果與蠻力法或輻照映射其中一方法搭配使用,光子映射可以粗略估計光線在場景中的位置。
光子映射有點類輻照映射。它也是用來成現場景照明的一種方式,它也是3D空間中點的集合(點雲)。但是,光子映射是以不同的方式建立的。它是藉由追蹤場景光源發散出的粒子(光子)。這些光子在場景中反彈,並撞向各種表面。光子擊中點會儲存在光子映射當中。
由光子映射重建出場景的照明是與輻照映射的重建方式有所不同。輻照地圖只需要把每個樣本點之間作簡單的混合與內插計算就可以。使用光子映射則必須要估計任一點的光子密度。光子密度估計是光子映射這項技術的重點。V-Ray可用使用多種方法進行光子密度估計,每個方法都有它優缺點。這些方法基本上就市找尋最接近採樣點的光子。
請注意,一般來說,光子映射算出來的光照效果比輻照映射算出來的較不精確,特別是在細節較多的場景時。輻照映射是自適應的,而光子映射不是。還有另一個重大的缺點就是光子映射對於場景的邊界常常出現計算錯誤。通常會出現在邊緣或角落,而算出來的會比它們原本應該的亮度來的深。輻照映射也有邊界計算錯誤的問題,只是因為其有自適應計算的性質,使得這個錯誤被大大地減低了大。光子映射的另一個缺點是它不能模擬天光照明。這是因為光子需要一個實際發射光子的表面。至少在V-Ray裡面,實際上天光並不只是場景中的一個表面物體而已。
然而,光子映射是不受視角所影響的且可以計算較快。因此把它作為場景照明的估計,然後與其他更精確的方法例如直接計算或是輻照映射搭配使用會更好。
表四、Vray的四種渲染引擎優缺點比較表 |
表五、各種全局照明演算法特性簡表
表六、推薦的GI配對方法 |
總結
Vray的irrandiance cache其實就等於MentalRay的Final Gathering。這兩個名詞不同但是本質相同 即使它們內插方式稍有不同。就全局照明的計算方式而言,Photon Mapping其實是最容易理解的;想像在一個純白的房間內,有一台自動網球發球機,每個網球上塗上了紅色的油漆。發球機發射網球在房間內反彈 把房間染的紅紅一點一點。用這樣比喻,越多的網球發射,房間的紅色球斑就越不明顯,越少就會有明顯的球斑。Photon Mapping的原理就是燈源發射光子到場景中彈跳,根據設定條件光子會停止彈跳停留光照資訊在場景表面。irrandiance cache (或Final Gathering)的概念就完全不同,自攝影機中決定場景細節多的地方放置收集點(Gathering Point)這些點自其半球方向收集四面八方的間接照明資訊 這種演算法的重點就是收集資訊 Final Gathering應該翻譯成最終收集,而不是最終聚集。Light Cache則是和Photon Mapping很像,只是Light Cache追蹤光線的方向不是自光源開始,而是源自攝影機視角。