日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

unity3d 动态合批设置_Unity3D SkinnedMeshRenderer合批优化

發(fā)布時間:2025/3/12 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity3d 动态合批设置_Unity3D SkinnedMeshRenderer合批优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近做了性能優(yōu)化相關(guān)的工作,其中一些是關(guān)于戰(zhàn)斗模塊的渲染的。主要是對場景中使用的基于SkinnedMeshRenderer的網(wǎng)格進(jìn)行了一些合批優(yōu)化(降DC),記錄如下。項(xiàng)目使用的Unity版本為5.6.4p1。

游戲中的戰(zhàn)斗模塊是這樣的:戰(zhàn)斗邏輯由服務(wù)器承擔(dān),戰(zhàn)斗瞬間完成,將戰(zhàn)斗過程發(fā)給客戶端,客戶端負(fù)責(zé)播放;

場景中有敵我雙方最多12個方陣(雙方各2排3列),每個方陣由12個小兵組成(3排4列);

戰(zhàn)斗基于回合制,敵我各個方陣依次攻擊,攻擊時會出列,沖到目標(biāo)方陣前,攻擊完成后返回;

小兵使用的是帶動畫的3D模型,使用AnimationController控制動作;

每個方陣的小兵是完全一致的(含模型、貼圖、動作)

綜上,使用戰(zhàn)場管理器根據(jù)后端發(fā)來的戰(zhàn)斗數(shù)據(jù),改變各個方陣的position以及控制AnimationController來實(shí)現(xiàn)戰(zhàn)斗過程的播放。

戰(zhàn)斗模塊中的渲染部分,從最初的版本到目前的一個可接受的版本,總共經(jīng)歷了多次迭代,以下詳細(xì)記錄,本文中使用的截圖非項(xiàng)目截圖(單個模型面數(shù)小于項(xiàng)目中使用的面數(shù),此處使用的模型來自AssetStore,僅供演示使用)。本文的工程可以在github上看到所有源碼。

原始版本

每個方陣12個小兵,實(shí)實(shí)在在地放了12個SkinnedMeshRenderer(后邊簡稱為SMR),在方陣的腳本中保存了所有的AnimationController(后邊簡稱AC),當(dāng)方陣要移動時則移動所有的SMR,播放動畫時同時為所有AC設(shè)置狀態(tài)。

此方案每方陣共計(jì)12個SMR和12個AC。

兩輪迭代

迭代一:共享網(wǎng)格

每個方陣放1個帶SMR的小兵模型,每幀Bake網(wǎng)格,同時有12個MeshRenderer,其MeshFilter指向的Mesh即SMR每幀Bake出的Mesh??紤]到SMR的AC會控制SMR及父節(jié)點(diǎn)的運(yùn)動,保留了所有的AC,僅僅把實(shí)際用來展示的SMR換成了普通的MeshRenderer。

此方案每方陣共計(jì)1個SMR和12(或13)個AC,節(jié)省了一些骨骼動畫的計(jì)算。所有的MeshRenderer使用相同的網(wǎng)格和材質(zhì),但是由于單個模型頂點(diǎn)數(shù)的原因無法合批繪制。

迭代二:GPU Instancing

每個方陣1個帶SMR的小兵模型,每幀需要Bake,并將Bake的Mesh使用Graphics.DrawMeshInstanced在指定的位置繪制12份。這一操作需要系統(tǒng)支持GPU Instancing并且材質(zhì)(shader)也要支持。大概是在shader中增加以下的代碼。1#pragma multi_compile_instancing

在頂點(diǎn)著色器的輸入的結(jié)構(gòu)體中增加:1UNITY_VERTEX_INPUT_INSTANCE_ID

在頂點(diǎn)著色器函數(shù)中增加:1UNITY_SETUP_INSTANCE_ID(v);

其中v是頂點(diǎn)著色器的輸入。這里是本文中使用的支持Instancing的shader。

最后不要忘了將材質(zhì)是否支持GPU Instancing屬性設(shè)置為true。

此方案每方陣共計(jì)1個SMR和1個AC,但需要系統(tǒng)和材質(zhì)支持GPU Instancing。12個小兵只需一個DrawCall即可繪制出來。當(dāng)整個方陣移動時,需要手動更新這些Instancing的變換矩陣。

目前項(xiàng)目中使用了結(jié)合了迭代一和迭代二的方案,首先會根據(jù)系統(tǒng)和材質(zhì)是否支持GPU Instancing做出判斷,如果支持則使用迭代二的方案,否則使用迭代一的方案。

備選方案:GPU Instancing的共享網(wǎng)格

如果系統(tǒng)支持GPU Instancing且使用迭代二中支持GPU Instancing的材質(zhì),在使用迭代一共享網(wǎng)格方案時也可以合批(按照GPU Instancing處理,可以突破最大頂點(diǎn)數(shù)對合批的限制)。

與迭代二相比,這種備選方案不需要計(jì)算Instance繪制時的變換矩陣,但是卻依賴AC來控制各小兵中SMR及其父級節(jié)點(diǎn)的變換。

方案匯總

在一臺支持GPU Instancing的機(jī)器上對比四種方案如下:方案A方案B方案C方案D原始版本迭代一迭代二備選方案

以下依次是方案ABCD場景statistics:

方案A:

方案B:

方案C:

方案D:

可以看到基本上方案A和方案B是同一個level的,方案C和方案D是同一個level,FPS由于一直波動所以截取到的數(shù)值只能表現(xiàn)出大概的趨勢。

下邊依次是方案ABCD繪制Frame截圖(使用FrameDebugger截取):

方案A:

方案B:

方案C:

方案D:

可以看到,方案B中因?yàn)槌?00頂點(diǎn)這一限制所以無法合批,但是修改材質(zhì)之后(方案D),支持GPU Instancing,不再受此限制的約束。

包含以上四個方案的項(xiàng)目工程都放在github。

一些彎路

除了前邊的一些方案之外,還曾經(jīng)走過一些彎路。在使用基于共享網(wǎng)格的迭代一方案時,發(fā)現(xiàn)會因?yàn)轫旤c(diǎn)數(shù)量超出限制而導(dǎo)致網(wǎng)格和材質(zhì)都相同的多次繪制無法合批。就想到使用Mesh.Combine來合并網(wǎng)格,初始化時合并一次并在每幀更新頂點(diǎn)和變換矩陣,或者每幀合并。

使用這種方案,確實(shí)可以合批降低DC,但是大大增加了CPU的計(jì)算負(fù)荷,相比之下整體性能降低,在移動平臺上FPS不升反降。于是拋棄了此方案。

其它思路

另外有一些思路,做了一些簡單嘗試,但是未落實(shí)成具體方案:

實(shí)時三渲二

使用另外的相機(jī)將小兵模型繪制到RenderTexture,然后將此RT作為紋理,在場景中使用12個2D的Sprite來顯示。

目前項(xiàng)目中使用的是正交相機(jī)且固定相機(jī)位置,此方案是可行的。但是后期需求變化可能會替換為透視相機(jī)且相機(jī)允許轉(zhuǎn)動,每個小兵呈現(xiàn)出的2D圖像不同,這一方案將失效。

拋開無法滿足未來需求這一點(diǎn),還有其它的一些因素需要考慮,這種繪制方式可能增加額外的性能開銷,如多了一個相機(jī)和RT,各個Sprite的空間位置關(guān)系、繪制層級控制,小兵與HUD的繪制層級控制等。

幾何著色器

在shader中增加幾何著色器(Geometry shader),以控制將一個模型的頂點(diǎn)(三角形)繪制出更多份。由于項(xiàng)目最終是部署到Android和iOS平臺,所以很快放棄了這一思路。

如果將來會有PC或者主機(jī)平臺的項(xiàng)目,或許可以嘗試。將原來的坐標(biāo)轉(zhuǎn)換(MVP矩陣變換)的工作從頂點(diǎn)著色器中移出,放入幾何著色器。并且?guī)缀沃髦袑⑤斎氲捻旤c(diǎn)(三角形)繪制多份,最終送達(dá)片段著色器一并繪制。由于對于Unity及圖形學(xué)的研究尚淺,不知這種方案是否可以實(shí)現(xiàn),如果真的可以實(shí)現(xiàn),也不了解這種方法是否會帶來更大的性能開銷,待后續(xù)有時間再研究研究這個。

Animation Instancing

最后一個方案是Animation Instancing,這種方法是在網(wǎng)上看到的(鏈接),由于與項(xiàng)目中的需求有些差異,并且時間關(guān)系也沒有去做更多的探索。這種方案可以針對更高要求的SMR合批繪制,不限制各個SMR必須有相同的動作。預(yù)先生成動畫保存到紋理中,然后運(yùn)行時讀取紋理來播放動畫,大幅降低了CPU的負(fù)載(提升了少量GPU的負(fù)荷和內(nèi)存占用),整體的渲染性能大大提升。但是目前無法支持動畫狀態(tài)切換,不過作者表示很快會支持這一功能。

REFERENCE

總結(jié)

以上是生活随笔為你收集整理的unity3d 动态合批设置_Unity3D SkinnedMeshRenderer合批优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。