2015年6月28日 星期日

Unity 5光源運作淺談

翻譯:Kelvin Lo

近代的遊戲大量的採用”全域光照”技術
全域光照(Global illumination,簡稱GI),是一個用來模擬光的互動和反彈等複雜行為的演算法,要精確的模擬全域光照非常有挑戰性,付出的代價也高,正因為如此,現代遊戲會先一定程度預先處理這些計算,而非遊戲執行時即時運算

同一場景裡:沒有照明(左),只有直接光源(中),和有間接光源的全域光照(右)的表現,可以注意到顏色如何在不同的表面進行光的”反彈”,產生更真實的結果

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

選擇一個照明技術
廣義的來說,Unity的全域光照是”即時”或是”預先計算好”的,在某些情況下兩種方法可以結合使用,照出更逼真的場景

本節我們會針對兩種技術的差異優勢和使用時機做個簡單的描述

即時照明(REALTIME LIGHTING)
預設情況下,Unity的燈源(直接光源, 投射燈, 點光源)都是即時的,代表這些燈源會把光線照射到場景並以每一幀的頻率更新,由於光源是可以在場景內移動的物件,場景燈光的更新是即時的,你可以在遊戲視窗和場景視窗看到改變


即時照明的影響:注意到因為沒有反射光源的關係陰影是全黑的,只有投射光錐體範圍內的物件表面才有光源影響

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

烘焙全域光照(BAKED GI LIGHTING)
當烘焙一張光照貼圖(Lightmap)時,場景內的靜態物件會基於光的影響算出一張貼圖成果,並疊在場景物件之上建立照明效果

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

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

烘焙光照所產生出來的貼圖,是無法在遊戲運作的時候變更運算的,因此被定義為靜態(Static),雖然仍可在這層貼圖上繼續疊加光源計算,但兩者已無法交互運算

通常我們採用這光照法來讓低階的手機能順利執行,解決光在遊戲中運行的效能問題

預計算全域光照(PRECOMPUTED REALTIME GI LIGHTING)
雖然傳統的靜態光照貼圖無法在遊戲執行時改變場景光照條件,但預先計算的即時全域光照系統能幫我們即時運算複雜的場景光源互動

透過這種方法,就能建立昏暗的環境帶有豐富的全域光照反射,並即時反映光源的改變,好比做個日晷,陰影的位置和顏色會隨著光源移動改變,這在原本的烘焙光照系統是無法達成的 

一個用GI呈現的日晷案例
為了在合理的幀率實現這些效果,我們需要在即時運算之前先將一堆壟長的數字資料做”預計算”,預計算負責計算遊戲過程中光的複雜行為,它可以在時間空檔時進行計算,我們稱作一個”離線”運算

如何運作?

最常見的需求是我們希望間接光源能夠列入場景光照貼圖的計算,幸好,原理上這些間接光源都是從直接光源慢慢轉變過來的顏色,只有少部分特定情況有比較大幅度的顏色改變,這樣的Unity的全域光照預計算,利用間接光源漫反射(diffuse)特性對運算有利

通常好的陰影是透過即時光源所計算出來的,而非烘焙到光照貼圖,假定我們並不需要太複雜的細節取樣,可以大大降低全域光照所產生的資料大小

透過預計算來簡化整個流程,有效的降低了原本要在遊戲中即時計算的全域光照運算數量,如果你要常在遊戲中改變光源顏色,旋轉光源或是調整光的強度,甚至對場景表面做變更,這點就很重要

Unity從表面上採樣底層貼圖,並從廣義定義顏色的值到一個大型的群組,或是”叢集”,這會產生一個低解析的模擬靜態幾何,以方便我們用來計算光照


左:場景預覽設定為”Albedo”時,可以清楚看到由Unity預計算所產生的叢集,右:如同遊戲的場景一樣,即時光照計算完結果後套用到場景

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

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

