天天看點

Unity 5 中的全局光照技術詳解(建議收藏)

原文位址:http://www.cocoachina.com/game/20150701/12339.html

全局光照,簡稱GI,是一個用來模拟光的互動和反彈等複雜行為的算法,要精确的仿真全局光照非常有挑戰性,付出的代價也高,正因為如此,現代遊戲會先一定程度的預先處理這些計算,而非遊戲執行時實時運算。

Unity 5 中的全局光照技術詳解(建議收藏)

同一場景裡:沒有照明(左),隻有直接光源(中),和有間接光源的全局光照(右)的表現,注意顔色如何在不同的表面進行光的”反彈”,産生更真實的結果。

在本文中,我們會描述全局光照如何在Unity裡運作,帶領你通過不同的照明技術解釋如何在項目裡設定照明,并思考如何透過各種工具幫場景打光。

選擇一個照明專案

廣義的來說,Unity的全局光照是”實時”或是”預先計算好”的,在某些情況下兩種方法可以結合使用,照出更逼真的場景。本節我們會針對兩種技術的差異優勢和使用時機做個簡單的描述。

實時照明(REALTIME LIGHTING)

預設情況下,Unity的燈源(直接光源, 投射燈, 點光源)都是實時的,代表這些燈源會把光線照射到場景并以每一幀的頻率更新,由于光源是可以在場景内移動的對象,場景燈光的更新是實時的,你可以在遊戲視窗和場景視窗看到改變。

Unity 5 中的全局光照技術詳解(建議收藏)

實時照明的影響:注意到因為沒有反射光源的關系陰影是全黑的,隻有投射光錐體範圍内的對象表面才有光源影響。

實時照明是場景裡照亮物體最基本的方法,用來照亮角色和會動的對象,可惜的是,Unity實時照明裡的光線不會反射,是以我們才導入了全局光照系統,啟用了預先計算的技術,都是為了表現一個更逼真的場景。

烘焙全局光照(BAKEDGI LIGHTING)

當烘焙一張光照貼圖(Lightmap)時,場景内的靜态對象會基于光的影響算出一張貼圖成果,并疊在場景對象之上建立照明效果:

Unity 5 中的全局光照技術詳解(建議收藏)

左:一個簡單的光照貼圖場景成果,右:由Unity産生的一張光照貼圖(陰影和光源資訊都被納入計算)

這些”光照貼圖”可以包含場景内投射到物體表面的直接光源,以及在不同物體間反射的”間接光源”,這樣的光照貼圖可以透過物體材質上的着色器(Shader)描述像是顔色的表面資訊(Albedo)和凹凸(Normals)資訊。

烘焙光照所産生出來的貼圖,是無法在遊戲運作的時候變更運算的,是以被定義為靜态(Static),雖然仍可在這層貼圖上繼續疊加光源計算,但兩者已無法互動運算,通常我們采用這光照法來讓低階的手機能順利執行,解決光在遊戲中運作的效能問題。

預計算全局光照(PRECOMPUTED REALTIME GI LIGHTING)

雖然傳統的靜态光照貼圖無法在遊戲執行時改變場景光照條件,但預先計算的實時全局光照系統能幫我們實時運算複雜的場景光源互動,透過這種方法,就能建立昏暗的環境帶有豐富的全局光照反射,并實時反映光源的改變。好比做個日晷,陰影的位置和顔色會随着光源移動改變,這在原本的烘焙光照系統是無法達成的。

Unity 5 中的全局光照技術詳解(建議收藏)

一個用GI呈現的日晷案例

為了在合理的幀率實作這些效果,我們需要在實時運算之前先将一堆壟長的數字資料做”預計算”,預計算負責計算遊戲過程中光的複雜行為,它可以在時間空檔時進行計算,我們稱作一個”脫機”運算。

如何運作?

最常見的需求是我們希望間接光源能夠列入場景光照貼圖的計算,幸好,原理上這些間接光源都是從直接光源慢慢轉變過來的顔色,隻有少部分特定情況有比較大幅度的顔色改變,這樣的Unity的全局光照預計算,利用間接光源漫反射(diffuse)特性對運算有利。通常好的陰影是透過即時光源所計算出來的,而非烘焙到光照貼圖,假定我們并不需要太複雜的細節取樣,可以大大降低全局光照所産生的資料大小。

