unity性能優化。貼圖、模型、shader、光照、編碼、 cup、gpu、內存、shader 性能優化相關

優化,老生常談。遊戲的優化和網站、軟件優化沒有任何不同,除了編碼質量和使用技巧以外,都是那些空間<>時間、效果<>性能的老套路。

Debug工具介紹

Statistics
Profile

內存優化

【適當的GC(Garbage Collection垃圾回收)】

GC有兩種觸發方式,1內存不足自動觸發,2手動觸發。
首先內存不足時自動GC,經反覆測試,並不是很好的辦法。因爲當內存不足時cpu壓力也比較大,在GC之前就已經會發生卡頓現象,GC時還會發生更嚴重的卡頓。最好的辦法還是手動GC。但一定要設計好觸發條件。因爲過於頻繁的GC也很影響性能。

函數相關的優化

【使用for循環,減少foreach】

foreach會涉及到迭代器的使用,而據傳每次循環所產生的迭代器會帶來24 Bytes的垃圾。

【不直接訪問gameobject的tag屬性】

比如if (object.tag == “target”)最好換成if (object.CompareTag (“target”))。因爲訪問物體的tag屬性會在堆上額外的分配空間。

【使用對象池,實現對象的複用】

將場景中的對象放在池中調用,節省反覆實例化的開銷

*【減少GetComponent方法調用組件】

腳本中三種調用Transform組件的方式,其響應時間有着巨大的不同,按時間的相應毫秒數大小排列的話是這個樣子:GetComponen > transform= 60ms >myTransformCache
所以應該建立組件的引用留作複用,而不是每次都使用GetComponent。

*【只運行物體在攝像機視野內的腳本】

使用void OnBecameVisible()和void OnBecameVisible()減少攝像機事業外腳本運行的開銷。這兩個函數分別是 當前物體在攝像機範圍內或離開攝像機範圍觸發。

【儘量使用內建值,減少new的開銷】

使用數組內建值,比如Vector3.zero而不是new Vector(0, 0, 0)。

【位置、旋轉、縮放的數值要使用低精度】

設置位置旋轉和縮放的時,不要使用高精度的變換。否則會產生模型抖動的問題。

貼圖、材質優化

【紋理尺寸最好2的整數幕】
【使用紋理圖集】

類似前端的雪碧圖。用一張包含了很多子貼圖的大貼圖,來代替一系列單獨的小貼圖。可以提高加載效率,並且更易於批量處理。
需要使用Renderer.sharedMaterial 代替Renderer.material

【減少透明物體的使用】

由於透明沒有開啓深度寫入所以會造成overdraw。

【使用共享材質】

共享材質可以減少材質數量,便於批量處理。
需要使用Renderer.sharedMaterial 代替Renderer.material

【壓縮紋理】

unity統合了紋理壓縮的方法。只需按質量等級選擇好即可。不過越高的壓縮質量,畫質越不好。GUI最好不要壓縮,質量影響很明顯。
【用法&步驟】
點擊貼圖文件 -> Inspector -> Default -> Compression 選擇壓縮質量

*【使用多級漸遠紋理MipMap】

類似模型LOD技術,逐級生成多個低精度貼圖,在適當的情況使用適當的貼圖。缺點是會增加內存佔用,典型的空間換時間優化。
【操作步驟】
點擊貼圖文件 -> Generate Mip Map -> Apply。
這時點擊Sprite Editor打開窗口,拖拽右上角的拉桿就能看到結果了。

光照優化

*【減少實時光照,使用光照紋理烘焙,或燈光探針】

如果物體使用了多個Pass 的Shader,使用實時光照很有可能會造成性能下降。這是因爲實時光照會產生更多的計算量,而且還無法使用動態批處理和靜態批處理。
1 使用光照紋理烘焙技術(GI、bake),把光照提前烘焙到一張光照紋理(lightmap ),運行時映射相應的紋理實現光照效果 。這樣不僅性能更好而且效果也更好。但缺點是物體必須設置爲靜態。對於需要移動的物體來說就不太合適。
2 這個時候使用燈光探針(Light Probe Group)是比較好的辦法
3如果一定要使用更多的實時光,也可以選擇用逐頂點光照來代替。

【減少實時陰影】

使用烘焙把靜態物體的陰影信息存儲到光照紋理中,只對動態物體使用適當的實時陰影。

模型優化

【儘可能移除隱藏的面】

這會減少頂點和三角面的處理。比如我們的相機在陽臺,附近高樓林立。那麼實際上只有前面幾個樓需要前、左、右的面。遠處的樓是不需要左或、右的面。因爲看不到。

【合併mesh】

網格合併,材質合併,優化批處理

【減少頂點】

建模時應儘量減少模型的頂點。根據動態、靜態批處理的觸發相關規則,簡單着色器模型頂點數必須小於900。如果着色器同時使用頂點位置、法線、UV值三種屬性則模型頂點數必須小於300。如果着色器同時使用頂點位置、法線、UV0、UV1、切向量五種屬性則模型頂點數必須小於180。

*【減少模型縮放(Scale)】

模型縮放會導致創建新的Batch。不利於動態、靜態批處理

【不使用mesh collider】

儘量使用cube collider 等內置colliser。性能會提高很多

*【使用模型的LOD (Level ofDetail )】

使用模型的多級細節技術,在不同的距離使用不同精度的模型、材質。提升cpu、gpu型能,加重內存負擔。典型的空間換時間優化技術。

*【使用遮擋剔除( Occlusion Culling )】
*【使用動態批處理(Baches,Saved by batching)】

【使用條件&步驟】

  1. 場景中存在多個相同模型。如果不是多個相同模型,則批處理無意義。
  2. 模型頂點數必須小於900。
  3. 如果着色器同時使用頂點位置、法線、UV值三種屬性則模型頂點數必須小於300。如果着色器同時使用頂點位置、法線、UV0、UV1、切向量五種屬性則模型頂點數必須小於180。
  4. 不能進行縮放 Scale。每次調整模型的大小都會產生新的Batch。
  5. 不能修改材質。每次修改材質都會纏身新的Batch。
  6. 不能使用lightmap(烘焙光照貼圖),除非是先烘焙,後實例化物體。
  7. 多通道的shader會妨礙批處理操作。比如,幾乎unity中所有的着色器在前向渲染中都支持多個光源,併爲它們有效地開闢多個通道
*【使用靜態批處理】

【使用條件&步驟】
點擊目標物體,在Inspector窗口勾選Static。
要注意靜態批處理不允許改變位置

shader相關優化

【內置shader使用mobile中的】

相比較其他內置shader,mobile性能更好

【儘量把計算放在對象或逐頂點着色器中】

優化對象數量 > 頂點運算 > 像素運算。
儘量不要把運算拖在片源元色器中計算。

【使用更低精度的值類型進行運算】

1 float 計算速度最慢,適合存儲頂點座標,在頂點着色器中使用。
2 half 計算速度快些,適用紋理座標等變量。
3 fixed 計算速度最快,適用於顏色變量和歸一化後的方向矢量,適合在片元着色器中使用。

【使用shader的lod技術】

與模型的 LOD 技術類似, Shader的LOD技術可以根據條件啓用shader片段,當Shader 的 LOD 值滿足條件設纔會渲染。

【根據硬件性能和平臺,調整效果方案】

根據不同的硬件性能,選擇性的啓用特效。

【儘量不要關閉深度測試】

由於被遮擋的物體無法通過深度測試,就不會再進行後面的渲染處理。

*【控制繪製順序隊列】

從前往後繪製,比從後往前繪製性能好的多。這是因爲深度測試的存在減少了被遮擋部分的繪製。
【從前往後繪製的隊列 - 不透明物體(Opaque)】
Shader中渲染隊列值小於2500的對象都被認爲是不透明(Opaque)的物體。如“Background"、“Geometry”、“Alpha Test”。
【從後往前繪製的隊列 - 透明物體(Transparent)】
Shader中渲染隊列值大於2500的對象都被認爲是透明(Transparent)物體。如"Transparent"、"Overlay"等
儘可能地把物體的染隊列值設置大於2500從而實現從前向後的渲染提升性能。

其他優化

【打包壓縮】

Build settings -> compression Method中設置壓縮

*【攝像機視錐剔除( Occlusion culling)】

剔除掉那些不在攝像機的視野範圍內的對象,從而避免不必要的計算。
【用法&步驟】
點擊攝像機 -> Inspector窗口 -> Camera組件 -> 勾選Occlusion Culling。

*【遮擋剔除技術( Occlusion culling)】

剔除掉那些被其他物體遮擋的看不到的物體,從而提升性能。
【用法&步驟】
unity工具欄 -> Windows -> Rending -> Occlusion culling -> Occlusion窗口 -> 作相關設置 -> Bake

後期效果優化插件Process

指定特效作用範圍,不要設置ervay thing。這是因爲比如GUI之類的東西沒有必要被計算。

【gui和場景使用不同的攝像機渲染】

GUI由於其特殊性大多需要設置成透明。如果GUI與場景物體一同西漢時,並且屏幕佔比太多,就會造成很多不必要的overdraw。
可以用兩個相機分別渲染ui和場景。

*【減小分辨率】

降低屏幕分辨率是 非常有效 的性能優化手段。尤其對於大屏幕低配置的設備。這時可以使用等比例縮小屏幕分辨率的方法來適當優化。用部分效果來換取性能山的提升
【用法&步驟】

///這裏作等比例運算,適配過長或過寬的設備
{
	//獲取當前分辨率
	int width = Screen.currentResolution.width;
	int height = Screen.currentResolution.height;
}
///
//設置當前分辨率
Screen.SetResolution(640, 480,true);
重複渲染物體的優化

對咯對咯忘記renderBuffer了
這個東東在渲染重複圖形的時候會有高額的性能提升。基本原理就是將某一模型存入buffer,在目標位置重複調用渲染該buffer。比如地上的草。可以設置以人爲中心,不斷重複渲染預置範圍內的草顯示。 一個比較有名的例子就是和平精英手遊。當你趴在草中的時候你會草遮擋,但遠處的人看你的時候,你就是趴在光禿禿的地上。有人誤認爲是lod技術,那是不對的。這個就是renderbuffer的典型應用。

unity官方移動平臺優化文檔
unity性能優化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章