效益和成本(BENEFITS AND COSTS)
雖然能同時使用烘焙GI和預計算GI,但要注意是同時模擬兩個系統,效能負擔也會兩次運算的總和,不只是因為要儲存兩套光照貼圖在顯卡記憶體(VRAM),同時著色器也得付出兩次的處理成本

最終要選擇哪個方法還是要取決於你專案的性質和預期的硬體考量,例如在手機平台上,效能和記憶體限制較高,烘焙的GI法就會比較適合,如果是在有顯卡的電腦上或是遊戲機上執行,那可能使用預計算即時全域光照,或兩個同時使用就比較可行

決定採用哪一種方法可以針對你的目標平台評估,記得如果專案要同時符合幾個不同的硬體需求,往往都是以效能最高的平台為考量

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

進度條顯示Unity預計算的進度


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



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


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

從屬性面板,將物件的Static勾選起來,這會將該物體所有跟靜態物件相關的旗標打開,包含導航旗標或是批次處理旗標,這或許不是你想要的,針對預計算只要把”Lighting Static”這個旗標打勾即可

更細部的控制,只要點選屬性介面Static右邊的下拉式選單即可,此外,從Window裡的Lighting介面也能指定設定靜態物件

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

自動/手動 預計算(AUTO/MANUAL PRECOMPUTE)
假如Lighting介面底下Auto這個選項是被勾選的(Lighting->Scene->Auto),那麼預計算就會自動在背景不停的改變場景產出的靜態幾何

但如果這個勾選沒勾,你將需要點擊在Auto旁邊的”Build”按鈕手動啟動預計算,這會用同樣的方式進行預計算,讓你比較好控制計算的開始時間

手動啟動預計算會對場景所有的照明與各方面進行重新評估並重新計算,如果你希望有選擇性的計算,可以從”Build”旁邊的下拉選單來選擇

使用烘焙GI或是預計算GI(ENABLING BAKED GI OR PRECOMPUTED REALTIME GI)
預設情況下,兩種計算法在Unity裡都是啟用狀態(Lighting->Scene),因為如此,你可以針對單獨的光源設定要採用哪種計算法(Inspector->Light->Baking)

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

預燈光設定(PRE-LIGHT SETTINGS)
Unity裡每盞燈光預設的烘焙模式都是”Realtime”,這代表這些燈光仍然會照亮你的場景,Unity的預計算GI系統會處理間接光

但如果預設的烘焙模式是”Baked”,那麼這些燈光將會透過Unity的烘焙GI系統處理直接光源和間接光源,產生出來的光照貼圖一旦貼到場景上在執行期間是不能改變的


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

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

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

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

場景設定(SCENE SETUP)
選擇著色路徑(CHOOSING A RENDERING PATH)

Unity支援許多渲染技術或”路徑”,在啟動一個專案時,必須要訂出出一個路線,Unity預設是”Forward Rendering”

在”Forward Rendering”裡,每個物件渲染是根據每個影響物件的光,透過”Pass”來渲染,所以有可能一個物件被重複渲染了好幾次,取決於有幾盞燈在作用範圍裡

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

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

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

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

關於”Deferred”,”Forward”或是其他路徑的更多資訊,可以參閱這裏(英文連結)


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

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

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


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

Linear另一個好處是著色器能在沒有Gamma補償的情況下對貼圖進行取樣,這有助於確保顏色品質在經過渲染管道還能保持一致性,能提高色彩和計算的精度,最後螢幕的輸出結果更為真實

可惜的是Linear顏色空間有些手機平台甚至有些遊戲機不支援,應該說PC或是一些新手機硬體和次世代遊戲機才會支援Linear顏色空間,在這種情況下,就得用Gamma方法替代了

確認你的目標平台是哪一種之後才選擇適合的顏色空間是很重要的,想要了解更多關於顏色空間的資訊,可以參閱這裏(英文)


