《球球大作戰》優化之路(下)

遊資網發表於2019-06-04
上一篇我們分享了《球球大作戰》優化之路客戶端主程王國禕部分,本文將繼續由資深技術徐宇峰講述後期遊戲製作中的優化方式。

《球球大作戰》優化之路(下)

演講內容

大家好,我叫徐宇峰,負責《球球大作戰》的效能優化。

《球球大作戰》現在擁有五億多的玩家,為了吸引如此龐大的玩家群體,我們提供給玩家更炫更酷的皮膚,這些美輪美奐的皮膚,讓《球球大作戰》的遊戲畫面更加絢麗多彩,但隨著皮膚日益精緻,效能問題開始日益突出。

《球球大作戰》優化之路(下)

我們的皮膚正面看起來很簡單,從側面看,皮膚由精美模型與很多特效層組合而成。

皮膚的材質大部分為半透明。大量的半透明材質無法合批渲染,導致單套皮膚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個未知數。

具體程式碼請參考:

http://wiki.unity3d.com/index.php/AnimationToPNG

下面看看具體制作流程。

《球球大作戰》優化之路(下)

我們把原資源用單相機渲染到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。數千物體的邏輯運算,儘可能分配到多個核心。

這極大的提升遊戲效能,並且更快更復雜的運算讓物體的移動、旋轉更加平滑和細膩,增強遊戲的使用者體驗。

《球球大作戰》優化之路(下)

上述的優化方法,部分處於《球球大作戰》的試用階段,我們一直都在不斷嘗試和創新,使用各種優化方式,讓《球球大作戰》擁有更好的使用者體驗,並不斷煥發新的活力!

我的演講到此結束,謝謝大家。

作者:徐宇fen  
原地址:Unity官方平臺

相關文章