2013年12月26日 星期四

Unity 4.3 關於 Occlusion Culling : 最佳做法

這篇文章是由Jasin Bushnaie所撰寫,用來解釋Umbra在Unity 4.3上的遮擋剔除(Occlusion culling)的第二篇,本篇說明更深入的遮擋剔除調整,如果你錯過了第一篇基礎篇,請見:
http://unitytaiwan.blogspot.tw/2013/12/unity-43-occlusion-culling.html

本篇文章會給你一些技巧建議,幫助你獲得最好的遮擋效果。


何謂好的遮擋品質?
理所當然,首先第一件事情是確保場景中所設定的遮擋是有效果的,遮擋物儘可能放在又好又大的遮擋器後面(Occluder),精細的物件累積到和遮擋器差不多大的時候才從某個角度可以出現。

一般來說Umbra系統不支援遮擋器之間的交互運算,所以就算是茂密的叢林,有很多樹葉會遮擋掉它背後的東西,因為它只會做一次遮擋物的累積運算,所以就Umbra的觀點來看,一般在場景裡的樹和森林是很差的遮擋物,從另一方面來看,像山脈這樣的地形就是一個很好的遮擋物,Umbra一定可以如預期的捕捉到正確的遮擋資料庫裡。


物件的標記
在Umbra裡面主要有兩種物件類型:遮擋器(Occluders)和遮擋物(Occludees),前者是簡單的幾何圖形,Umbra也將它視為單一的實體模型。後者是畫面上那些物件,Umbra實際用來處理遮擋資料的。

遮擋器包含幾乎所有被標記為"靜態遮擋物件(Occluder static)"的物件,理所當然遮擋物就一定是標記了"靜態遮擋物件(Occluder static)"這個旗標。

就經驗來看,正常情況下你應該儘可能的標記為靜態物件好讓Umbra來剔除它們。
另外在預設情況下,大部分的靜態物件也可以作為遮擋器,只要確保你的物件是不透明的,否則就不適合成為一個遮擋器。(如果發生這樣的透明物件指定,Unity會警告你)

還有,如果你的物件包含很小的孔洞(例如有洞的乳酪或是茂密的植物),而且你希望從洞可以看到後面的東西,但調整smallest hole沒有達到你要的效果(關於smallest hole設定可以參考上一篇文章),你只需要把遮擋器的旗標移除就好了。

此外,由於遮擋器是被判定為實心,如果鏡頭沒有誤入遮擋器的情況下都可以正常剔除,這表示如果碰撞系統無法保證鏡頭不會誤入遮擋器,你應該把它的遮擋旗標移除。

物件的精細度
由於Umbra是處裡物件的遮擋剔除,物件不應該有誇張的大小,太大的物件是很難剔除,因為總是會看到物件的某一個部分,透過Umbra處理後幾乎是從來沒被剔除過。
所以如果有這樣的物件請把它分成小塊,像是可以把地形分成很多不同的區塊,不然整個地形從頭到尾都不會被剃除。

對遮擋剔除而言,分類規則最好自然一點,也就是說用正常邏輯思考物件歸類方法,分類太嚴格並不一定好,每一個群組應該是可視範圍接近的物件組合,另一方面來看,太過仔細的分類也可能導致一些不必要的效能消耗,實際上,如果場景有數以萬計遮擋物的話,這個問題就會常常發生。

也許應該強調的是,遮擋物分區問題比較大,遮擋器只是一個用來裝遮擋物的超大湯碗而已。


防漏模型
在上一篇文章裡,我簡單的介紹了Umbra如何像素化遮擋幾何,這些像素資料放在不同的區(Cell),然後通過傳送區(Portal)相互連結,Umbra在處理這個過程是很保守的,小的遮擋器通常會認定這些像素資料比實際上來的小,大的遮擋器會比實際上來的大。

這代表如果剛好有物件接合意外造成的孔,像素化的時候會修補掉而不會留下一個洞,這問題可能會導致奇怪的"遮擋洩漏",例如相機對著一面牆,但是因為牆上有隱形破洞導致牆後面看不到的物件都沒被剔除。