高動態範圍(HDR)
如同顏色空間,相機的”Dynamic range”動態範圍是需要指定的,從本質上來說,這是用來定義相機截取的最亮與最暗的顏色範圍,要啟用HDR可以從相機元件裡把HDR項目打勾即可,要注意的是,某些手機硬體是不支援HDR的,在渲染路徑為Forward Rendering並啟用MSAA柔邊時也不支援HDR

HDR和Linear顏色空間一起搭配是最好的,在處理非常明亮的顏色的時候還能保有準確性

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

在現實環境中,顏色遠遠超出1600萬個色階,顏色和亮度的排列甚至遠遠超越了我們人眼所能辨識的,同樣的,Unity能夠處理超出這些範圍的顏色並輸出高於LDR設備支援的顏色,用來提供給像是電腦畫面的高品質結果,儘管現今輸出裝置仍有很多限制,這些多出來的數值仍然可有很多的應用

啟用HDR之後,會儲存更大精度的顏色資料(使用浮點運算表示),能處理更多更亮的顏色範圍

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

色調映射(TONEMAPPING)
以攝影來比喻的話,如果我們使用不同的曝光度來拍攝我們的場景,我們可以先觀察到哪些顏色會因為曝光過度而遺失,淺色調在很亮的區域可能被白色給覆蓋過去,暗色調可能會被黑色給覆蓋,這像是電腦圖學的”色調映射”,當顏色在顯示設備(比如電腦螢幕)表現範圍之外時,演算法會將顏色修正為裝置合理的顏色並重現在螢幕上

當相機啟用HDR時,建議相機加入Tonemapping這隻程式(Assets->Import Package->Effects),這隻程式可以幫你轉換控制超出範圍的顏色成為合理的顏色

更多關於色調映射的資料可以查看這裡(英文)


環境光(Ambient Lighting)
場景中一個照亮整體環境非常重要的就是”環境光”,可以說是影響場景光源最全面的一個要素

環境光很多情況都很有用,也取決於你所選的風格,比如卡通風格的陰影不清楚或燈光是手繪風格,環境光也很適合用在當你不想單獨調整場景內的燈光但又想要增加整體場景亮度的時候

在沒有使用Unity 5全域光照的功能時,環境光不會算出準確的物理遮擋,但如果開啟了任何一種GI的情況下,從Skybox照下來的環境光就能被算出遮擋,結果會更加真實


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

透過將物件設定為靜態物件來啟用全域光照的場景,可以注意到光線在不同的表面有遮擋的效果

使用環境光的好處是耗用效能很低,因此在手機平台上只要燈光數量控制得宜也能得到很好的表現

你可以從Lighting視窗(Window->Lighting)找到Environment Lighting設定區域(Lighting->Scene),改變Ambient Source來改變環境光來源

Ambient Source的預設值是”Skybox”,上圖的天空盒是Unity 5系統產生的一個預設天空盒,帶有一個藍色調的環境光,以及一些用該半球體上純色與漸變色的設定

要注意的是 改變Lighting裡面的Ambient Source並不會讓Skybox的顏色改變,但會影響到場景內環境光照射

反射源(REFLECTION SOURCE)
預設的情況下,場景中的物件會使用Unity內建的標準著色器(Standard Shader)來渲染,標準著色器是一個基於物理的著色器(PBS),它會透過模仿真實世界的物理特性像是反射或能量傳遞等來模擬真實世界裡光在材質上的表現

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



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

場景內的物件在預設的情況下會反射天空盒的內容,但你可以從Lighting介面裡找到Reflection Source屬性來改變來源,指定一個新的方體貼圖,或指定一個反射探頭來定義

反射探頭(REFLECTION PROBES)
天空盒的資訊不可能包含所有的場景物件,在許多情況下,物件從天空蒐集反射資訊時可能會被遮蔽,像是室內物件或是在類似橋或是隧道等建築物裡的物件,為了要準確反射這些物件,我們必須用反射探頭針對這些物件取樣,這種探頭從他們的位置對周圍取樣並把結果寫到方體貼圖,可以讓周圍經過的物體得到環境的反射影像

