2016年12月26日 星期一

Unity預計算即時GI - 5.光照探測

原文
翻譯:Kelvin Lo

版本:5.5 難度:中等

我們已經理解場景裡的圖表數量對預計算時間的影響,這樣我們就能從預計算流程裡想辦法降低一些物件計算來讓光照效能大躍進,同時也會減少圖表產生的數量.取而代之的,我們可以對這些物件做光照探測(Probe Lighting)處理,它是一種讓物件接收場景間接照明的好方法,雖然被光照探針指定的物件無法計算場景的光照反射,但通常影響不大。這種方法非常適合用在場景裡的小物件,因為小物件對光照反射計算幾乎沒什麼影響。


何謂光照探測



光照探測技術是一個能在遊戲裡讓即時光照更逼真的快速演算法,通常會用在處理遊戲世界的人物角色或是動態物件的光照,它的優點在於Runtime處理效能佳而且還能預先計算好。

光照探測的原理是透過放在3D空間裡的探針來接收照明資訊,然後用像是球諧函數(spherical harmonics)的數學演算法將結果編碼在一個球體上。這些係數佔用空間很小在遊戲過程裡能快速"解包",好讓Shader可以存取並計算表面光照,在Unity裡這個功能叫做Light Probes。

使用光照探測是有些限制的,其中一個限制是在不提高探針數量的前提下很難在球型範圍上表現出高頻或斑駁的光照,但精度和消耗成本成正比,代表在效能的前提下,我們必須限制較低階的球諧函數。

實際上一個3D座標只能用一個球體來紀錄照明資料,所以光照探測不適合用在有大量光照投射在大物件的狀況。另外一個限制是當用球諧函數在一個球體上編碼時,通常不擅於處理用有廣大平面的物件或帶有很深的凹洞的物件.如果你正計畫要把光照探測技術用在大型物件上,Unity有提供另一個光照探測代理體(Light Probe Proxy Volumes,LPPV)的技術可以參考手冊說明

儘管有這些限制,光照探測還是很適合和符合條件的小物件一起搭配使用,產生成本低廉效果卓越的結果。在本教學後面我們將會深入探討如何設定和放置光照探針(Light Probes),現在我們只需要理解適當的使用光照探測這功能可以降低光照貼圖的數量。


幫物件設定光照探針



儘管一次將環境裡所有的物件設定為靜態物件來做光照計算是很OK的,但是整個環境裡有很多物件很適合用光照探測技術來處理,把這些物件的靜態標籤清除之後,他們就不再受到PRGI計算影響,同時光照貼圖的數量也會降低。減少場景裡光照圖的數量是加快預計算時間的關鍵。

使用光照探測的最佳物件就是像這種凸起的小碎石

我們從Unity編輯器的Hierarchy視窗來看看環境(Environment物件)底下的子物件,你會發現Props底下的物件幾乎都是點綴場景用的小物件,像是石頭,水桶或木板。這些物件非常多,而且很多小物件可能不太好拆UV。取得沒有失真的光照貼圖UV可能會產生很多UV Shell,一旦UV Shell一多就會需要額外的光照圖,更多的光照圖代表更多的貼圖像素產生,依此類推。

假設這些物件很小,不太可能對場景的間接照明產生什麼影響,因為小所以表面能顯示的光照細節也有限,所以這樣的物件非常適合用光照探測技術來計算,不但可以加速預計算時間,同時要存到記憶體的光照圖和Shader解碼的數量也變少了,在Runtime時的效能也會因此提升。

  • 從Hierarchy視窗選擇Props物件
  • 從Inspector視窗把最右上角的Static取消打勾
  • 這時會跳出一個視窗,選擇"Yes, change children"

如果這時我們放著算到完就能看到場景最終的光照運算結果,但你會發現被探測光影響的非靜態物件(non-Static objects)和周圍的物件有點格格不入,和場景的光照也不匹配。這是因為我們還沒幫光照探針(Light Probes)做設定,導致這些物件被納入環境探針(Ambient Probe)的計算。環境探針本質上是一個在場景裡無法看到的隱形探測器,只對Lighting視窗裡的Ambient Source所指定的來源取樣。

在沒有光照探針影響下,非靜態物件可能看起來不像在他們應該在的地方

為了將非靜態物件擺起來的結果更令人信服,我們需要花點時間來將光照探針放置在場景的周圍,方便取樣世界裡的間接照明。