透過預計算來簡化整個流程,有效的降低了原本要在遊戲中實時計算的全局光照運算數量,如果你要常在遊戲中改變光源顔色,旋轉光源或是調整光的強度,甚至對場景表面做變更,這點就很重要。Unity從表面上采樣底層貼圖,并從廣義定義顔色的值到一個大型的群組,或是”叢集”,這會産生一個低解析的仿真靜态幾何,以友善我們用來計算光照。

Unity 5 中的全局光照技術詳解(建議收藏)

左:場景顯示設定為”Albedo”時,可以清楚看到由Unity預計算所産生的紋理;右:如同遊戲的場景一樣,即時光照計算完結果後套用到場景。

基本上,當在計算全局光照時,我們會針對靜态場景周圍做”光迹追蹤”運算,這是非常耗效能的,是以無法苛求要實時運算,相反的,Unity把光迹追蹤用在計算這些表面的叢集關系 - 在預計算”光傳輸”的階段,然後把世界串成一個網絡結構,我們在關鍵性的遊戲過程就不再需要耗費效能的光迹追蹤法。

我們有效的創造出一個簡化的算法可以在遊戲過程中變化輸入結構,這代表我們可以改變光源或是表面顔色,并很快的看到場景内全局光照的影響,算出的結果産出光照貼圖透過GPU着色,并和其他照明或是表面混合,最後輸出到螢幕上。

收益和成本(BENEFITS AND COSTS)

雖然可以同時使用烘焙方式的GI和預計算的GI,但要注意是同時仿真兩個系統,效能負擔也會兩次運算的總和,不隻是因為要儲存兩套光照貼圖在顯示卡記憶體,同時着色器也得付出兩次的處理成本。

最終要選擇哪個方法還是要取決于你項目的性質和預期的硬體考慮,例如在手機平台上,效能和記憶體限制較高,烘焙的GI法就會比較适合,如果是在有顯示卡的計算機上或是遊戲機上執行,那可能使用預計算實時全局光照,或兩個同時使用就比較可行。決定采用哪一種方法可以針對你的目标平台評估,記得如果項目要同時符合幾個不同的硬體需求,往往都是以效能最高的平台為考慮。

預先計算的過程(THE PRECOMPUTE PROCESS)

在Unity裡,預計算是在背景執行,不管是自動流程或是手動啟用,計算期間你都可以繼續編輯你的遊戲對象而不受影響,預計算的時候會在右下角出現一個進度條,不同的算法會有不同的運算階段,進度條上方也會顯示階段名稱與進度。

Unity 5 中的全局光照技術詳解(建議收藏)

從上面的例子可以看出,11個工作已經進展到第5個,”叢集”還有108件工作要執行完才會到第6個會話,數值狀态欄表如下:

Unity 5 中的全局光照技術詳解(建議收藏)

啟用一個預計算(STARTING A PRECOMPUTE)

隻有靜态對象會被納入GI預計算,要讓預計算啟動首先必須最少要有一個靜态對象,不管是單獨設定對象或是從層級選單用Shift + 選擇多個對象後一次修改。

從屬性面闆,将對象的Static勾選起來,這會将該物體所有跟靜态對象相關的旗标打開,包含導航旗标或是批處理旗标,這或許不是你想要的,針對預計算隻要把”Lighting Static”這個旗标打勾即可。更細部的控制,隻要點選屬性接口Static右邊的下拉式選單即可,此外,從Window裡的Lighting接口也能指定設定靜态對象。

如果你的場景設為自動(Lighting->Scene->Auto),Unity的預計算就會自動啟動,否則就需要用下列的流程手動執行。

自動/手動預計算(AUTO/MANUALPRECOMPUTE)

假如Lighting接口底下Auto這個選項是被勾選的(Lighting->Scene->Auto),那麼預計算就會自動在背景不停的改變場景産出的靜态幾何。但如果這個勾選沒勾,你将需要點選在Auto旁邊的”Build”按鈕手動啟動預計算,這會用同樣的方式進行預計算,讓你比較好控制計算的開始時間。手動啟動預計算會對場景所有的照明與各方面進行重新評估并重新計算,如果你希望有選擇性的計算,可以從”Build”旁邊的下拉選單來選擇。

