Unity大密度建築場景載入解決方案

2021-09-19 05:26:40 字數 2648 閱讀 9878

現在虛擬城市**,以及軍事**專案越來越多,開發此類專案,首先面對的乙個比較棘手的問題是記憶體管理,城市中的建築物特別多,這些建築物的面數和貼圖都要被加到記憶體中的,記憶體有自己的峰值,超過了就要崩掉,所以記憶體的優化是必須要面對以及解決的問題。 

unity官方提供了occlusion culling的裁剪操作,網上有很多文章對它做了相關介紹,因為它是unity自身提供的,對於我們程式設計師來說就是乙個黑盒子,並不利於我們自己去進一步的優化,最好的方式就是自己通過**重新實現乙個occlusion culling演算法,當然對於城市**只做occlusion culling是不能完全解決問題的,我們需要從幾個方面入手搞定它,本篇博文就給讀者介紹這些針對密集建築物的優化。下面先看看虛擬**的場景: 

面對這麼複雜的場景,我們該如何去解決呢?本篇部落格教給開發者解決問題的方法,我們會從五個方面來實現我們的密集建築物解決方案。

autolod

攝像機是用來裁剪的,我們可以設定攝像機的遠裁剪面距離做一些優化操作,當然如果是在飛行模擬,這種方法是不可取的,因為我們要求視野是足夠大的,這樣攝像機視錐體內的物體肯定會很多的,效率就會下降,解決這個問題很自然的想到lod演算法,虛擬場景中的建築是非常多的,我們不可能讓美術幫我們把每個建築都進行減面處理,工作量是相當大的,lod是根據攝像機的距離遠近相應的顯示不同面數的建築物,我們需要想一種能夠自動幫我做lod處理的演算法,autolod就是為解決這個問題而生的。lod模型顯示如下所示: 

autolod實現的效率比較高,佔的視訊記憶體少,測試的結果如下所示:

其實我們還可以找到一種更好的演算法,結合autolod演算法一起優化建築物的面數以及材質,也是第二個步驟要講解的內容——amplify impostors外掛程式,下面介紹amplify impostors外掛程式。

amplify impostors

這個是asset store提供的解決方案,它的基本原理是根據攝像機的距離,將原物體生成乙個**物體,**物體面數非常少的,外形跟原物體幾乎是一樣的,而且還可以旋轉,縮放,位移,並且可以投影,效果如下所示: 

**物件的生成,我們可以使用gpu例項化,該技術非常適合用於移動端,它對於面數的優化非常好,執行效率測試如下所示: 

在實際專案執行中,看一下樹木模型實現的效果圖如下所示: 

amplify texture

技術實現參考**:

關於模型的優化技術差不多就講完了,運用上面的技術完全可以幫助我們處理密集型建築模型。下面還有一項重要的技術講解,也就是我們說的場景裁剪,我們使用的演算法也是occlusion culling。

occlusion culling

occlusion culling也是一種遮擋裁剪,可以將遮擋住的物體直接從記憶體中移除,或者從攝像機可視空間移除,這裡講的演算法與unity自帶的occlusion culling是不一樣的,該演算法尤其對建築物密集的場景非常實用,先看看occlusion culling是如何工作的?如下圖所示: 

在此介紹兩種利用occlusion culling方法解決遮擋剔除的問題,首先介紹的方法是

potentially visible set

參考**: 

具體實現步驟如下所示: 

1、地圖切割成tile,tile切割成portal(視口)和cell(大物件、中物件、小物件); 

2、檢測場景物件所屬cell,乙個物件可以屬於多個cell; 

3、 利用蒙特卡洛方法portal隨機一些起點,cell隨機一些終點(根據大、中、小隨機不同數量的點); 

4、 雙層遍歷每個portal和cell,射線檢測是否阻擋,如果阻擋,判斷阻擋物是否被在當前檢測cell內,如果是,cell可見;(注,當前設定兩個高度檢測) 

5、 儲存檢測資料,執行時載入解析,根據玩家位置檢測當前portal,然後遍歷場景所有cell內item,判斷顯示和隱藏; 

總之: 

此pvs方案相比於unity occlusionculling,更適合大地圖比如5000公尺x5000公尺,pvs生成data基於tile,支援動態載入,占用記憶體忽略不計,同時cpu消耗也極少;

先看看沒有使用occlusion culling裁剪演算法之前,實現效果圖如下所示: 

應用了occlusion culling 演算法後,看看效果如下所示: 

通過上面兩幅圖的資料對比,可以看到draw call明顯減少了,優化效果還是非常明顯的,再看看另一種occlusion culling 演算法實現的效果。

ioc演算法

先把該演算法能實現的功能給讀者介紹一下: 

1、實現建築物的裁剪 

2、粒子效應遮擋剔除 

3、燈光遮擋剔除 

4、完全支援實時陰影 

5、完全支援動態批處理 

6、支援移動裝置上的密集場景處理

我們先看看對特效的遮擋剔除優化,在優化前的場景渲染,如下圖所示: 

優化後的遮擋剔除效果,如下圖所示: 

通過兩幅圖對比可以看到,draw call減少了一半多,當然我們還可以進一步去優化。

該演算法對於密集型建築同樣好用,同樣先展示乙個沒有使用任何裁剪演算法的有密集物體的場景,draw call數量是非常大的。如下圖所示: 

經過我們的occlusion culling演算法後的裁剪效果,如下圖所示: 

draw call數量對比也是非常明顯的,還是有效果的。

總結:以上給讀者介紹了針對密集型建築使用的解決方案,該方法在pc端,移動端都是適用的,最後把**奉上,參考案例**可以將其應用到自己的專案開發中。

unity 場景載入

gui.draw texture 繪製紋理 static function drawtexture position rect image texture scalemode scalemode scalemode.stretchtofill alphablend bool true,imageas...

unity之載入場景

遊戲中的loading分為 靜態loading和動態loading。簡單形象的做個比喻 靜態loading可能就是一張背景圖。而動態的loading就是在讀取的同時有乙個東西在 轉圈 1.靜態loading 2.動態loading 一些常見問題 一.遊戲是否可以只做乙個場景?可以,執行 gameob...

Unity打包載入場景(Assetbundle )

打包scene 我們可以把整個場景進行打包,因為移動平台不能更新指令碼,所以這個功能就會有所限制,我的建議是烘培場景,然後把多個場景可復用的物件移除,場景中只保留獨一無二的遊戲物件,然後再打包場景,執行遊戲時載入場景後,再動態的將之前移除的物件重新新增進來。menuitem custom edito...