雖然像素化會幫你修補很多意外的孔洞,但在模型製作時就應該考慮模型的"水密處理",下一篇文章我也會介紹怎麼來解決這類問題。


找尋合適的參數值
不可否認,使用Umbra最難的部分是找到適合專案的各項參數,我們用Unity的預設值為出發點,假設Unity的單位對應你遊戲裡面的一米,且遊戲像是一個人類世界的規模(不是那種小分子世界或是有超大機器人的宇宙行星遊戲)。

在經驗法則上smallest hole開始可以給予較大的值,並邊做邊往下調到適合的感覺。
值調大一點有助於一開始快速的烘焙速度,當遊戲體驗中看到錯誤的遮擋才開始往下調整,直到整體感覺沒有問題。


同理,smallest occluder從大一點的值開始也是一樣的道理。一邊檢視一邊調整直到遮擋剔除的感覺完美。如果發現遮擋剔除開始影響效能或是遮擋數據過大,你應該停止往下調整。

至於Backface threshold參數,你可以從100開始如果你的遮擋數據過大或是當鏡頭很接近遮擋器時所呈現的結果怪異,試著把數值往下調90或更小。

最後的文章我會討論一些常見問題,各位也可以訪問www.umbrasoftware.com來或許更多消息。

Unity 現在已經是4.3,是最好的2D,3D專案製作方案,想知道更多訊息請上官方網站:
www.unity3d.com

2013年12月6日 星期五

Unity 4.3 關於 Occlusion Culling : 基本篇

原文作者:Kristyna Paskova

Unity 4.3針對遮擋剔除功能(Occlusion Culling)有重大改進,包含把遮擋剔除重製,不是只有把介面簡化也加快了運算的時間和加了一些新功能。

這個介紹總共有三篇文章,會說明新的遮擋剔除如何在Unity 4.3裡面運作,本篇會說明遮擋剔除的基本原理,以及基本的操作介面。後面的兩篇會著重在常見問題和解決方法。


接下來從基本知識的開始,遮擋剔除是用來消除躲在其他物件後面看不到的物件,這代表資源不會浪費在那些看不到的地方進而提升校能。
在Unity裡,遮擋剔除是透過名為Umbra的中介軟體來執行這個工作,你可以從介面的Window->Occlusion Culling找到(在Lightmapping底下)。


Umbra運作方式

Umbra的遮擋剔除過程可以分為兩個階段,在編輯器裡Umbra會即時檢查可以被看到的物件,首先Umbra會採樣遊戲場景並透過烘焙(Bake)將場景紀錄成為一個資料結構,在製作結構的期間,Umbra會先像素化場景,把一區一區的點歸類群組,並把每一區(Cell)合併到傳送區(Portal),再添加一些必要的數據資料就會成為Unity用的遮擋剔除資料。

在執行時,Umbra會從傳送區呼叫並格式化這些資料並放到一個緩衝區,並測試哪些物件可以被看到,Unity這時會給Umbra鏡頭座標,讓Umbra回傳那些物件是可以看到的,這是一個單向檢查,並不會回傳任何False值,另一方面來看,可能會有些物件被判斷是可見的,但或許並非如此。


這個版本看起來和上個版本很像,但是我們基本上是重製了這個系統,不管內在和外在變得更好!


如何使用Umbra

有幾個因素來讓遮擋剔除得到最佳效果,在理想情況下是效能最好,但越高精準度代表取樣的資料越大,取樣資料越大代表遮擋剔除執行效能越低,如果遮擋剔除吃掉了太多的效能,就不要整個場景都使用。另一個角度來看,如果物件太少就不需要為了少少的物件使用遮擋剔除。這是需要平衡考量的。


Umbra給予你一些參數來調整控制取樣資料平衡,調整執行時烘焙過程和資料取樣類型,就像看到的一樣簡單明瞭,如果已經取樣完成並且鏡頭有開啟遮擋剔除設定,那Unity就會自動使用Umbra。

三個設定

關於Smallest Hole
在設定裡面Smallest Hole值控制著輸入的內容,當像素化遮擋的形狀時,Smallest Hole會直接對應像素大小,這代表如果你的幾何圖形有包含一些縫隙或裂縫你想看穿到後面,可以用這個參數來控制。
另一方面,很多的幾何含有裂縫,你不想要看穿的話,也可以給他一個適當的值來修補。它可以在烘焙的時候協助規劃可視範圍。

