Unity效能最佳化記憶體最佳化

weigang發表於2024-05-20
如何最佳化記憶體?
1.壓縮自帶類庫;
2.將暫時不用的以後還需要使用的物體隱藏起來而不是直接Destroy掉;
3.釋放AssetBundle佔用的資源;
4.降低模型的片面數,降低模型的骨骼數量,降低貼圖的大小;
5.使用光照貼圖;
6.使用多層次細節(LOD);
7.使用著色器(Shader);
8.使用預設(Prefab)等。
記憶體開銷無外乎三大部分:
1. 資源記憶體佔用;
2. 引擎模組自身記憶體佔用;
3. 託管堆記憶體佔用
資源記憶體佔用:
在一個較為複雜的大型專案中,資源的記憶體佔用往往佔據了總體記憶體的70%以上。因此,資源使用是否恰當直接決定了專案的記憶體佔用情況。一般來說,一款遊戲專案的資源主要可以分為以下幾種:紋理(Texture),網路(Mesh),動畫片段(AnimationClip)、音訊片段(AudioClip)、材質(Material)、著色器(shader)、字型資源(Font)以及文字資源(TextAsset)等等。其中,紋理,網格、動畫片段和音訊片段則容易造成較大記憶體開銷的資源。
紋理:
紋理資源可以說是幾乎所有遊戲專案中佔據最大記憶體開銷的資源。一個6萬片的場景,網格資源最大才不過10MB,但一個2048*2048的紋理,可能直接就達到16MB,因此,專案中紋理資源的使用是否恰當會及大地印象專案的記憶體佔用。
那麼,紋理資源再使用時應該注意哪些地方呢?
紋理格式。紋理格式是研發團隊最需要關注的紋理屬性。因為它不僅影響紋理的內粗你佔用,同時還決定了紋理的載入效率。一般來說,我們建議開發團隊儘可能根據硬體的種類選擇硬體支援的紋理格式比如Android平臺的ETC、iOS平臺的PVRTC、WindowsPC上的DXT等等。因此,我們在UWA測評報告中,將紋理格式進行了羅列,一邊開發團隊進行快速查詢,一步定位。
在使用硬體支援的紋理格式時,你可能會遇到以下幾個問題:
色階問題:
由於ETC、PVRTC等格式均為有失真壓縮,因此,當紋理色差範圍跨度較大時,均不可避免地造成不同程度的階梯狀的色階問題。因此,很多研發團隊使用RGBA32/ARGB32格式來實現更好的效果。但是,這種做法將造成很大的記憶體佔用。比如,同樣一張1024*1024的紋理,如果不開啟Mipmap,並且為PVRTC格式,則其記憶體佔用為512KB,而如果轉換為RGBA32位,則很可能佔用更達到4MB。所以,研發團隊在使用RGBA32或ARGB32格式的紋理時,一定要慎重考慮,更為明智的選擇是儘量減少紋理的色差範圍,時期儘可能使用硬體支援的壓縮格式進行儲存。
ETC1不支援透明通道問題:
在Android平臺上,對於使用OpenGLES2.0的裝置,其紋理格式僅能支援ETC1格式,該格式有個較為嚴重的問題,即不支援Alpha透明通道,使得透明貼圖無法直接透過ETC1格式來進行儲存。對此。我們建議研發團隊將透明貼圖儘可能分成兩張,即一張RGB24位紋理記錄原始紋理的顏色部分和一張Alpha8紋理記錄原始紋理的透明通道部分。然後,將這輛張貼圖分別轉化為ETC1格式的紋理,並透過特定的Shader來進行渲染,從而來達到支援透明貼圖的效果。該種方法不僅可以極大程度上逼近RGBA透明貼圖的渲染效果,同時還可以降低紋理的記憶體佔用,是我們非常推薦的使用方式。
當然,目前已經有越來越多的裝置支援了OpenGLES3.0這樣Android平臺上你可以進一步使用ETC2甚至ASTC,這些紋理格式均為支援透明通道且壓縮比更為理想的紋理格式。如果你的遊戲適合人群為中高階裝置使用者,那麼不妨直接使用這兩種格式來作為主要儲存格式。
紋理尺寸:
一般來說,紋理尺寸越大,佔用記憶體越大。
Mipmap功能
Mipmap旨在有效降低渲染頻寬的壓力,提升遊戲的渲染效率。但是,開啟Mipmap會有將紋理記憶體提升1.33倍。對於具有較大縱深感的3D遊戲來說,3D場景模型和角色我們一般是建議開啟Mipmap功能的,但很多2DUI紋理就不必要了。
Read&Write
一般情況下,文理資源“Read&Write”功能在Unity引擎中是預設關閉的。但是,我們仍然在專案深度最佳化時發現了不少專案的紋理資源會開啟該選項。對此,我們建議壓發團隊密切關注文理資源中該選項的使用,因為開啟該選項將會使文理記憶體增大一倍。
網格
網格資源在比較複雜的遊戲中,往往佔據較高的記憶體。
Normal\Color和Tangent(切線)
在我們深度最佳化過的大量專案中,Mesh資源的資料經常會含有大量的Color資料,Normal資料和Tangent資料。這些資料的存在將大幅增加Mesh資源的檔案體積和記憶體佔用。其中Color資料和Normal資料主要為3DMax、Maya等建模軟體匯出時設計所生成,而Tangent一般為匯入引擎時生成。
更為麻煩的是,如果專案對Mesh進行DrawCallBatching操作的話,那麼狠有可能進一步增加總體記憶體的佔用。正因如此,我們在UWA測評報告中為每個Mesh展示了其Normal,Color和Tangent屬性的具體使用情況,研發團隊可以直接針對每種屬性進行排序檢視,直接定位出現冗餘資料的資源。一般來說這些資料主要為Shader所用,來生成較為酷炫的效果。所以,建議研發團隊針對專案中的網格資源進行詳細檢測,檢視該模型的渲染Shader中是否需要這些資料進行渲染。
其他
動畫片段
音訊片段
引擎模組自身記憶體佔用。
託管堆記憶體佔用

相關文章