放置光照探針



非靜態物件會透過附近的光照探針來接收光照資料,光照探針會基於探針之間的空間劃分為四角面,然後檢查物件屬於哪個四角面來決定物件"讀取"哪個探針。為了正確的產生這些四角面,探針間的位置關係在3D空間裡就必須要放的有體積感。

畫面中那些白色的球體就是光照探針在場景裡的樣子

光照探測技術執行所耗的效能非常低,預計算也非常快,然而,為了要最佳化效能有些地方要注意一下,儘管設定簡單,但密度太高的探針可能會浪費資源,太接近的探針在特定的光照條件下取樣結果沒什麼差異。為了效率最好的做法是在光照變化明顯的區域放置密度較高的探針,例如由亮轉暗的區域,或是強光反射的區域。

  • 要設定光照探針,可以從物件選單建立一個光探針群組(GameObject > Light > Light Probe Group)
  • 開始放置光照探針,從Hierarchy視窗選擇剛建好的光探針群組物件
  • 從Inspector視窗裡找到Light Probe Group元件,選擇Edit Light Probes開始編輯
  • 你可以從場景直接點選那些探針,留下角落一個探針,其他可以全刪了
  • 將剩下的一個探針移到地形上面一點點,然後按Ctrl + D( Mac是按Cmd + D)來複製它
  • 用移動工具(按W)將複製的二號探針沿著Y軸往上約2米(2 meters)
  • 再複製一次探頭,並將新探頭的Y軸往上移更高,約5米


Light Probe Group元件裡的Edit Light Probes按鈕位置


這樣的垂直探針分佈為的是讓我們可以同時取樣到地表,頭部高度和天空(考慮到物體可能跳躍的高度)的間接光照(indirect light)。當我們將這組光照探針開始大量複製到場景其他地方來產生光照探測區域時,要確保可玩區域都會被探針所產生的四角面覆蓋到,可以看到探針之間會以洋紅色的線串聯起這些區域。

如圖所示光照探針的位置和他們之間所產生的四角面

  • 全選剛剛建立好的三個探針(按住Shift並點選每個探針或是拉一個框選起來)
  • 複製整個探針組並移到場景其他需要採樣的地方

說到需要採樣的地方不外乎是有陰影的區域或是地形材質色調會變化的地方,請記住,我們的目的是取樣場景裡的間接或反射光照。為了讓每個光照探頭效能都花在刀口上,儘量確保他們對一些變化明顯的地方進行取樣,如果探針放在一致性很高的光照區域,那探針反映給動態物體的結果不會太明顯。如同遊戲優化各方面技巧一樣,儘量確保每個探針都是有其存在的必要。

繼續重複上述操作,在照明區域大密度的放置光照探針直到產生了一個像是籠子般的區域涵蓋所有的可玩區域。佈置這些探針時,請記得每一次都要檢查最底部的探針要和地面保持一定的距離。


我們的範例檔LightingTutorialOptimal裡面附了兩組光照探針,VillageLightProbeGroup比較密集用在村莊區域,ExtentsLightProbeGroup比較稀疏用在村莊外無法到達的區域。第二個光照探針組涵蓋了整個遊戲世界以防止任何非靜態物件離開可玩區域,這一組不需要像村莊那組探針那麼密集,垂直軸只要兩個探針就夠了。

將光照探針拆成兩組方便定義探針用途,每個探針組都可以獨立開啟或關閉方便因應場景各種需求,這些光照探針在Runtime執行的時候會自動組合並執行重疊檢查(de-duplication pass)刪除所有重疊的探針。

要看到光照探針的照明結果,必須等到預計算完成,如果Lighting視窗(Window > Lighting)底下的Auto是打勾的話計算就會自動進行,如果沒打勾就要按一下旁邊的Build按鈕來手動計算。

一旦計算完成後,你會發現場景裡面的非靜態物件會開始接收光照探針的資料,看起來和場景光源會更匹配。要查看點燈狀態下的光照探針,可以從Hierarchy視窗選擇光照探針組。

現在場景裡有了光照探針組,我們就能幫場景裡的小物件取得間接光照資料,而不需要從PRGI的流程中為這些物件產生額外的光照圖。


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

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.介紹


沒有留言:

張貼留言

著作人

網誌存檔