使用烘焙GI或是預計算GI(ENABLINGBAKED GI OR PRECOMPUTED REALTIME GI)

預設情況下,兩種計算法在Unity裡都是啟用狀态(Lighting->Scene),因為如此,你可以針對單獨的光源設定要采用哪種計算法(Inspector->Light->Baking)

在一個場景同時采用兩種方法可能會對效能造成負擔,最好的做法在同一個時間隻用一種方法,要關閉任何一種方法可以從GI的接口(Lighting->Scene),把不要用的方法取消打勾即可,隻有有打勾的算法會計算,任何相關光的設定都會被覆寫。

預燈光設定(PRE-LIGHTSETTINGS)

Unity裡每盞燈光預設的烘焙模式都是”Realtime”,這代表這些燈光仍然會照亮你的場景,Unity的預計算GI系統會處理間接光。但如果預設的烘焙模式是”Baked”,那麼這些燈光将會透過Unity的烘焙GI系統處理直接光源和間接光源,産生出來的光照貼圖一旦貼到場景上在執行期間是不能改變的。

Unity 5 中的全局光照技術詳解(建議收藏)

一個設定烘焙模式為”Realtime”的點光源

選擇烘焙模式為”Mixed”的話,場景内的靜态對象會被烘焙GI拿去做計算,然而,不像”Baked”模式,混合模式的燈光仍會繼續運算即時光源到非靜态對象上,這對于你想把靜态環境烘成光照貼圖,但同時又希望同樣一盞燈能為會動的角色計算陰影很有幫助。

GI快取(GI CACHE)

無論是烘焙還是預計算系統,Unity會”緩存”場景的光照資料到”GI快取”,并會在計算時嘗試重複運用這些資料來節省時間,你對場景的改變會影響這個資料重複利用的多寡。

如果你要清除這個快取可以從(Preference->GICache->Clear Cache)來清除,清除後代表所有資料都必須重新運算,因次會花費一些時間,在某些情況下你也許需要降低檔案空間大小(例如要把項目轉到另外一台計算機)是有幫助的。

場景設定(SCENESETUP)

選擇着色路徑(CHOOSING A RENDERING PATH)

Unity支援許多著色技術或”路徑”,在啟動一個項目時,必須要訂出出一個路線,Unity預設是”Forward Rendering”。在”ForwardRendering”裡,每個對象著色是根據每個影響對象的光,透過”Pass”來著色,是以有可能一個對象被重複著色了好幾次,取決于有幾盞燈在作用範圍裡。

這種方法的優點是快速,也代表硬體需求低,此外,這種正向著色提供了廣泛的自定義”着色模型”,可以快速處理透明度,也支援像是多重采樣柔邊(MSAA)的硬體功能,等等有些在其他路徑上是無法實作的功能,對于圖形品質有很大的影響。

然而他的缺點是要為每盞燈光付出相對應的成本,也就是說,對象被越多盞燈光影響,花費的運算成本就越高,有些類型的遊戲必需要大量的光源,就會令人望之卻步,反觀如果你能管理好你的燈光數量,那這個路徑會是一個非常快速的解決方案。

“Deferred”路徑,是延遲了光的遮蔽與混合資訊直到第一次接收到的表面的位置 法線 以及材質資料著色到一個”幾何緩沖器”(G-buffer)作為一個螢幕空間的貼圖,最後合成這些結果,這種方法優點是照明的著色成本是和像素數量成正比,而非燈光數量,是以你不用再管控場景燈光數量,某些遊戲類型将會是一個關鍵優勢。

“Deferred”路徑呈現可預見的效能特點,但通常需要較強大的硬體,對于手機平台支援度也較低。

關于”Deferred”,”Forward”或是其他路徑的更多資訊,可以參閱這裡。

選擇一個色彩空間(CHOOSING A COLOR SPACE)

除了要選好著色路徑之外,一開始選擇一個”色彩空間(Color Space)”也是很重要的事情,色彩空間決定采用哪種算法來計算照明或材質加載時的顔色混合,這會對遊戲的畫面真實感有很大的影響,但大多數情況下,太超過的色彩空間設定可能會被目标平台的硬體強制限制。