你可以透過GameObject->Light->Reflection Probe來新增一個反射探頭

反射探頭的位置會決定方體貼圖取樣的內容,以及反射所看起來的樣子,一般來說,基於效能考量反射探頭越少越好,請記住,反射探頭並非用來讓物理得到精確結果,而是讓遊戲世界有更好的反射,大多數情況下幾個安排妥當的反射探頭就很足夠了


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

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

需要注意的是,只有標記為”Reflection Probe Static”的物件才會被反射探頭取樣,從屬性介面上靜態物件(Static)的下拉選單打勾即可,相反的,即時的反射探頭會對所有可見的物體取樣,除非你在遮罩(Mask)選單指定剔除它


照亮一個場景(LIGHTING A SCENE)
我們已經介紹了一些在Unity裡針對場景照明開始工作之前所需要考慮的條件,希望你對目標平台該用哪些設定已經有了一個方向(手機平台採用烘焙GI和Gamma顏色空間,PC或遊戲機採用即時GI和Linear顏色空間)

接下來讓我們來看看有哪些協助制定光源的工具


定向光源(DIRECTIONAL LIGHTS)
“定向光”非常適合用來模擬陽光,它的特性就像是個太陽,定向光能從無限遠的距離投射光源到場景

從定向光發出來的光線是互相平行的,也不會像其他種光源會分岔,結果就是不管物件離定向光源多遠,投射出來的陰影看起來都一樣,這其實對戶外場景的照明很有利



定向光沒有真正的光源座標,放置在場景任何地點都不會影響光的效果,只有旋轉會影響定向光的照射結果

其他有光源座標的燈光類型,例如投射燈(Spotlights),角色陰影會因為接近或遠離光源而改變,這也許在照亮室內環境時會是個問題,一般來說,避免角色太接近隱形的光源,我們會建立一個亮點來假裝光源

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

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

旋轉預設的定向光會導致天空盒也跟著更新,如果光的角度和地面平行就可以做出日落的效果,把光源轉到天空導致變黑就能做出夜晚的效果,從上往下照就會模擬日間的效果

如果天空盒有指定為環境光源(Ambient Source),那麼天空盒的顏色就會影響環境裡面的物件


點光源(POINT LIGHTS)
點光源可以想像是在3D空間裡一個對著所有方向發射光線的點,很適合用來製作像是燈泡, 武器發光或是從物體發射出來的爆炸效果

點光源的亮度從中心最強一直到範圍屬性(Range)設定的距離遞減到0為止,光的強度從光源到距離成反比,這是所謂的”平方反比定律”,類似光在現實世界的行為


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

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

當在場景中加入點光源時要注意,目前它們不支援陰影的間接反射,這代表由點光源產生的光線,只要在距離內有可能會穿過物件反射到另外一面,這可能會導致牆壁或地板”漏光”,因此放置點光源要格外注意,然而如果是採用Backed GI的話,就不會有這類的問題產生


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


聚光燈有許多用途,他們可以用來模擬路燈, 壁燈, 或許多創意用法,例如模擬手電筒,因為投射區域能精確的控制,因此很適合用來模擬打在角色身上的光或是模擬舞台燈光效果等等


光線會因為離源頭越遠而遞減,可以注意到光也會因為越靠近錐體邊緣而變弱,我們稱之為半影區,這會因為錐體角度變大而更明顯

和點光源一樣,使用預計算GI時,聚光燈不支援間接光陰影,這表示燈光會穿過幾何影響到另外一面,因此放置投射燈要特別注意


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


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

區域光用在建立柔和的照明效果非常有用,光線在任何方向穿過光的表面時會產生不同方向的折射 - 造成在物件上產生漫反射,常見的用途是拿來當作天花板壁燈或是背光燈

