2016年12月29日 星期四

Unity預計算即時GI - 8.微調光照參數

原文
翻譯:Kelvin Lo

版本:5.5 難度:中等

Unity提供許多進階的光照貼圖控制方法,這些設定被放在一個光照參數集(Lightmap Parameters)的資源裡,好讓設定能在不同的專案場景或是透過版本控制和團隊一起共用。
  • 要建立一個Lightmap Parameters資源,先找到Project視窗
  • 從Create下拉選單建立(Create > Lightmap Parameters)
  • 我們也可以在Project介面裡按右鍵選(Asset > Create > Lightmap Parameters) 來建立。
透過這個參數集可以針對烘焙光照或預計算GI做更高階的設定

建立完成的光照參數集可以被指定給靜態物件。

  • 從Hierarchy介面選擇你要指定變數集的物件,物件必須是帶有Mesh Renderer元件的靜態物件。
  • 開啟Lighting介面(Window > Lighting)並選擇Object頁籤
  • 從Advance Parameters下拉選單指定你的變數集給物件,右邊的"Edit"按鈕是開啟編輯光照變數的捷徑。

從Lighting介面裡的Advanced Parameters欄位指定光照參數集

同一個光照參數集可以指定個許多不同的物件,你只要從Hierarchy介面一次把要指定的物件全選起來,執行上面說明的步驟把檔案指定到Advanced Parameters欄位即可。


光照參數集:實例(per-instance)還是預製(per-Prefab)好?


和拆UV的部分很像,光照參數集可以指定給Prefab預製物件或給場景裡的獨立物件,一旦參數集被貼上物件就會覆蓋掉物件身上舊有的設定。

這個方法的好處是你可以把正常情況下會用到的光照設定貼在預製物件上,然後依照不同需求修改覆蓋場景裡實例物件身上的光照參數設定。

本教學裡,我們會從一個實例物件身上示範如何使用光照參數集,主要是因為我們想根據使用的物件來選擇不同的光照參數集。


預設參數集


這部分適合用來設定場景預設的光照參數,這個參數集待會會被指定給所有場景裡面帶有Mesh Renderer元件但卻還沒指定Lightmap Parameters的物件。場景裡建立的任何帶有Mesh Renderer的物件都會以此為基礎,這樣可以省下手動指定的時間。

  • 開啟Lighting介面(Window > Lighting)並選擇Scene頁籤
  • 從General GI區塊裡找到Default Parameter,選擇你剛才建立的光照參數集。

雖然新的物件會開始採用這個預設設定值,你仍然可以從Advanced Parameter參數單讀覆蓋它。

預設的設定會反映到所有新的靜態物件

Unity預設有幾組光照參數集可以選,分別是:

  • Default - HighResolution
  • Default - Medium
  • Default - LowResolution
  • Default - VeryLowResolution


這幾個不同的設定存有會影響到光照結果的設定像是光照貼圖解析度,光照圖大小以及其他一些進階選項設定,可以用來快速調整總體結果。


光照參數集說明


Unity預設的參數組合事實上已經很適合大多數的情況,但我們還可以建立自己的參數組並做更多的微調,來讓GI計算達到比預期更好的結果。

Unity手冊上關於光照參數集有個別的詳盡說明,但針對這個教學我們也會重點說明幾個最有用的設定。

Resolution
解析度的值確訂了物件採用的光照貼圖解析,這個值會和Lighting介面裡的解析度做加乘。比如說,如果場景解析度設為2,這裡的解析度設為0.5,那所有帶有這個參數集的物件都會採用1texel/unit來計算光照貼圖。

由於PRGI只會呈現場景裡的漫反射(diffuse)和間接照明,所以我們不需要用到像傳統烘焙貼圖那麼高(20-30)的採樣值,通常設定2-3已經很好了。如果是戶外場景,甚至可以縮小很多倍像是0.1就足以提供足夠的細節。

解析度值很大光照貼圖所產生的影子斑點可以把Irradiance Budget這個參數調高來獲得緩解。

注意,當解析度值很大時,在較低解析度下可能會產生奇怪的陰影,這些陰影在最終的光照貼圖裡可能看起來像是斑點或髒汙。如果有這種情況可以試著把Irradiance Budget參數提高來獲得改善。

Cluster Resolution

叢集解析度用來決定1個像素裡能有多少叢集數量。假如這個值設為1,代表光照圖裡面每個像素都都會有一個叢集,0.5代表一個像素會有2個叢集,換句話說叢集會是光照圖的兩倍大。

進一步來說,可以想像如果我們把場景的解析度設為1,並建立一個1x1x1的方塊,然後指定這個光照參數集給物件,那麼方塊的每一面都會有1個叢集。如果我們把解析度改為2,結果就會變成2(1x1),方塊的每一面叢集會變成4個。

