1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | Unity移動端性能優化 馮委 馮委 遊戲開發 262人讚同了該文章 1.渲染 利用reflect probe代替反射、折射,盡量不用RTT、GrabPass、RenderWithShader、CommandBuffer.Blit (BuiltinRenderTextureType.CurrentActive...) 建立統一後處理框架(bloom、hdr、DOF等)代替多後處理,可以共用模糊函數,減少多次blit;另外要注意RTT的尺寸。 空氣折射、熱浪扭曲等使用GrabPass不是所有硬件都支持,改為RTT或者後處理來優化。 建立統一shader材質代替單一shader,充分利用shader_feature、multi_compile,並將宏開關顯示於界面。 圖像混合代替多通道紋理,陰影投射、陰影接收、MetaPass、forwardadd 等pass不需要時要剔除。 少用alpha test、discard、clip、Alpha Converage等,因為會影響Early-Z Culling、HSR的優化。 避免Alpha Blend穿透問題(權重混合、深度剝離等透明排序方法代價太大了)。 光照貼圖代替動態陰影、盡量不用實時光;陰影貼圖、環境貼圖用16位代替32位;利用projector+rtt或者光圈代替實時陰影。 將環境參數(風、雨、太陽)等shader全局參數統一管理。 非主角可以用matcap代替pbr、無金屬不一定要用pbr,仔細選擇物理渲染所用的FDG(F:schlick、cook-torrance、lerp、要求不高用4次方,D:blinn-phong、beckmann、 GGX、GGX Anisotropic,G:neumann、cook-torrance、Kelemen、SmithGGX;standard shader要注意選擇BRDF1-BRDF3),渲染要求不高時不用GGX;可以用LH來優化GGX。 用fixed、half代替float,建立shader統一類型(fixed效率是float的4倍,half是float的2倍),小心選擇shader變量的修飾(uniform、static、全局),選擇Mobile或Unlit目錄下shader 使用高低配渲染,內存足夠時可以考慮開啟mipmap 使用surface shader注意關掉不用的功能,比如:noshadow、noambient、novertexlights、nolightmap、nodynlightmap、nodirlightmap、nofog、nometa、noforwardadd等 standard shader的變體太多(3萬多),導致編譯時間較長,內存佔用也很驚人(接近1G),如果使用要關掉沒用的shader_feature,比如:_PARALLAXMAP、SHADOWS_SOFT、DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE、_DETAIL_MULX2、 _ALPHAPREMULTIPLY_ON;另外要去掉多餘的pass shaderforge、Amplify Shader Editor生成的shader有多餘代碼要程序專門優化,Amplify Shader Editor功能更強大一些,而且開源,建議學習。 不要用unity自帶terrian,因為即使只用3張splat圖,shader也是對應4個的,建議T4M或者轉為mesh。 模型和材質相同且數量巨大時用Instance來優化,比如草。 利用查找紋理(LUT)來優化複雜的光照渲染,比如:皮膚、頭髮、噴漆等。 盡量不要使用Procedural Sky,計算瑞麗散射和米氏散射效率比較低。 盡量不要使用speedtree,改為模型加簡單樹葉動畫,不過SpeedTreeWind.cginc裡面的動畫函數很豐富,TerrianEngine中的SmoothTriangleWave很好用。 多用調試工具檢查shader性能,常用工具有:FrameDebug、Nsight、RenderDoc 、AMD GPU ShaderAnalyzer / PVRShaderEditor、Adreno Profiler 、騰訊Cube、UWA等;另外可以內置GM界面,比如開關陰影,批量替換shader等方便真機調試。 2.腳本 減少GetComponent、find等查找函數在Update等循環函數中的調用、go.CompareTag代替go.tag 、 減少SendMessage等同步函數調用;減少字符串連接;for代替foreach,5.5以後版本foreach已經優化過了;少用linq; 大資源改為異步加載 合理處理協程調用 將AI、網絡等放在單獨線程 發布優化:關閉log、剔除代碼 偽隨機 腳本掛載類改為Manager等全局類實現 lua中盡量不實現update、fixedupdate等循環函數,lua和csharp互調用的效率比較低。 3.內存管理 池子管理粒子、float UI等小資源,頻繁地GC會造成卡頓 必要時主動調用GC.Collect() 按照不同資源、不同設備管理資源生命週期,Resources.Load和Assetbundle統一接口,利用引用計數來管理生命週期,並打印和觀察生命週期。保證資源隨場景而卸載,不常駐內存,確定哪些是預加載,哪些洩漏。 內存洩漏(減少駐留內存):Container內資源不remove掉用Resources.UnloadUnusedAssets是卸載不掉的;對於這種情況,建議直接通過Profiler Memory中的Take Sample來對其進行檢測,通過直接查看WebStream或SerializedFile中的AssetBundle名稱,即可判斷是否存在“洩露”情況;通過Android PSS/iOS Instrument反饋的App線程內存來查看; 堆內存過大:避免一次性堆內存的過大分配,Mono的堆內存一旦分配,就不會返還給系統,這意味著Mono的堆內存是只升不降的。常見:高頻調用new;log輸出; CPU佔用高:NGui的重建網格導致UIPanel.LateUpdate(按照靜止、移動、高頻移動來切分);NGUI錨點自身的更新邏輯也會消耗不少CPU開銷。即使是在控件靜止不動的情況下,控件的錨點也會每幀更新(見UIWidget.OnUpdate函數),而且它的更新是遞歸式的,使CPU佔用率更高。因此我們修改了NGUI的內部代碼,使錨點只在必要時更新。一般只在控件初始化和屏幕大小發生變化時更新即可。不過這個優化的代價是控件的頂點位置發生變化的時候(比如控件在運動,或控件大小改變等),上層邏輯需要自己負責更新錨點。加載用協程; 控制同一個UIPanel中動態UI元素的數量,數量越多,所創建的Mesh越大,從而使得重構的開銷顯著增加。比如,戰鬥過程中的HUD血條可能會大量出現,此時,建議研發團隊將運動血條分離成不同的UIPanel,每組UIPanel下5~10個動態UI為宜。這種做法,其本質是從概率上盡可能降低單幀中UIPanel的重建開銷。 資源冗餘:AssetBundle打包打到多份中;動態修改資源導致的Instance拷貝多份(比如動態修改材質,Renderer.meterial,Animation.AddClip)。 磁盤空間換內存:對於佔用WebStream較大的AssetBundle文件(如UI Atlas相關的AssetBundle文件等),建議使用LoadFromCacheOrDownLoad或CreateFromFile來進行替換,即將解壓後的AssetBundle數據存儲於本地Cache中進行使用。這種做法非常適合於內存特別吃緊的項目,即通過本地的磁盤空間來換取內存空間 4.美術 建立資源審查規範和審查工具:PBR材質貼圖製作規範、場景製作資源控制規範、角色製作規範、特效製作規範;利用AssetPostprocessor建立審查工具。 壓縮紋理、優化精靈填充率、壓縮動畫、壓縮聲音、壓縮UI(九宮格優於拉伸);嚴格控制模型面數、紋理數、角色骨骼數。 粒子:錄製動畫代替粒子、減少粒子數量、粒子不要碰撞 角色:啟用Optimize Game Objects減少節點,使用(SimpleLOD、Cruncher)優化面數。 模型:導入檢查Read/Write only、Optimize Mesh、法線切線、color、禁用Mipmap 壓縮紋理問題:壓縮可能導致色階不足;無透明通道用ETC1,現在安卓不支持ETC2已不足5%,建議放棄分離通道辦法。 UI:盡可能將動態UI元素和靜態UI元素分離到不同的UIPanel中(UI的重建以UIPanel為單位),從而盡可能將因為變動的UI元素引起的重構控制在較小的範圍內; 盡可能讓動態UI元素按照同步性進行劃分,即運動頻率不同的UI元素盡可能分離放在不同的UIPanel中; 盡可能讓動態UI元素按照同步性進行劃分,即運動頻率不同的UI元素盡可能分離放在不同的UIPanel中; ugui:可以充分利用canvas來切分不同元素。 大貼圖會導致卡頓,可以切分為多個加載。 iOS使用mp3壓縮、Android使用Vorbis壓縮 5.批次 開啟static batch 開啟dynamic batch:要求模型小於900頂點,用法線小於300,用切線小於180,縮放不一致、使用lightmap、多通道材質等會使dynamic batch無效。 減少GameObject,場景模型數量對fps影響巨大。 批次不是越少越好,過大的渲染數據會給總線傳輸帶來壓力。 6.物理 不需要移動的物體設為Static 不要用Mesh碰撞,角色不用碰撞體 觸發器邏輯優化 尋路頻率、AI邏輯頻率、Fixed Timestep、降幀到30 出現卡頓的複雜計算,例如尋路、大量資源加載可以用分幀或者協成異步來處理 編輯於2017-04-01 |
Direct link: https://paste.plurk.com/show/05iRgIRvcvjYoWSsBCme