前言
unity引擎中渲染代價(jià)的指標(biāo)是場(chǎng)景中網(wǎng)格(Mesh)的數(shù)量淮逻,對(duì)顯卡來(lái)說(shuō)渲染一個(gè)100面的物體和渲染一個(gè)1500面的物體幾乎是等價(jià)的,于是當(dāng)多個(gè)物體的材質(zhì)(Shader)相同時(shí),可以把他們的網(wǎng)格合并起來(lái)侵歇,然后共用一個(gè)材料(Material)來(lái)降低渲染的成本碍彭,達(dá)成優(yōu)化游戲體驗(yàn)的效果。
這里我們把對(duì)材料的共用模糊化了摸袁,其實(shí)這也是一個(gè)復(fù)雜的過(guò)程钥顽,后文中會(huì)詳細(xì)描述其原理和算法。
什么樣的物體可以合并靠汁?
場(chǎng)景中有那么多物體蜂大,在進(jìn)行合并之前闽铐,我們需要先確定哪些物體是可以合并在一起的?
1.shader相同的物體才可以合并
觀察物體的屬性面板奶浦,我們發(fā)現(xiàn)物體可能有不同的材料兄墅,這些材料會(huì)有不同的shader。shader是也是使用編程語(yǔ)言編寫(xiě)的由gpu處理的财喳,不同的shader渲染出的效果是不一樣的察迟。因?yàn)槲覀兒喜⑵饋?lái)的物體的網(wǎng)格是一個(gè)合并的網(wǎng)格,使用的是合并的材料耳高,每個(gè)材料只能有一個(gè)shader屬性扎瓶,這也就限制了我們要合并的物體的材料的shader必須要相同。
2.要合并的物體需要處于一定范圍內(nèi)
多個(gè)物體合并了之后泌枪,成為一個(gè)物體概荷,若這個(gè)物體的mesh分布在場(chǎng)景中的各個(gè)地方,無(wú)疑是對(duì)資源的一個(gè)浪費(fèi)碌燕。極端地來(lái)說(shuō)误证,若我們將一萬(wàn)個(gè)物體合并成了一個(gè),攝像機(jī)所看到了這一萬(wàn)個(gè)之中的一個(gè)修壕,其他九千九百九十九個(gè)雖然對(duì)玩家不可見(jiàn)愈捅,但因?yàn)槭峭粋€(gè)物體,所以也渲染了出來(lái)慈鸠,這樣的資源浪費(fèi)是無(wú)必要的蓝谨。
于是我們?cè)诤喜⒅皶?huì)將場(chǎng)景劃分為多個(gè)正方體,每個(gè)正方體內(nèi)的物體才能互相合并在一起青团,以此避免合并出來(lái)物體的mesh分散的情況譬巫。
3.物體的光照貼圖需要相同(lightmapindex屬性相同)
一個(gè)很General的算法
變量的數(shù)據(jù)結(jié)構(gòu)及意義
在此處先將mesh合并整個(gè)過(guò)程的大體算法描述出來(lái),細(xì)節(jié)部分在后篇展開(kāi)解釋督笆。
當(dāng)然在描述算法前芦昔,先說(shuō)明算法中用到的變量的數(shù)據(jù)結(jié)構(gòu)及其意義:
List<MeshFilter> AllMeshFiltersInScene : 場(chǎng)景中所有meshfilter的鏈表
List<MeshRender>?AllMeshRenderersInScene?: 場(chǎng)景中所有meshrenderer的鏈表
List<GameObject> AllGameobjectsInScene?: 場(chǎng)景中所有Gameobject的鏈表
Dictionary<Shader, Dictionary<Texture2d, List<int>> ShaderToTextures? : 場(chǎng)景中所有的Shader到其貼圖的映射(在合并之前,所有貼圖都是貼在材料之上的娃肿,這些材料有自己的Shader咕缎,就視為這個(gè)貼圖的Shader。只有Shader相同的貼圖才能打包到一個(gè)圖集中料扰,他們的mesh才能合并在一起)
List<List<Gameobjcet>> CubesOfGameobjects : 場(chǎng)景中的正方體數(shù)組锨阿,里面存著這個(gè)正方體里的物體
Dictionary<Gameobject, int> GameObjectToIndex : 建立物體到其索引的映射
算法
1.FindAllMeshesInScene : 找到場(chǎng)景中所有MeshFilter組件,存在AllMeshFiltersInScene记罚,據(jù)其還可以獲得帶這個(gè)組件的物體存在AllGameobjectsInScene?以及這個(gè)物體的其他有用組件如MeshRenderer存在AllMeshRenderersInScene
2.PackAllTexturesInScene && DividingTextures: 將場(chǎng)景內(nèi)所有的貼圖打包成若干個(gè)圖集(圖集,即是貼圖的集合壳嚎;如前所述桐智,Mesh合并之后多個(gè)物體成為一個(gè)物體末早,這個(gè)物體使用的是一個(gè)合并的Mesh,合并的材料说庭,這個(gè)合并的材料當(dāng)然就有一個(gè)合并的貼圖集合然磷,即為圖集)
3.DoCombine : 遍歷場(chǎng)景內(nèi)的每個(gè)正方體,對(duì)其內(nèi)的物體進(jìn)行合并條件判斷后刊驴,分組進(jìn)行合并