上圖可以看到一個解析度設為1的1x1x1方塊,光照參數設定叢集解析度(Cluster Resolution)為1和光照貼圖解析度為2時,我們每一面都會有4個叢集。

在大多數的情況下,Cluster Resolution只需要設為低於貼圖像素(lightmap texels)大小即可,例如Default - HighResolution設定值為0.6。

一個場景中叢集太多的話會很快拉高預計算時間,還會影響到即時場景的光照效能,因此必須要把叢集的數量花在刀口上,永遠以保持品質儘可能的降低叢集數量為目標。

將光照貼圖解析和叢集解析度保持指定比例,這樣我們可以和場景整體的解析度建立一個相對關係。我們可以把Lighting介面裡面的解析度定義為高解析度作為整體設定,然後針對個別物件微調各自的光照參數集。

Unity採用這種分層法方便讓開發者能更全觀的控制場景光照,不然要針對每個物件手動都設定光照參數的值會很麻煩。

Irradiance Budget

我們之前說明過光照計算是如何用叢集來計算靜態物件的預計算光照,在預計算的過程裡,叢集之間的關係被建立起來,好讓光線得以在叢集網內快速傳遞。

在本質上,光照貼圖像素值的算法是基於叢集從該像素的位置對場景的一個檢視所計算得來,這會讓我們可以很快計算叢集之間的光照反射最後產生一個全域光照,這些叢集就能在畫面渲染完之前給予適當的樣本數。

Irradiance Budget(輻照度範圍)用來制訂當叢集採樣時每個光照貼圖像素所使用到的記憶體量,這會決定照明結果的精度,數值太低代表每個貼圖像素在記錄時使用較少記憶體同時提升CPU效能,代價就是會失真,數值越低光照結果會越模糊。反過來看,數值拉高GI會更準確,但記憶體和CPU的消耗都會提升。

如果我們的預計算在Runtime執行時更新有點慢或會lag,可能降低這個值會得到改善,這個設定比較適合用在不用精細的物件,很大、模糊或遙遠的物件。

Irradiance Quality

當計算PRGI時,每個光照貼圖像素會開始對場景投出射線,然後將可視資料報告給附近的叢集,然後貼圖像素就會得到每個叢集的百分比數值,這個值用來定義光照貼圖裡每個像素從叢集所分到的可視數據,而一欄設定就是用來設定每個像素能對場景投射多少射線。

如果場景裡的物件和周圍物件光照不合的情況下可以斟酌加大這個值,有時該暗的時候光照結果卻意想不到的亮,有可能是因為投射到場景的射線不足或遮擋到,導致漏算叢集資料。同樣該亮的的放如果射線沒有檢查到,可能會造成過暗。

提高射線的投射量就能解決類似的問題,代價就是增加預計算的時間,要優化這個時間,我們應該找出最適合的值來達到我們理想的照明效果。請注意,這個值不會影響到Runtime時的效能。

Backface Tolerance

當射線從光照貼圖像素投射出,從場景叢集蒐集光線有時會打到幾何的背面,當計算全域光照時我們只需要關心投射到物體表面的光照,從背面來的光照資源通常都會忽略掉,這些從背面來的光照資料會破壞光照結果,因此調整這個值能防止這類情況發生。

這裡的地板上的陰影就是Unity在計算期間從物件無效的背面所創造的,增加Backface Tolerance能改善這個問題。

Backface Tolerance必須指定從前方光源來的百分比,好讓正面的像素被判定為有效。假如一個貼圖像素沒通過測試,Unity會採用鄰近的像素值嘗試算得正確光照資料。

調整這個值並不會影響PRGI運算效能,也不會對預計算時間長度有太大影響。反而是蠻適合在調整Irradiance Budget都無法解決的場景貼圖太亮或太暗問題時,Backface tolerance會是一個不錯的除錯工具。

Modelling Tolerance

有時候在場景靜態物件中存在小間隙的區域會產生黑色的光暈或是不需要殘像,很容易發生在鄰近有相反幾何圖形的區域,像是地板上的物件:

像這樣物品的黑暗邊緣通常可以透過加大Modelling Tolerance來改善

通常在這樣的情況下,物體和物體之間存在著小小的縫隙,因為沒有太多光線可以進入,導致非常暗的光照圖產生。當光照解析度低的時候,這些黑暗像素的大小可能會導致它們跑出遮擋物的邊界並產生不協調的黑色塊。

Modelling Tolerance是用來忽略比Threshold值還小的細節,提高這個值可以確保Unity 在計算GI時忽略掉非常靠近其他物體表面的幾何面,這個值越高代表Light Transport這個階段需要額外計算忽略這些間隙,調低Modelling Tolerance也能確保小物件不會被遺漏計算。