請注意,這個參數設定的太小的話會讓烘焙時間很久並占用很大的記憶體,甚至會導致記憶體不足而失敗,話說回來,如果設定的太大的話當然會快得多記憶體也省得多,但也有可能會造成像是圍欄中間的洞看不見後面的東西,所以大不一定好,一般情況下,這個參數儘量是在視覺可接受的範圍內越大越好,實際上大部分的遊戲我們建議是5-50cm是玩家可接受的範圍,在Unity裡面預設值是25cm,是不錯的預設值。



關於Smallest Occluder
Smallest hole決定了那些幾何面的顯示,而Smallest Occluder決定產生資料取樣的品質,數值越大執行遮擋剔除的速度越快,但會提高誤判的機率,數值越小結果會越精確,但會耗用較多CPU的資源成本,品質越好的資料取樣也代表越大的資料空間。

這個值越小代表會取樣更細的遮擋剔除資料,這會直接影響Umbra建立取樣區塊的大小。小區塊太多代表區塊之間的傳送區也會變多,自然會消耗大量的資源在建立傳送區上面。反之亦然
改變這個值的影響可以從下面的圖片看出,越大的值細節就越低,速度越快,反之越小的值細節越多,速度越慢。


大多數遊戲裡,僅量讓Smallest occluder產生的區塊比玩家大個幾米,如果你的遊戲規模不是像星空這樣特別大或是非常小,地方保持可以看到2-6米的距離剛剛好,Unity預設值是5米

Backface threshold
這或許是最難掌握的參數,雖然在大部分情況下你並不需要修改它,但可以了解一下會有一些情況它會派上用場。
首先,這個參數存在最重要的目的是"優化遮擋資料的大小",代表如果你的遮擋資料大小是OK的,你可以完全不管這個值
第二,這個值是一個百分比,因此90代表90%

那到底這個值是做甚麼用呢?
想像一個場景包含許多物件,可能也會有一個地形,在這個情況下我們預設鏡頭位置不會跑到地表下或跑進像建築物的物件裡面(通常你的碰撞體會判斷),這些無效的位置也會從裡面看到三角面,因此在大部分情況下,這個值的設定是為了讓遊戲中的鏡頭不會停在這些無效的位置。


backface threshold參數會幫助你處理這樣的工作.設定多少%的背面幾何可以從鏡頭的任何角度被看到,Umbra會把角度以外的背面資料剔除,原理是Umbra從全部的區塊隨機取樣後用射線檢查有多少光線射到背面幾何面,如果超過一定值會把該區塊從遮擋資料中剔除,當值是100代表完全禁用背面測試。

所以,如果你設定這個值為70,代表在區塊裡所有的位置超過70%背面被射線射到的區塊,會被執行"剔除在遮擋資料裡尚未定義的位置",因為相機永遠不會停在那些地方,有些像是地表以下區域由於相機不會在那裏停留,某些情況下會場生相當顯著的資料大小差異。

要強調的是"剔除在遮擋資料裡尚未定義的位置",裡面的"尚未定義"意思是可能是正確或不正確或有錯誤的資料,所有的物件都是簡單的視錐剔除。

當然,在某些情況下,會發生有些背面的幾何面被鏡頭看到,有可能是因為被認定為單面網格或因為錯誤標記為遮擋器,如果物件很大,可能會導致背面測試觸發附近的區域,造成剔除錯誤等等,這就是為什麼Unity預設這個值是關閉的(100)。



你可以隨意調整參數來體驗一下效果如何,試著調成90應該就會放棄了大量的地形,例如地表下,看看他是如何影響遮擋資料大小,甚至可以試著調整更低,如果開始發現畫面不自然再把值調回100看看是否問題得以解決。


待續...
在下一章,我們會介紹一些如何做出最佳遮擋剔除結果的實踐和建議,各位也可以訪問www.umbrasoftware.com來或許更多消息。



Unity 4.3 關於 Occlusion Culling : 第二篇


著作人