資源加載
資源加載是加載模塊中最為耗時的部分,其CPU開銷在Unity引擎中主要體現在Loading.UpdatePreloading和Loading.ReadObject兩項中,相信經常查看Profiler的朋友對這兩項肯定毫不陌生了。
Loading.UpdatePreloading,這一項僅在調用類似LoadLevel(Async)的接口處出現,主要負責卸載當前場景的資源,并且加載下一場景中的相關資源和序列化信息等。下一場景中,自身所擁有的GameObject和資源越多,其加載開銷越大。
在很多項目中,存在另外一種加載方式,即場景為空場景,絕大部分資源和GameObject都是通過OnLevelWasLoaded回調函數中進行加載、實例化和拼合的。對于這種情況,Loading.UpdatePreloading的加載開銷會很小。
Loading.ReadObject,這一項記錄的則是資源加載時的真正資源讀取性能開銷,基本上引擎的主流資源(紋理資源、網格資源、動畫片段等等)讀取均是通過該項來進行體現。可以說,這一項很大程度上決定了項目場景的切換效率。正因如此,我們就當前項目中所用的主流資源進行了大量的測試和分析,下面我們將分析結果與大家一起分享,希望可以幫到正在進行開發的你。
注意事項:本篇文章的資源性能分析主要是針對移動項目而言,因為目前UWA所測評的項目中,移動游戲/應用占比在90%以上。所以,我們選擇首先在移動設備上針對每種資源的加載性能進行分析和總結。
資源加載性能測試代碼
以下為我們測試時所使用的測試代碼,我們將每種資源均制作成一定大小的AssetBundle文件,并逐一通過以下代碼在不同設備上進行加載,以期得到不同硬件設備上的資源加載性能比較。
測試環境
引擎版本:Unity 5.2版本
測試設備:五臺不同檔次的移動設備(Android:紅米2、紅米Note2和三星S6,iOS:iPhone 5 和 iPhone 6)
紋理資源
紋理資源是項目加載過程中開銷占用最大的資源之一,其加載效率由其自身大小決定。目前,決定紋理資源大小的因素主要有三種:分辨率、格式和Mipmap是否開啟。
1. 分辨率 & 格式
分辨率和格式是影響紋理資源加載效率的重要因素,因為這兩項的設置對紋理資源的大小影響很大。因此,我們對這兩種因素進行了詳細的測試:
測試1:相同格式、不同分辨率的加載效率測試
我們選取了兩張分辨率為2048x2048的普通紋理資源,并在打成AssetBundle時,將其分辨率最大值分別設置為512x512、1024x1024和2048x20248,紋理格式均設置為ETC1(Android)和PVRTC(iOS)、且關閉Mipmap功能。所以,三組紋理的內存占用分別為256KB、1MB和4MB,其對應AssetBundle大小為156KB、531KB和1.92MB(對于Android平臺)、175KB、628KB和2.4MB(對于iOS平臺)。Unity 版本為5.2,壓縮格式為默認的LZMA壓縮。
Android平臺測試紋理:
我們在五種不同檔次的機型上加載這些紋理資源,為降低偶然性,每臺設備上重復進行十次加載操作并將取其平均值作為最終性能開銷。具體測試結果如下表所示。
通過上述測試,我們可以得到以下結論:
1、紋理資源的分辨率對加載性能影響較大,分辨率越高,其加載越為耗時。設備性能越差,其耗時差別越為明顯;
2、設備越好,加載效率確實越高。但是,對于硬件支持紋理(ETC1/PVRTC)來說,中高端設備的加載效率差別已經很小,比如圖中的紅米Note2和三星S6設備,差別已經很不明顯。
測試2:不同格式、相同分辨率的加載效率測試
我們選取了兩張分辨率為1024x1024的普通紋理資源,并在打成AssetBundle時,根據不同平臺將其紋理格式分別設置不同格式用于打包。對于Android平臺,我們使用ETC1、ETC2、RGBA16和RGBA32四種格式,對于iOS平臺,我們使用PVRTC 4BPP、RGBA16和RGBA32三種格式,同時,對于每張紋理均關閉Mipmap功能。所以,三組紋理的內存占用分別為1MB、1MB、4MB 和 8MB(Android平臺)/1MB、4MB 和 8MB(iOS平臺)。
Android平臺測試紋理:
與測試1相同,我們在五種不同檔次的機型上重復進行十次加載操作并將取其平均值作為最終性能開銷。具體測試結果如下圖所示。
Android設備:
iOS設備:
通過上述測試,我們可以得到以下結論:
1、紋理資源的格式對加載性能影響同樣較大,Android平臺上,ETC1和ETC2的加載效率最高。同樣,iOS平臺上,PVRTC 4BPP的加載效率最高。
2、RGBA16格式紋理的加載效率同樣很高,與RGBA32格式相比,其加載效率與ETC1/PVRTC非常接近,并且設備越好,加載開銷差別越不明顯;
3、RGBA32格式紋理的加載效率受硬件設備的性能影響較大,ETC/PVRTC/RGBA16受硬件設備的影響較低。
注意事項:這里需要指出的是測試中所使用的ETC1和ETC2紋理均為RGB 4Bit格式,所以對于半透明紋理貼圖,需要兩張ETC1格式的紋理進行支持(一張RGB通道,一張Alpha通道)。逐一加載兩張ETC1格式的紋理,其加載效率要低于RGBA16格式,但可以通過加載方式來進行彌補。這一點我們將在后續文章中進行詳細說明。
2. 開啟Mipmap功能
開啟Mipmap功能同樣會增大一部分紋理大小,一般來說,其內存會增加至原始大小的1.33倍。因此,我們對開啟Mipmap功能前后的加載性能進行了詳細的測試:
測試3:開啟/關閉Mipmap功能的加載效率測試
我們仍然使用兩張分辨率為1024x1024的普通紋理資源,分別使用ETC1格式、PVRTC格式、RGBA16格式和RGBA32格式(測試所用紋理與測試2相同),并在打成AssetBundle時,一組開啟Mipmap功能,一組關閉Mipmap功能。
與測試1相同,我們在五種不同檔次的機型上重復進行十次加載操作并將取其平均值作為最終性能開銷。具體測試結果如下圖所示。
Android平臺:
iOS平臺:
通過上述測試,我們可以看出:開啟Mipmap功能會導致資源加載更為耗時,且設備性能越差,其加載效率影響越大。
通過以上性能測試,我們對于紋理資源的加載建議如下:
1、嚴格控制RGBA32和ARGB32紋理的使用,在保證視覺效果的前提下,盡可能采用“夠用就好”的原則,降低紋理資源的分辨率,以及使用硬件支持的紋理格式。
2、在硬件格式(ETC、PVRTC)無法滿足視覺效果時,RGBA16格式是一種較為理想的折中選擇,既可以增加視覺效果,又可以保持較低的加載耗時。
3、嚴格檢查紋理資源的Mipmap功能,特別注意UI紋理的Mipmap是否開啟。在UWA測評過的項目中,有不少項目的UI紋理均開啟了Mipmap功能,不僅造成了內存占用上的浪費,同時也增加了不小的加載時間。
4、ETC2對于支持OpenGL ES3.0的Android移動設備來說,是一個很好的處理半透明的紋理格式。但是,如果你的游戲需要在大量OpenGL ES2.0的設備上進行運行,那么我們不建議使用ETC2格式紋理。因為不僅會造成大量的內存占用(ETC2轉成RGBA32),同時也增加一定的加載時間。下圖為測試2中所用的測試紋理在三星S3和S4設備上加載性能表現。可以看出,在OpenGL ES2.0設備上,ETC2格式紋理的加載要明顯高于ETC1格式,且略高于RGBA16格式紋理。因此,建議研發團隊在項目中謹慎使用ETC2格式紋理。
文章列表