1. 程式人生 > >(整理總結)unity效能優化

(整理總結)unity效能優化

減少Draw call

Draw call就是cpu對圖形繪製介面的呼叫,CPU通過呼叫圖形庫(directx/opengl)介面,命令GPU進行渲染操作。

每一次繪製CPU都要呼叫DrawCall,呼叫DrawCall之前,CPU要進行很多準備工作:檢測渲染狀態,提交渲染所需要的資料,提交渲染所需要的結果,當DrawCall過多CPU會有很多額外的開銷用於準備工作,CPU負載,GPU限制。

解決方案:把小的DrawCall合併為一個大的DrawCall中,這就是批處理思想。

使用批處理的注意事項:

合併的網格會在一次渲染任務中進行繪製,他們的渲染資料,渲染狀態和shader都是一樣的,因此合併的條件至少是:同材質、同貼圖、同

shader。最好網格頂點格式也一致。

儘量避免使用大量小的網格,當確實需要時,考慮是否要合併。

避免使用過多的材質,儘量共享材質。

網格合併的頂點數量有上限(Unity中好像是65535

合併本身有消耗,因此儘量在編輯器下進行合併

確實需要在執行時合併的,將靜態的物體和動態的物體分開合併:靜態的合併一次就可以,動態的只要有物體發生變換就要重新合併。

unity選單欄window-profiler可以看專案性能資料:


二 資源優化

優化標準:

Mesh

動態模型:面片數材質數<3

骨骼數<50

靜態模型:定點數<500

長時間音樂(背景音樂)壓縮格式mp3

短時間音樂(音效)非壓縮格式wav(例如戰鬥音效,如果壓縮,攻擊一次就需要壓縮一次)

貼圖長寬<1025

Shader

減少複雜數學運算

減少discard操作

一貼圖優化:

二模型優化:

減少頂點數量

三減少冗餘資源和重複資源:

   1.Resources目錄下不管資源是否被使用都會被打包

   2.不同目錄下的相同資原始檔,如果被引用,那麼大寶都會打包進資源包

   3.保證同一個資原始檔在專案中只存放在一個目錄位置


相關文件:

三 渲染優化

一 LOD層級

   讓模型在視野的不同範圍內顯示不同精度的模型,距離越遠模型越粗糙,渲染越簡單。

   在屬性面板新增LOD Group元件,設定攝像機視野顯示的模型。


具體細節設定在Edit-projectsetting-QualitySetting

二 遮擋剔除

在攝像機視野範圍內的渲染顯示,不在範圍內的不渲染顯示

1. 全選要進行遮擋剔除的物體

2. 在static裡面選中OcclusionCulling Static屬性

3. 在Window-Occlusion Culling中設定烘焙,選擇目標攝像機

三 光照貼圖

把環境的光照效果提前計算好,生成一張光照貼圖,這樣以後就不需要再去實時渲染環境的光照效果

1.選擇環境,再static裡面選擇lightmap Static

2.在window-Lightting-setting設定烘焙

3.在資原始檔夾中會生成光照貼圖資訊,彩色的一個屬性圖示

四 網格合併

把多個物體合併成為一個大的物體,需要通過程式碼實現,把要合併的物體放到一個物體下面作為子物體:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshCombiner : MonoBehaviour {

	// Use this for initialization
	void Start () {
        MeshCombine();
	}
	
    void MeshCombine()
    {
        MeshFilter[] filters = GetComponentsInChildren<MeshFilter>();

        CombineInstance[] combiners = new CombineInstance[filters.Length];

        for(int i = 0; i < filters.Length; i++)
        {
            combiners[i].mesh = filters[i].sharedMesh;
            combiners[i].transform = filters[i].transform.localToWorldMatrix;
        }

        Mesh finalMesh = new Mesh();
        finalMesh.CombineMeshes(combiners);

        GetComponent<MeshFilter>().sharedMesh = finalMesh;
    }

四 其他優化

一  物件池    當有物體大量重複出現時可以使用物件池去優化,例如子彈,每此扣動扳機都要射出一發子彈,例項化一個子彈,太浪費效能,這時候就可以去使用物件池解決。 二 程式碼編寫

   1.儘量不要動態的instantiatedestroy object,使用object pool

   2.儘量不要再update函式中做複雜計算,如有需要,可以隔N幀(FixedUpdate)計算一次

   3.不要動態的產生字串,如Debug.Log("boo" + "hoo"),儘量預先建立好這些字串資源

   4.cache一些東西,在update裡面儘量避免search,如GameObject.FindWithTag("")GetComponent這樣的呼叫,可以在start中預先存起來

   5.儘量減少函式呼叫棧,用x = (x > 0 ? x : -x);代替x = Mathf.Abs(x)

三  其他優化博文