推薦比較接近真實的色彩空間是Linear,你可以從PlayerSetting裡面找到”Color Space”來設定(Edit->ProjectSetting->Player)

設定Linear的優點是會讓場景内的提供給着色器的顔色也會因為光強度增加變亮,如果換成”Gamma”色彩空間,亮度馬上會轉為以白色做為參考,這将不利于圖像的品質。

采用Linear和Gamma顔色空間的圖像對照表,可以注意到切換成Gamma時顔色快速的換成以白色為光照強度為基準。

Unity 5 中的全局光照技術詳解(建議收藏)

Linear另一個好處是着色器能在沒有Gamma補償的情況下對貼圖進行取樣,這有助于確定顔色品質在經過著色管道還能保持一緻性,能提高色彩和計算的精度,最後螢幕的輸出結果更為真實。可惜的是Linear顔色空間有些手機平台甚至有些遊戲機不支援,應該說PC或是一些新手機硬體和次世代遊戲機才會支援Linear顔色空間,在這種情況下,就得用Gamma方法替代了。

确認你的目标平台是哪一種之後才選擇适合的顔色空間是很重要的,想要了解更多關于顔色空間的資訊,可以參閱這裡。

高動态範圍(HDR)

如同顔色空間,相機的”Dynamic range”動态範圍是需要指定的,從本質上來說,這是用來定義相機截取的最亮與最暗的顔色範圍,要啟用HDR可以從相機元件裡把HDR項目打勾即可,要注意的是,某些手機硬體是不支援HDR的,在著色路徑為ForwardRendering并啟用MSAA柔邊時也不支援HDR,HDR和Linear顔色空間一起搭配是最好的,在處理非常明亮的顔色的時候還能保有準确性。

在預設的情況下,Unity是使用低動态範圍(LDR),顔色會以每個頻道8位儲存三原色(紅 綠 藍),8位确切的意思是用8個0或1的數字組合成的值,一共會有256種組合,三個頻道256 x256 x 256可以組合出1600萬種色采來表達從黑色到白色不同層度的灰階。

在現實環境中,顔色遠遠超出1600萬個色階,顔色和亮度的排列甚至遠遠超越了我們人眼所能辨識的,同樣的,Unity能夠處理超出這些範圍的顔色并輸出高于LDR裝置支援的顔色,用來提供給像是計算機畫面的高品質結果,盡管現今輸出裝置仍有很多限制,這些多出來的數值仍然可有很多的應用。啟用HDR之後,會儲存更大精度的顔色資料(使用浮點運算表示),能處理更多更亮的顔色範圍。

HDR能讓我們在同一畫面下維持兩個巨大差異的亮度,例如場景的陰影區域和戶外的亮光,我們也可以在環境場景建立一個”光暈”或發光特效,透過這些特效或可視的光影效果能增加畫面的真實感,但也要小心處理這些效果以防止他們曝光過度。

色調映射(TONEMAPPING)

以攝影來比喻的話,如果我們使用不同的曝光度來拍攝我們的場景,我們可以先觀察到哪些顔色會因為曝光過度而遺失,淺色調在很亮的區域可能被白色給覆寫過去,暗色調可能會被黑色給覆寫,這像是計算機圖學的”色調映像”,當顔色在顯示裝置(比如計算機螢幕)表現範圍之外時,算法會将顔色修正為裝置合理的顔色并重制在螢幕上,當相機啟用HDR時,建議相機加入Tonemapping這隻程式(Assets->ImportPackage->Effects),這隻程式可以幫你轉換控制超出範圍的顔色成為合理的顔色。

更多關于色調映像的資料可以檢視這裡。

環境光(AmbientLighting)

場景中一個照亮整體環境非常重要的就是”環境光”,可以說是影響場景光源最全面的一個要素,環境光很多情況都很有用,也取決于你所選的風格,比如卡通風格的陰影不清楚或燈光是手繪風格,環境光也很适合用在當你不想單獨調整場景内的燈光但又想要增加整體場景亮度的時候。在沒有使用Unity 5全局光照的功能時,環境光不會算出準确的實體遮擋,但如果開啟了任何一種GI的情況下,從Skybox照下來的環境光就能被算出遮擋,結果會更加真實。

