《球球大作战》游戏优化之路(下)
演講內容
大家好,我叫徐宇峰,負責《球球大作戰》的性能優化。
《球球大作戰》現在擁有五億多的玩家,為了吸引如此龐大的玩家群體,我們提供給玩家更炫更酷的皮膚,這些美輪美奐的皮膚,讓《球球大作戰》的游戲畫面更加絢麗多彩,但隨著皮膚日益精致,性能問題開始日益突出。
?
我們的皮膚正面看起來很簡單,從側面看,皮膚由精美模型與很多特效層組合而成。
皮膚的材質大部分為半透明。大量的半透明材質無法合批渲染,導致單套皮膚Draw Calls達到82個,面數1.1萬以及骨骼40個。
?
《球球大作戰》最核心技能就是分身吃球,而當玩家分身之后,Draw Calls更是暴漲,游戲中玩家最大16分身時,Draw Calls有820多,面數達17.7萬。
?
在實際游戲中,多玩家多皮膚分身后,Draw Calls經常能輕松過千,下面視頻是我們內部的極限測試版情況。
大家能看到,Draw Calls最低有400-500,最高達到2000多,如此高的Draw Calls導致游戲的幀率急劇下降,卡頓嚴重。而球球作為一款競技游戲,性能與體驗至關重要。
?
我們團隊采用各種優化方法:
?
- 模型貼圖合并:模型與貼圖盡可能的合并在一起,利用Unity的動態合批渲染,減少Draw Calls。
- 減少半透明材質:半透明會帶來融合運算,其次重疊的半透明物體無法合批渲染,導致Draw Calls增加。
- 減少粒子系統:粒子會增加CPU運算,還會增加Draw Calls,每套皮膚的粒子數量我們控制在40個以內.
- LOD系統
- 降低分辨率:皮膚的貼圖普遍采用512k,部分貼圖在低端機器上降低到256k。
?
我們來看看優化對比。
下面視頻是一個LOD系統的效果對比,左邊是高性能機型高畫質,右邊是低端機型流暢畫質。左右相互對比可以看到,右邊的皮膚少了些特效與動畫,貼圖分辨率也相應降低。
通過以上優化,游戲性能大約提升52%,但畫面品質同樣遭受損失,在中低端機器上尤為明顯,這點很容易引起玩家的不滿。
美術團隊也希望所有機型,畫面盡可能的完美,并且過少Draw Calls極大限制了美術的高水平發揮。
?
《球球大作戰》優化的難點是皮膚分身后Draw Calls暴漲的問題。
我們想到用RenderTexture來降低Draw Calls峰值,但皮膚有太多半透明,渲染管線中對于透明相關的處理是在管線后期進行的。由于不同物體是按照順序渲染的,對透明的處理方式是混合,實際上就是shader輸出顏色與此像素位置已有顏色的合并過程。
下圖中的混合公式是Unity中最標準的混融模式Blend SrcAlpha OneMinusSrcAlpha。
?
假設將Camera背景的顏色設置為全黑色(0001)或全白色(1111),分別進行渲染,渲染后的顏色分別為Cblack、Cwhite,得到公式1和2。公式中藍色為已知數,紫色為未知數,2個公式可以求出2個未知數。
具體代碼請參考:
下面看看具體制作流程。
?
我們把原資源用單相機渲染到RenderTexture,相機每幀切換黑白背景,形成連續序列幀,這是因為單個相機能節省更多的Draw Calls,但如果動畫速度過快,就必須使用雙相機保證品質。
RT經過GPU做算法剔除,輸出到多張RenderTexture。RT我們采用512分辨率,一共40張,格式為ARGBHalf,真機占用內存約為20兆,目前市面上主流手機內存大部分為2G以上,所以內存很充足。具體用到那種分辨率與RT數量的多少,需要根據不同機型做適當調整。
?
多張帶RT的RenderTexture組成一套序列幀,利用Plane切換RT做成序列幀動畫。序列幀會循環渲染,從RT1渲染到40,再回到第1張。
Plane讀取RT時也是循環讀取,最后序列幀動畫放到場景中與半透明背景,半透明皮膚以及UI等進行融合。
下面我們來看看原資源與RT資源的實時效果對比。這是原素材與RenderTexture的實時效果對比,原素材由十幾層特效疊加,而RenderTexture只有單個面。
大家看看不同資源的效果對比,新技術首先必須保證美術品質才能投入使用。
?
在美術品質保證后,再看看優化前后Draw Calls對比。
當分身不斷增加時,Draw Calls以線性增長,大家可以看看下面的Draw Calls圖表,從最開始63暴漲至900多。
在RT模式下,分身的增加帶來Draw Calls的個位數增加,同時可以看到在RT模式下,因為我們利用多張RenderTexture,每個分身的動畫幀是錯開的,動畫并不完全一樣。
?
1
我們再看看真機數據對比,測試平臺為普通千元機。
如下圖所示,左圖分身數從1至16,普通模式Draw Calls從63暴漲至917,翻了14.5倍,每一次分身數量的翻倍都讓Draw Calls劇烈變化。而RT模式從64到83只增加19個。
有圖CPU消耗圖,在RT模式下,CPU的消耗非常平穩,而普通模式最大分身時消耗已經翻倍。
?
再來看看FPS與內存消耗。
如下圖所示,手機號碼幀率在普通模式下,16分身幀率已經降低到25,加上UI與其它邏輯消耗,已經產生游戲卡頓。而RT模式幀率非常平穩。
內存方面因為RT用了40張16位的512貼圖,內存大約多20MB,這是RT模式唯一消耗點。實際應用中我們會根據機器的內存容量,控制RT的數量與分辨率。
《球球大作戰》同屏有上千物體,每幀數千個物體的位置、大小、動畫、網絡數據等伴隨著產生大量邏輯運算。
主要邏輯有:
?
- 利用插值函數使物體的移動更加平滑。
- 玩家吃球后重量會增加:根據重量來計算球的尺寸與前后位置,尺寸越大物體越靠近攝像機。
- AI狀態機:玩家根據游戲狀態,如二個玩家距離接近時,會播放調侃動畫,吃掉其他玩家時播放炫耀動畫;
- 相機視野計算:玩家所有球的數量與尺寸變化,都伴隨著相機位置與FOV調整,每個分身必須在相機視野內,最大分身盡可能處于屏幕中心;
- 其它邏輯:還有網絡數據解壓縮、解密、背景迷霧、UI運算等。
以上這么多的實時運算量會對CPU產生巨大壓力。
?
我們利用Unity 2018的ECS系統,把所有邏輯做分類,純邏輯運算做成PureECS,其他部分做成HybridECS。數千物體的邏輯運算,盡可能分配到多個核心。
這極大的提升游戲性能,并且更快更復雜的運算讓物體的移動、旋轉更加平滑和細膩,增強游戲的用戶體驗。
?
上述的優化方法,部分處于《球球大作戰》的試用階段,我們一直都在不斷嘗試和創新,使用各種優化方式,讓《球球大作戰》擁有更好的用戶體驗,并不斷煥發新的活力!
我的演講到此結束,謝謝大家。
總結
以上是生活随笔為你收集整理的《球球大作战》游戏优化之路(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《球球大作战》游戏优化之路(上)
- 下一篇: 用Unity盖房子(一):《勇者斗恶龙: