首先,HLOD System主要的目標是爲了減小Draw Call。而後,進行更多的Batch批處理,從而大大提升渲染性能,減小面數和紋理,這樣咱們相應地節省了內存,並提高了加載時間。
HLOD System只針對當前所在的地方進行加載,它會流式加載網格和紋理,在後臺進行異步的操做。html
本次HLOD是基於官方AutoLOD代碼的擴展和改進製做出來的,連接:https://github.com/Unity-Technologies/AutoLOD,連接是AutoLOD的文章,能夠先看看。下面將詳細介紹HLOD原理和實現。git
HLOD與傳統LOD差別對好比表所示。github
|
LOD架構 |
HLOD異步 |
減面性能 |
√測試 |
√優化 |
減小Batches、紋理數量spa |
×設計 |
√ |
減小內存使用 |
× |
√ |
CPU性能提高 |
× |
√ |
磁盤空間 |
= |
+ |
1.系統架構
系統主要由編輯層和運行層組成,編輯層負責每一個預製體的LODGroup生成、BVH劃分、網格、貼圖合併,同時自動作好運行層所須要的關聯。運行層負責該系統中Renderder、LODGroup管理及BVH層級切換,系統架構如圖所示。
2.系統流程
本套系統擁有一條完整流程,其系統流程如圖所示。
八叉樹對LOD Group進行劃分到各個區域,劃分條件由每一個區域超過n個mesh開始劃分,劃分依據由LOD Group中心點做爲劃分點,可設置剔除實際包圍盒超過指定大小的mesh,劃分規則如圖2-4所示。
劃分後效果如圖所示。
這裏劃分方式對AutoLOD進行了改進,AutoLOD劃分方式以下圖所示,下圖是BVH劃分的同一級別中其中的4個區域,圈內是一組LodGroup,AutoLOD在進行BVH劃分規則是隻要該組LodGroup有任何模型與區域接觸,那麼該組LodGroup就會被算入該區域,圖中4角星與二、三、4區域同時有相交,所以在模型合併的時候這3個區域都會將該組LodGroup下的模型合併。假設HLOD切換到了該層級且同時顯示二、三、4節點的合併模型,那麼這個LodGroup合併的模型就會被顯示了3份,這樣的效果是不容許的,解決辦法就是同一個層級每一個區域不能出現相同的LodGroup。
本次HLOD採用的解決辦法是使用LodGroup的中心點進行劃分,這樣就能夠保證一個LodGroup最多能被一個區域包含,以下圖所示,箭頭指向的點就是LodGroup的中心點,它只有4這個區域包含。
1.合併原理
根據2.3的劃分,能夠設置合併幾層的模型(從最底下開始計算),以下圖所示的爲合併2層,其中第一層(最底層)有三個區域合併,第二層有兩個區域合併。這裏節點比2.3少了,是由於沒用的節點會被剔除掉,若是這裏設置只合並一層也就是最底層,那麼上面兩層也會被剔除掉。
2.合併的網格
網格每生成一層就會多一倍以上磁盤大小,若是重複的模型多了,那麼合併後的網格磁盤大小將會成倍增長,合併後的網格以下圖所示。
例如:(300*300M場景),原始網格6M磁盤空間,合併原始網格兩層後多出20M空間(fbx)。
3.合併的貼圖
以下圖,貼圖目前只保留了MainTex貼圖,默認使用Standard物理光照shader(帶陰影),支持GPU Instancing。
貼圖合併規則以下圖所示,設置合併層次,好比圖中設置3層,那麼第三層是全部子節點合集的大貼圖(不重複)。
例如:300*300M場景,原始貼圖大小26M,合併原始網格兩層後多出50M,多出這麼多主要是由於把整個場景合併,原始貼圖不少是共用的,致使合併後內存上升問題,因此合併時選擇模型和貼圖複用性低的模型合併比較好。
1.如何工做
當上述步驟作好後,在BVH的根節點上會有個HLOD CULL腳本,用於控制當前管理的HLOD的切換。
當攝像機靠近部分精細模型時,HLOD切換狀態如圖2-10所示(紅色爲當前顯示的層級,藍色爲不顯示層級)。
當攝像機靠近少部分精細模型時,HLOD切換狀態以下圖所示。
當攝像機距離精細模型比較遠時,HLOD切換狀態如圖2-12所示。
2.計算原理
首先是精細度模型是否須要顯示計算,根據距離LOD Group的距離、屏幕佔比與攝像機FieldOfView計算出relativeHeight,這個數值對應如圖2-14所示的攝像機位置,若是這個數值不指向最精細模型,那麼就顯示合批模型。
relativeHeight表示
3.工做原理
如圖2-15所示,LODGroup的計算只會計算最精細的模型,只要有一個精細模型被激活那麼該節點的精細模型都會被激活,父節點的全部HLOD被dirty並隱藏。若是精細模型不激活,那麼直到找到父節點被dirty或已是最頂層狀況激活當前層HLOD。
流式加載的設計主要針對移動端內存佔用太高問題,利用流式加載能夠作到極大下降移動端運行常駐的內存。設計如圖3-1所示。
首先,一個HLOD System裏面有多顆子樹,每顆子樹都會帶有一個流式管理器,該管理器負責當前子樹的全部節點流式加載,而HLOD Cull系統負責通知每顆子樹哪些節點狀態出現了變更。
以下圖,流式加載有兩種模式,通過大量測試,總結出了各自優缺點。
1.裝完再卸載
當前子樹下,全部須要加載的節點加載完畢後再卸載須要卸載的。
優勢:能夠保證模型常在視區
缺點:常常會出現內存峯值,常常會卡幀
2.直接卸
當前子樹下,卸載不等待其餘節點加載完就卸載
優勢:極大避免卡幀問題,少量出現內存峯值問題。
缺點:不可保證模型常在視區,加載的模型內存大可能會出現閃爍現象。
常常會出現玩家在加載邊沿處來回走動,這會形成資源不斷的來回裝卸,所以加入距離緩衝策列。
設定必定距離的緩衝,當觸發流式切換後,要再次激活流式切換須要走出設定的緩衝距離纔會切換,設計如圖3-3所示。
HLOD Stream應用場景:
1.大城鎮,不少房屋須要處理不少Bathces的狀況
2.須要看得遠,遠處看得見輪科且數量較多的狀況使用
3.物件密集而且沒法使用GPU Instancing的地方使用
4.只要有不少Batches的地方而沒法優化掉的均可以考慮使用
1.貼圖合併只保留MainTex貼圖,默認使用Standard物理光照shader(帶陰影),支持GPU Instancing。
2.相同的預製體的網格合併時內存會翻倍(這個跟靜、動態合批同樣)
3.每生成一層HLOD所須要的網格內存會多一倍以上
4.不一樣子樹相同貼圖會出現重複貼圖合併現象。