在同一個場景之下,左邊是沒有任何光源的場景,右邊則開啟了環境光,可以注意到調整環境光的強度天空盒的亮度并沒有改變。

透過将對象設定為靜态對象來啟用全局光照的場景,可以注意到光線在不同的表面有遮擋的效果。

Unity 5 中的全局光照技術詳解(建議收藏)
Unity 5 中的全局光照技術詳解(建議收藏)

使用環境光的好處是耗用效能很低,是以在手機平台上隻要燈光數量控制得宜也能得到很好的表現,你可以從Lighting視窗(Window->Lighting)找到EnvironmentLighting設定區域(Lighting->Scene),改變Ambient Source來改變環境光來源。

Ambient Source的預設值是”Skybox”,上圖的天空盒是Unity 5系統産生的一個預設天空盒,帶有一個藍色調的環境光,以及一些用該半球體上純色與漸變色的設定。要注意的是改變Lighting裡面的AmbientSource并不會讓Skybox的顔色改變,但會影響到場景内環境光照射。

反射源(REFLECTIONSOURCE)

預設的情況下,場景中的對象會使用Unity内建的标準着色器(StandardShader)來著色,标準着色器是一個基于實體的着色器(PBS),它會透過模仿真實世界的實體特性像是反射或能量傳遞等來模拟真實世界裡光在材質上的表現。

當使用标準着色器時,每一個材質都會具有一定程度的鏡面反射(specularity)和金屬反射(metalness)屬性,在沒有強大的硬體來處理即時光迹追蹤反射的情況下,我們得仰賴預先計算著色反射,我們使用了一個由六張描述天空的圖檔所組成的方體貼圖(Cubemap)或從Unity 5用來從定點搜集環境資訊的反射探頭(Reflection Probe)産生所需的貼圖,然後在和其他光和地表資訊混合運算來仿真如同我們真實世界看到的反射效果。

Unity 5 中的全局光照技術詳解(建議收藏)

在預設的情況下,調高Specular和Metalness會更清楚的反射天空盒,反射的來源可以從設定來調整。

場景内的對象在預設的情況下會反射天空盒的内容,但你可以從Lighting接口裡找到ReflectionSource屬性來改變來源,指定一個新的方體貼圖,或指定一個反射探頭來定義。

反射探頭(REFLECTIONPROBES)

天空盒的資訊不可能包含所有的場景對象,在許多情況下,對象從天空搜集反射資訊時可能會被遮蔽,像是室内對象或是在類似橋或是隧道等建築物裡的對象,為了要準确反射這些對象,我們必須用反射探頭針對這些對象取樣,這種探頭從他們的位置對周圍取樣并把結果寫到方體貼圖,可以讓周圍經過的物體得到環境的反射影像。你可以透過GameObject->Light->Reflection Probe來新增一個反射探頭,反射探頭的位置會決定方體貼圖取樣的内容,以及反射所看起來的樣子,一般來說,基于效能考慮反射探頭越少越好,請記住,反射探頭并非用來讓實體得到精确結果,而是讓遊戲世界有更好的反射,大多數情況下幾個安排妥當的反射探頭就很足夠了。

Unity 5 中的全局光照技術詳解(建議收藏)

左圖:場景隻有預設的反射設定   右圖:場景加入了反射探頭後的結果

在反射探頭的屬性面闆我們可以設定Type為實時(Realtime),烘焙(Baked)或自定義(Custom),需要明白的是,實時反射的設定對效能極為不利,每多一個實時反射探頭就會多出額外六次的著色運算,是以擺設實時的反射探頭應該要有明确的需求,例如反射會閃動的霓虹燈,否則一般來說建議設成烘焙的就夠了,效能也會好很多。

需要注意的是,隻有标記為”ReflectionProbe Static”的對象才會被反射探頭取樣,從屬性接口上靜态對象(Static)的下拉選單打勾即可,相反的,實時的反射探頭會對所有可見的物體取樣,除非你在屏蔽(Mask)選單指定剔除它。

照亮一個場景(LIGHTINGA SCENE)