Modelling Tolerance不會影響PRGI的優化,對於計算時間和執行效能也沒甚麼負面影響,它能用在一些除錯流程上,解決連Irradiance Budget都無法改善的殘影問題。


開始建立Lightmap Parameters光照參數資源


現在我們已經明白光照參數能做甚麼了,可以開始嘗試建立這些資源。


  • 打開LightingTutorialStart場景
  • 在Project視窗找到Assets > LightmapParameters目錄並點進去
  • 從Project視窗最上面的下拉選單建立一個光照參數集(Create > Lightmap Parameters
  • 把物件名稱改為"TutorialTerrainLow"


這個物件從鏡頭看起來非常大,蠻適合設一個光照參數集而不是用場景預設的

接下來我們要把剛剛新建的光照參數集指定給這個物件


  • 在場景視窗裡,選擇最接近主場景的兩座山,這些山都已經被命名為"MountainPeak"。注意,我們將忽略最遠的山。
  • 從Inspector介面確認兩個物件都是設定為靜態物件
  • 開啟Lighting視窗(Window > Lighting) 並選擇Scene頁籤
  • 確保最底下的Auto是打勾
  • 改選擇Object頁籤
  • 從Advanced Parameters下拉選單選擇剛建立的TutorialTerrainLow
  • 按一下右邊的Edit按鈕,準備開始調整設定


預設的光照參數集

首先我們要看的是Resolution,降低這個值可以加速預計算時間同時也提升執行效能,所以我們應該目標定在不影響畫質的前提下採用較低的解析度。

會很接近看的物件可以設比較高的值,但是兩座山距離鏡頭都非常遠,因此這個例子設低一點是比較好的。這些大物件表面材質相當一致,從鏡頭的角度來看,接收到光的顏色變化也不大,所以可以降低這個值而不會影響結果品質。

像是山或地形的大場景,採用預設值反而很浪費


使用較低的解析度犧牲品質但可以大大節省預計算和執行效能


  • 慢慢的降低TutorialTerrainLow光照參數集裡面的Resolution參數並觀察結果的變化。

請記得這裡的解析度和Lighting視窗裡的場景解析度是會相乘的,目前場景解析度是1,代表如果這裡的解析度小於1的話,輸出的光照貼圖每unit也會小於1像素(texel)

兩座山和其他的物件距離非常遠,它們不可能接受頻率很高的光照,因此如果我們採用較低的解析度損失的品質不會太多。教學裡我們發現用0.05就足以採樣該有的光照資料。

  • 從Project視窗點選TutorialTerrainLow物件
  • 從Inspector介面把Resolution設為0.05

然後來看看Cluster Resolution的值,之前討論過,這個值也是一個用來和光照貼圖像素數量相乘計算叢集的乘法器,當數值是1的時候叢集的數量就等於光照貼圖像素的數量,因此低於1會比較好。叢集本質上是為了計算PRGI所產生類似靜態場景的模擬體,所以只有在數量不足以反映物體的光照反射時才需要加大這個值。

和光照貼圖解析很像,這兩座山的叢集解析度可以設很低,如果把它設的跟其他小場景一樣的話,代表可能會需要幾百個小場景的叢集量來覆蓋這兩座山。



  • 對於很大的物件,叢集解析度可以設很低
  • 把Scene視窗左上方的繪製模式改為Clustering
  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Cluster Resolution的值慢慢降低,彩色色塊會慢慢變大,數量會慢慢變少


或是改用Lit Clustering繪製模式來評估設定的解析度是否足以採樣場景細節的光照。


  • 把Scene視窗左上方的繪製模式改為Lit Clustering
  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Cluster Resolution的值慢慢降低,觀察場景的變化。


調整到這裡時,可以問問自己是否能接受更低的叢集數值,如果繼續調高對畫質已經沒有好處了,那就應該要往下修正。請記住叢集數量對於預計算的時間和GI有很大的影響,這個案例我們發現用0.4是很適合的值。


  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 設定Cluster Resolution為0.4
Lit Clustering繪製模式可以用來評估場景裡是否有足夠的叢集

需多情況下只是單單降低光照和叢集的解析度就足夠提升很大的效能,但是我們還能用Irradiance Budget和Irradiance Quality做更進一步的改進.

首先我們先看看Irradiance Budget,如之前所提,這個值控制貼圖像素會占用多少記憶體計算,為了執行時的效能,我們應該使用最低的值以免產生負面的影響。

如果預計算的結果模糊不清的話可以試著調大這個值,對於場景裡有著高對比度卻沒有被精確表達出來的區域是很有用的。

Irradiance場景繪製模式可以用來評估調整Irradiance Budget或Quality的值

兩座山照明的頻率沒有很高,也沒有任何高對比的光照處理,代表在不影響品質的情況下,預設值128還能再低。


  • 把Scene視窗左上方的繪製模式改為Irradiance
  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Irradiance Budget的值慢慢降低
  • 你會看到當我們減少這裡的值時,兩座山上的照明會變得柔和一點

經過一些實驗之後,我們發現將Irradiance Budget設定為64最好


  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Irradiance Budget的值設為64
現在來看看另外一個Irradiance Quality,像之前所說的,Irradiance Quality影響著當計算光照像速時從叢集所投射出來的射線數量,不像Irradiance Budget只會影響到預計算時間,這個設定會影響到Runtime執行效能。

我們的兩座山是非常大的物件,代表不太容易錯過鄰近的叢集,因此我們可以透過降低Irradiance Quality來提升預計算的效能。


  • 把Scene視窗左上方的繪製模式改為Irradiance
  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Irradiance Quality的值慢慢降低
  • 隨著值的下降,產生的光照貼圖變得越來越模糊
我們發現2048是一個既可保持我們要的品質又能提升計算效能的平衡點,雖然準確對度會有點損失,但整體來看是利多於弊的。
  • 從Project視窗選擇TutorialTerrainLow光照參數集
  • 從Inspector介面裡把Irradiance Quality的值設為2048


把設定好的光照參數集指定給場景其他物件


現在我們可以幫LightingTutorialStart場景裡剩餘的靜態物件建立並指定光照參數集。

我們之前討論如果決定一個分類方法。基於特徵(例如大小或是距離鏡頭的距離)將場景物件分組,以方便我們能更容易為物件指定光照參數集。

當我們在處理Environment物件底下其餘的子物件時,請儘量幫能共享光照參數集的物件分同一類,例如:物件是否會很接近? 這樣如果提高該物件的解析度對於結果會明顯的改善,如果是很遠的物件你就不需要相同的設定值,如果物體材料無法反映材質的大量變化,高解析度就沒甚麼好處。

分組不需要太細,對於大多數情況下,幾組差異性大的設定就夠了,分太細也不好管理,可能每個細節都要針對物件獨立修改。

在我們完成的場景LightingTutorialOptimal裡面,我們分組依據如下:


  • RockLow:距離鏡頭有段距離的光滑石頭,因為距離遠所以解析度低。
  • RockMedium:光滑石頭,更接進玩家區域,所以需要高一點解析度和設定。
  • StructuresHigh:需要高解析度呈現的重要的建築物,同時也需要更高的Irradiance Budget和Quality設定。
  • StructuresLow:遠距離的建築物,只需要低解析度設定。
  • TerrainLow:大,遙遠的網格,比如山
  • TerrainPlayable:會很靠近鏡頭的大型地形,需要一個光照貼圖解析度來平衡,大的地形把叢集數量降低也還是很合理
  • TerrainVeryLow:非常遙遠和假的模擬地形,低解析度和低叢集數量,Irradiance Budget和Quality也都很低


除了這些自訂參數之外,在完成的教學LightingTutorialOptimal裡面,我們還放了一些使用預設光照參數的結構,這裡我們用預設的Default-Medium。

使用場景中大多數靜態物件預設的參數集可以減少很多手動的工作,將常用值指定為預設參數設定很有幫助,對於我們的目的,Default-Medium和預設1像素的解析度搭配使用很適合。

Irradiance繪製模式用來評估場景照明非常有用,因為它只會顯示對PRGI有貢獻的靜態物件光照結果。

當要決定你的光照設定決策時,可以用LightingTutorialOptimal來當作一個評估基礎,將光照參數集指定給場景的物件不會花你太久的時間。記住,當你設定這些物件時,要不斷的思考調高參數值所帶來的好處有多少,如果調低帶來的負面影響不多,那不管如何都是首選。


---------------------------------------------------------------------------------

Unity預計算即時GI全文超連結
Unity預計算即時GI - 9.總結
Unity預計算即時GI - 8.微調光照參數
Unity預計算即時GI - 7.了解叢集
Unity預計算即時GI - 6.拆解與減少光照圖
Unity預計算即時GI - 5.光照探測
Unity預計算即時GI - 4.開始預計算
Unity預計算即時GI - 3.了解光照圖
Unity預計算即時GI - 2.即時解析度
Unity預計算即時GI - 1.介紹


沒有留言:

張貼留言

關於我自己

我的相片
Unity台灣官方部落格 請上Facebook搜尋Unity Taiwan取得Unity中文的最新資訊