前言
unity引擎中渲染代價的指標(biāo)是場景中網(wǎng)格(Mesh)的數(shù)量,對顯卡來說渲染一個100面的物體和渲染一個1500面的物體幾乎是等價的,于是當(dāng)多個物體的材質(zhì)(Shader)相同時,可以把他們的網(wǎng)格合并起來,然后共用一個材料(Material)來降低渲染的成本,達成優(yōu)化游戲體驗的效果。
這里我們把對材料的共用模糊化了,其實這也是一個復(fù)雜的過程,后文中會詳細描述其原理和算法。
什么樣的物體可以合并?
場景中有那么多物體,在進行合并之前,我們需要先確定哪些物體是可以合并在一起的?
1.shader相同的物體才可以合并

觀察物體的屬性面板,我們發(fā)現(xiàn)物體可能有不同的材料,這些材料會有不同的shader。shader是也是使用編程語言編寫的由gpu處理的,不同的shader渲染出的效果是不一樣的。因為我們合并起來的物體的網(wǎng)格是一個合并的網(wǎng)格,使用的是合并的材料,每個材料只能有一個shader屬性,這也就限制了我們要合并的物體的材料的shader必須要相同。



2.要合并的物體需要處于一定范圍內(nèi)
多個物體合并了之后,成為一個物體,若這個物體的mesh分布在場景中的各個地方,無疑是對資源的一個浪費。極端地來說,若我們將一萬個物體合并成了一個,攝像機所看到了這一萬個之中的一個,其他九千九百九十九個雖然對玩家不可見,但因為是同一個物體,所以也渲染了出來,這樣的資源浪費是無必要的。
于是我們在合并之前會將場景劃分為多個正方體,每個正方體內(nèi)的物體才能互相合并在一起,以此避免合并出來物體的mesh分散的情況。
3.物體的光照貼圖需要相同(lightmapindex屬性相同)
一個很General的算法
變量的數(shù)據(jù)結(jié)構(gòu)及意義
在此處先將mesh合并整個過程的大體算法描述出來,細節(jié)部分在后篇展開解釋。
當(dāng)然在描述算法前,先說明算法中用到的變量的數(shù)據(jù)結(jié)構(gòu)及其意義:
List<MeshFilter> AllMeshFiltersInScene : 場景中所有meshfilter的鏈表
List<MeshRender>?AllMeshRenderersInScene?: 場景中所有meshrenderer的鏈表
List<GameObject> AllGameobjectsInScene?: 場景中所有Gameobject的鏈表
Dictionary<Shader, Dictionary<Texture2d, List<int>> ShaderToTextures? : 場景中所有的Shader到其貼圖的映射(在合并之前,所有貼圖都是貼在材料之上的,這些材料有自己的Shader,就視為這個貼圖的Shader。只有Shader相同的貼圖才能打包到一個圖集中,他們的mesh才能合并在一起)
List<List<Gameobjcet>> CubesOfGameobjects : 場景中的正方體數(shù)組,里面存著這個正方體里的物體
Dictionary<Gameobject, int> GameObjectToIndex : 建立物體到其索引的映射
算法
1.FindAllMeshesInScene : 找到場景中所有MeshFilter組件,存在AllMeshFiltersInScene,據(jù)其還可以獲得帶這個組件的物體存在AllGameobjectsInScene?以及這個物體的其他有用組件如MeshRenderer存在AllMeshRenderersInScene
2.PackAllTexturesInScene && DividingTextures: 將場景內(nèi)所有的貼圖打包成若干個圖集(圖集,即是貼圖的集合;如前所述,Mesh合并之后多個物體成為一個物體,這個物體使用的是一個合并的Mesh,合并的材料,這個合并的材料當(dāng)然就有一個合并的貼圖集合,即為圖集)
3.DoCombine : 遍歷場景內(nèi)的每個正方體,對其內(nèi)的物體進行合并條件判斷后,分組進行合并