我們已經介紹了一些在Unity裡針對場景照明開始工作之前所需要考慮的條件,希望你對目标平台該用哪些設定已經有了一個方向(手機平台采用烘焙GI和Gamma顔色空間,PC或遊戲機采用實時GI和Linear顔色空間),接下來讓我們來看看有哪些協助制定光源的工具。

定向光源(DIRECTIONALLIGHTS)

“定向光”非常适合用來模拟陽光,它的特性就像是個太陽,定向光能從無限遠的距離投射光源到場景,從定向光發出來的光線是互相平行的,也不會像其他種光源會分岔,結果就是不管對象離定向光源多遠,投射出來的陰影看起來都一樣,這其實對戶外場景的照明很有利。

Unity 5 中的全局光照技術詳解(建議收藏)

定向光沒有真正的光源坐标,放置在場景任何地點都不會影響光的效果,隻有旋轉會影響定向光的照射結果。其他有光源坐标的燈光類型,例如投射燈(Spotlights),角色陰影會因為接近或遠離光源而改變,這也許在照亮室内環境時會是個問題,一般來說,避免角色太接近隐形的光源,我們會建立一個亮點來假裝光源。

使用定向光不用考慮距離,不管多遠它都會影響場景所有的表面(除非被剔除),當使用延遲(Deferred)著色路徑時會造成一些效能損耗,要注意的是,使用這個著色路徑時,光的效能代價和他影響的像素數目是成正比的,但雖然需要消耗效能,起碼結果較為統一,是以比較容易調整平衡。

在預設情況下,新的場景都會附帶一盞定向光,在Unity 5裡還會與天空盒系統關聯(Lighting->Scene->Skybox),你也可以删除預設的定向光并建立一個新的光源,然後從Sun這個屬性重新指定(Lighting->Scene->Sun)

旋轉預設的定向光會導緻天空盒也跟着更新,如果光的角度和地面平行就可以做出日落的效果,把光源轉到天空導緻變黑就能做出夜晚的效果,從上往下照就會模拟日間的效果。如果天空盒有指定為環境光源(Ambient Source),那麼天空盒的顔色就會影響環境裡面的對象。

點光源(POINT LIGHTS)

點光源可以想象是在3D空間裡一個對着所有方向發射光線的點,很适合用來制作像是燈泡, 武器發光或是從物體發射出來的爆炸效果,點光源的亮度從中心最強一直到範圍屬性(Range)設定的距離遞減到0為止,光的強度從光源到距離成反比,這是所謂的”平方反比定律”,類似光在現實世界的行為。

Unity 5 中的全局光照技術詳解(建議收藏)

點光源從它的位置對四面八方射出光線,球形的小圖示代表光的”範圍”,光線到達此範圍是會”衰減”到0,但如果有間接光源或反射光則會繼續投射。

點光源開啟陰影運算是很耗效能的,是以必須謹慎使用,點光源的陰影為了要給六個不同的世界方向會運算六次,在比較差的硬體開啟此功能會造成較大的效能負擔。

當在場景中加入點光源時要注意,目前它們不支援陰影的間接反射,這代表由點光源産生的光線,隻要在距離内有可能會穿過對象反射到另外一面,這可能會導緻牆壁或地闆”漏光”,是以放置點光源要格外注意,然而如果是采用Backed GI的話,就不會有這類的問題産生。

聚光燈(SPOTLIGHTS)

聚光燈投射一個錐體在他的Z軸前方,這個錐體的寬度由投射角度(Spot Angle)屬性控制着,光線會從源頭到設定的範圍慢慢衰減到0,同時越靠近錐體邊緣也會衰減,把投射角度的值加大會讓錐體寬度加大,同時也讓邊緣淡化的力度變大,這現象學名叫做”半影”。

Unity 5 中的全局光照技術詳解(建議收藏)
Unity 5 中的全局光照技術詳解(建議收藏)

聚光燈有許多用途,他們可以用來模拟路燈, 壁燈,或許多創意用法,例如模拟手電筒,因為投射區域能精确的控制,是以很适合用來模拟打在角色身上的光或是模拟舞台燈光效果等等。光線會因為離源頭越遠而遞減,可以注意到光也會因為越靠近錐體邊緣而變弱,我們稱之為半影區,這會因為錐體角度變大而更明顯。和點光源一樣,使用預計算GI時,聚光燈不支援間接光陰影,這表示燈光會穿過幾何影響到另外一面,是以放置投射燈要特别注意。