為了實現這功能,我們必須從每個光照貼圖像素上發射一定數量的光線,背對著區域光以確定光有能見度,這代表區域光的計算是消耗很大的,而且會延長烘焙的時間,但如果運用得宜可以增加場景光的深度,那麼消耗就很值得,值得注意的是區域光只能用在烘焙,因此不影響遊戲效能


發光材質(EMISSIVE MATERIALS)
雖然區域光不支援即時GI,Unity提供另外一個柔和的燈光效果叫做發光材質(Emissive Materials),和區域光一樣,發光材質可以讓物體表面發光,他們可以反射場景內像是顏色或是光強度等等能在遊戲內改變的光源

自發光(Emission)是一個在標準著色器(Standard Shader)內的屬性,允許靜態物件成為一個發光體,預設情況下是0,代表指定了這個材質並不會有任何的自發光反應,HDR顏色選擇器能指定發光顏色,強度能在0-1的範圍調整,來建立類似區域光的效果

發光材質並沒有範圍屬性,但從材質發出的光會以二的次方速度遞減,自發光材質只會作用在有標記為”Static”或”Lightmap Static”標籤的物件,同樣的,如果發光材質附加在非靜態物件或像是角色的動態物件則不會有任何作用

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


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

發光材質只會影響場景內的靜態物件,如果你想要影響像是角色的動態物件,就必須採用光探頭系統(Light Probes),在遊戲週期改變發光材質的值會更新光探頭取樣,並直接在結果上看到變化


光探頭(LIGHT PROBES)
靜態物件只被Unity全域光照GI系統計算,為了使動態物件能夠和靜態場景接收到的光影資訊互動,我們需要紀錄這些光的資訊並做成可以在執行期間快速存取的格式

我們在場景放置許多取樣點來截取各個方向蒐集來的資訊,顏色資訊會被編成能在遊戲中快速被取出的一組數值(或係數),這些取樣點我們稱為”光探頭”


使用了光探頭的場景,注意圖中光探頭放置位置在光線容易變化的地方,例如陰影或是顏色轉換的地方
光探頭允許移動物件接受由全域光照GI所計算出來複雜的反射光源,物件在渲染網格的時候會判斷附近光探頭的位置並且把光的資訊一併融合計算,這是透過找尋由光探頭所產生的一個四面體,然後決定哪個四面體的落入物件的軸向,這樣就能讓場景內的動態物件正確地接受光資訊,如果沒有放置光探頭,動態物件就無法接受全域光照的資訊,造成動態物件比場景還要暗

預設的情況下,場景是沒有任何光探頭的,你必須從GameObjects->Light->Light Probe Group自行建立光探頭群組

假如全域光照裡的Auto是打勾的(Lighting->Scene->Auto),當光源或是靜態物件更新時,光探頭資訊也會即時更新,沒打勾的話必須點Build運算才會更新
接下來...
本篇文章大致描述了Unity的光源運作基礎原理,但是還有許多細節沒有涵蓋到,後面還有兩篇文章會陸續推出,請密切注意

5 則留言:

  1. 我想請問一下,自發光和光探頭會很吃效能嗎?

    回覆刪除
    回覆
    1. 這兩種方法都是事先取樣不適合即時改變的類型,所以消耗效能都很低。

      刪除
  2. HI 如果我的角色自帶animation並將static勾上,程式runtime時會有揮手的動作,影子會改變,這時場景有一個Mixed的光,想請問一下,這個腳色會BAKE GI嗎,Precompute realtime light也會預先計算嗎。會有消耗效能的問題嗎?

    回覆刪除
    回覆
    1. 由於有設為靜態物件,GI是會計算的,但任何會動的物件static旗標被打勾有可能會觸發runtime時光照重新取樣,所以是有可能造成大量的效能消耗。建議會動的東西就不要設定是靜態物件

      刪除
  3. 請問,如果是要在效能較低的手機上運行,應該是全部bake完再用light probe計算,效能會比較好,還是全部即時運算呢?

    回覆刪除

著作人