區域光(AREA LIGHTS)

區域光可以當作是攝影用的柔光燈,在Unity裡面他們被定義為單面往Z軸發射光線的矩形,目前隻能和烘焙GI一起使用,區域光會均勻的照亮作用區域,雖然區域光沒有範圍屬性可以調整,但是光的強度也是會随着距離光源越遠而遞減。

Unity 5 中的全局光照技術詳解(建議收藏)

區域光照亮表面并在區間産生漫反射與柔和的陰影

區域光用在建立柔和的照明效果非常有用,光線在任何方向穿過光的表面時會産生不同方向的折射 - 造成在對象上産生漫反射,常見的用途是拿來當作天花闆壁燈或是背光燈,為了實作這功能,我們必須從每個光照貼圖像素上發射一定數量的光線,背對着區域光以确定光有能見度,這代表區域光的計算是消耗很大的,而且會延長烘焙的時間,但如果運用得宜可以增加場景光的深度,那麼消耗就很值得,值得注意的是區域光隻能用在烘焙,是以不影響遊戲效能。

發光材質(EMISSIVE MATERIALS)

雖然區域光不支援實時GI,Unity提供另外一個柔和的燈光效果叫做發光材質(Emissive Materials),和區域光一樣,發光材質可以讓物體表面發光,他們可以反射場景内像是顔色或是光強度等等能在遊戲内改變的光源,自發光(Emission)是一個在标準着色器(Standard Shader)内的屬性,允許靜态對象成為一個發光體,預設情況下是0,代表指定了這個材質并不會有任何的自發光反應,HDR顔色選擇器能指定發光顔色,強度能在0-1的範圍調整,來建立類似區域光的效果。

發光材質并沒有範圍屬性,但從材質發出的光會以二的次方速度遞減,自發光材質隻會作用在有标記為”Static”或”LightmapStatic”卷标的對象,同樣的,如果發光材質附加在非靜态對象或像是角色的動态對象則不會有任何作用。

然而,材質設定隻要emission數值大于0,即使他們不接收場景光源在畫面上也會有發光的效果,這種效果也可以透過将emission屬性底下的”Global Illumination”改為”None”,像這樣的自發光材質很适合來模拟霓虹燈等類似的光源。

Unity 5 中的全局光照技術詳解(建議收藏)

使用Unity标準着色器并附加自發光材質的一個範例,注意從Unity Logo的自發光也會計算陰影,在這個案例讓球體有了陰影。

發光材質隻會影響場景内的靜态對象,如果你想要影響像是角色的動态對象,就必須采用光探頭系統(Light Probes),在遊戲周期改變發光材質的值會更新光探頭取樣,并直接在結果上看到變化。

光探頭(LIGHT PROBES)

靜态對象隻被Unity全局光照GI系統計算,為了使動态對象能夠和靜态場景接收到的光影資訊互動,我們需要紀錄這些光的資訊并做成可以在執行期間快速存取的格式。我們在場景放置許多取樣點來截取各個方向搜集來的資訊,顔色資訊會被編成能在遊戲中快速被取出的一組數值(或系數),這些取樣點我們稱為”光探頭”。

Unity 5 中的全局光照技術詳解(建議收藏)

使用了光探頭的場景,注意圖中光探頭放置位置在光線容易變化的地方,例如陰影或是顔色轉換的地方。

光探頭允許移動對象接受由全局光照GI所計算出來複雜的反射光源,對象在著色網格的時候會判斷附近光探頭的位置并且把光的資訊一并融合計算,這是透過找尋由光探頭所産生的一個四面體,然後決定哪個四面體的落入對象的軸向,這樣就能讓場景内的動态對象正确地接受光資訊,如果沒有放置光探頭,動态對象就無法接受全局光照的資訊,造成動态對象比場景還要暗。

預設的情況下,場景是沒有任何光探頭的,你必須從GameObjects->Light->LightProbe Group自行建立光探頭群組。假如全局光照裡的Auto是打勾的(Lighting->Scene->Auto),當光源或是靜态對象更新時,光探頭資訊也會實時更新,沒打勾的話必須點Build運算才會更新