【3.x合批親測(cè)】使用這個(gè)優(yōu)化方案,iPhone6也能飛起來(lái),直接拉滿60幀!

大家好,我是曉衡!

上周我花了3天的時(shí)間,體驗(yàn)測(cè)試了一款 Creator 3.x 性能優(yōu)化工具:98K動(dòng)態(tài)分層合批

它能將 DrawCall 超過(guò) 1000+ 次的 2D 界面,實(shí)現(xiàn)運(yùn)行時(shí)節(jié)點(diǎn)分層排序,利用引擎動(dòng)態(tài)合圖 + 批量渲染能力,從底層將 DrawCall 優(yōu)化到個(gè)數(shù)位。

測(cè)試案例是一個(gè) 2D 背包界面,我在 ScrollView 中動(dòng)態(tài)創(chuàng)建了 500 個(gè) item 元素。你可以看到,開啟合批優(yōu)化后 DrawCall 從 1016 直接降到了 8,游戲幀率也從 5 幀直接拉滿到 60 幀。

這里是H5測(cè)試體驗(yàn)鏈接,你也可以試一下:

98K動(dòng)態(tài)分層合批 支持H5、小游戲、原生等多個(gè)平臺(tái),而我的測(cè)試目標(biāo)是,觀察對(duì)比在不同平臺(tái)環(huán)境上,使用 98K 優(yōu)化前后的性能表現(xiàn)差異。

01 合批優(yōu)化測(cè)試對(duì)比

先給出我的測(cè)試結(jié)果,一共測(cè)試了 7 個(gè)環(huán)境:

  1. Mac M1 Chrome 桌面瀏覽器
  1. realme X50 Pro Android 原生

  1. realme X50 Pro Android 微信小游戲
  1. OPPO R11s Plus Android 原生
  1. OPPO R11s Plus Android 微信小游戲
  1. iPhone11 微信小游戲
  1. iPhone7 微信瀏覽器

以上測(cè)試環(huán)境數(shù)據(jù),我整理了個(gè)表格,方便大家對(duì)比優(yōu)化關(guān)后的效果:

如果你覺得看數(shù)據(jù)表還是很費(fèi)勁的話,可以直接看曉衡這個(gè)結(jié)論:

  1. 開啟合批優(yōu)化后,所有平臺(tái)都能跑到 60 幀,ScrollView列表滑動(dòng)流暢;
  2. 除減少 DrawCall 外,還啟了渲染剔除,降低了渲染面數(shù);
  3. 優(yōu)化前后差異對(duì)比是:桌面 > 低端原生 > 低端小游戲 > 中高端原生&小游戲。

桌面瀏覽器上的優(yōu)化性能最佳,這是我萬(wàn)萬(wàn)沒想到的,不論是 Mac 還是 Windows 系統(tǒng),都是如此。未合批前僅僅只有 5 幀,在列表上滑動(dòng),非常卡頓,基本上無(wú)法使用。開啟合批后,直接拉滿到60幀,列表滑動(dòng)流暢。

其次是在 iPhone 上,小游戲上的優(yōu)化比瀏覽器要好,未合批前不到 30 幀,開啟合批后滿幀 60,列表滑動(dòng)也更順滑。

然后是在 Android 手機(jī)上,中高機(jī)型未合批前就能達(dá)到 50 ~ 60 幀,優(yōu)化后提升不到 10 幀的樣子,不看調(diào)試數(shù)值感覺不明顯。低端機(jī)型的優(yōu)化效果不錯(cuò),有 20 ~ 30 幀的提升,硬件性能越低優(yōu)化后的效果越好。

最后,我在多說(shuō)一點(diǎn),就是在 iPhone 和 Android 低配機(jī)型上,原生性能要低于H5和小游戲,優(yōu)化效果會(huì)好。下面是我構(gòu)建的 APK 安裝包,感興趣的伙伴可以來(lái)體驗(yàn)一下:

- 鏈接: https://pan.baidu.com/s/12aEvOL9fQrpyB4Xs--OALg?pwd=4znt 提取碼: 4znt 

測(cè)試數(shù)據(jù)和結(jié)論有了,我們?cè)偕钊胍稽c(diǎn),98K動(dòng)態(tài)分層合批的核心是對(duì) DrawCall 的優(yōu)化,初學(xué)游戲開發(fā)的小伙伴,可能會(huì)有疑問:

DrawCall 是什么?為什么減少 DrawCall 能提升游戲的性能?合批又是個(gè)什么鬼?

而有過(guò)游戲開發(fā)經(jīng)驗(yàn),又愛思考的老鐵多半會(huì)問:

道具背包這類應(yīng)用場(chǎng)景,一個(gè) item 混合有復(fù)雜的圖片、文字,98K是如何避免 DrawCall 被打斷的?

下面我就來(lái)嘗試一下,能否將上面幾個(gè)問題說(shuō)清楚,你可以更加清楚知道是否適合在自己的項(xiàng)目中使用98K合批優(yōu)化。

02 理解Drawcall與合批

DrawCall 是什么?

  • 簡(jiǎn)單來(lái)講 CPU 準(zhǔn)備好渲染數(shù)據(jù),提交給 GPU 進(jìn)行繪制的這個(gè)過(guò)程就是一次 DrawCall

為什么減少 DrawCall 能提升游戲的性能?

  • GPU 渲染圖像的速度非常非常快;
  • CPU 的內(nèi)存\顯存讀寫、數(shù)據(jù)處理和渲染狀態(tài)切換,相比 GPU 非常非常慢;
  • 大量的 DrawCall 會(huì)讓 CPU 忙到焦頭爛額,而 GPU 大部分時(shí)間都在摸魚

因此,盡可能一次性將更多的渲染數(shù)據(jù)提交給 GPU,減少 CPU 的工作時(shí)間,從而提升游戲性能。

什么是合批?

  • 簡(jiǎn)單來(lái)說(shuō),組織更多渲染數(shù)據(jù)提交給 GPU 的過(guò)程,稱之為“批量渲染”簡(jiǎn)稱“合批”
  • 但要實(shí)現(xiàn)合批的前提是:渲染數(shù)據(jù)必須一致

更多關(guān)于 DrawCall 優(yōu)化的理解,可以閱讀陳皮皮的這篇文章:Cocos Creator 性能優(yōu)化:DrawCall

舉個(gè)例子

比如像下面這樣的節(jié)點(diǎn)樹結(jié)構(gòu),就無(wú)法實(shí)現(xiàn)合批:

因?yàn)?item 節(jié)點(diǎn)下的 Sprite 與 Label 節(jié)點(diǎn)渲染類型不同,并相互間隔排列,引擎無(wú)法向 GPU 批量提交渲染數(shù)據(jù)。

因此渲染一個(gè) item 需要 DrawCall 4次:Sprite → Label → Sprite → Label。

我們調(diào)整一下 item 下的節(jié)點(diǎn)順序,像下面這樣:

試試你能計(jì)算出上圖中的 DrawCall 值嗎?在 Creator 引擎中預(yù)覽運(yùn)行游戲,在畫面左下角,你會(huì)看到 DrawCall 的值顯示為 3。

細(xì)心的你這時(shí)可能會(huì)問:為什么 DrawCall 是 3 而不是 2 呢?

不用懷疑,你計(jì)算的 DrawCall 為 2 是正確的,因?yàn)橐孢@里會(huì)占用一次 DrawCcall,具體為什么,我們后面來(lái)說(shuō)原因,你也可以思考一下!

03 98K是如何避免 DrawCall 被打斷?

要想避免 DrawCall 被打斷,首先要理解什么是 DrawCall 打斷!

通過(guò)上面的舉例,不知道你沒有點(diǎn)感覺了。我們?cè)賮?lái)看多個(gè) item 節(jié)點(diǎn)樹 DrawCall 情況又會(huì)是怎么樣的呢?

在層級(jí)管理器中,我們?cè)購(gòu)?fù)制一顆 item 節(jié)點(diǎn)樹出來(lái),見下圖所示:

從上圖可以看出,兩顆 item 節(jié)點(diǎn)樹時(shí)又出現(xiàn):item1(Sprite → Label) → item2(Sprite → Label) 交替的情況,合批就這樣被打斷了。

聰明的我立馬會(huì)想到,將所有 item 下的節(jié)點(diǎn)合并不就好了,像下圖這樣:

效果是不是很好?6 個(gè)節(jié)點(diǎn)只有 2 次 DrawCall !就這樣干?

有經(jīng)驗(yàn)的你問題又來(lái)了,我們的邏輯代碼通常是以單個(gè) item 為單位建立的對(duì)象,如果將類型節(jié)點(diǎn)點(diǎn)合并到一起,上層邏輯代碼豈不是要亂成一鍋粥?

優(yōu)化的方法是知道了,但代價(jià)太大,不知道如何下手!

這個(gè)問題一直困擾我多年,一直沒找到可行的解決方案,直到遇到98K動(dòng)態(tài)合批的開發(fā)者。

這里不得不說(shuō)下 98K動(dòng)態(tài)合批 的強(qiáng)悍,就在于它可以讓你無(wú)視 item 子節(jié)點(diǎn)順序和層級(jí)關(guān)系,只需要在上層容器節(jié)點(diǎn)上添加 BatchItems 組件,最大程度上保證合批不被中斷,實(shí)現(xiàn)該節(jié)點(diǎn)樹的渲染優(yōu)化。

其代碼實(shí)現(xiàn)原理是:

  1. 攔截引擎渲染開始事件,對(duì)節(jié)點(diǎn)樹下的所有子節(jié)點(diǎn)按類型重新分層排序;
  2. 攔截引擎渲染結(jié)束事件,立即還原渲染前的節(jié)點(diǎn)樹排序,從而實(shí)現(xiàn)無(wú)入侵式的合批優(yōu)化
  3. BatchItem組件唯一的 Culling 屬性是可選的,它會(huì)拿 Culling 屬性所指定的矩形區(qū),與容器中 item 矩形做相交測(cè)試,將不在 Culling 區(qū)的元素從渲染隊(duì)列中剔除掉

05 應(yīng)用場(chǎng)景

需要注意的是98K合批優(yōu)化,僅適用于 2D UI 界面的優(yōu)化,特別是具有大量重復(fù)結(jié)構(gòu)的 item 場(chǎng)景如:背包系統(tǒng)、滑動(dòng)列表、技能欄、聊天界面等,以下應(yīng)用場(chǎng)景供大家參考。

背包系統(tǒng)

頻道列表

游戲排行榜

聊天界面

04 注意事項(xiàng)

我在使用 98K編寫前面那個(gè)背包測(cè)試工程時(shí),踩到幾個(gè)坑有幾點(diǎn)需要注意:

  • item 下子節(jié)點(diǎn)名字不能重復(fù)需保持唯一性

  • 多個(gè)同結(jié)構(gòu)的 item 子節(jié)點(diǎn)名字需要保持一致

  • 節(jié)點(diǎn)的 Layer 屬性需保持相同,建議統(tǒng)一為 UI_2D

  • 需要手動(dòng)開啟引擎的動(dòng)態(tài)合圖和關(guān)閉清除圖片緩存開關(guān)

    dynamicAtlasManager.enabled = true;
    macro.CLEANUP_IMAGE_CACHE = false;
    
  • 充分使用引擎的動(dòng)態(tài)合圖,將盡量多的圖片合并,需要增大項(xiàng)目設(shè)置中 BATCHER2D_MEM_INCREMENT 宏的參數(shù)值

06 結(jié)語(yǔ)

最后,我再小結(jié)一下 98K動(dòng)態(tài)分層合批 的整體感受!

它是非常適用于像背包系統(tǒng)、滑動(dòng)列表、聊天消息這類 2D UI 場(chǎng)景。

如果因游戲中因節(jié)點(diǎn)太多導(dǎo)致圖文分層原因,打斷合批造成 DrawCall 劇增影響性能和增加發(fā)熱問題,98K合批可以說(shuō)是首選的優(yōu)化工具。

當(dāng)然,你也可以使用虛擬列表的技術(shù)并不用創(chuàng)建出所有的 item,但我的感受是98K更為簡(jiǎn)單粗暴、立桿見影,能結(jié)合使用效果更定會(huì)更佳。

而從多個(gè)環(huán)境平臺(tái)的測(cè)試效果來(lái)看:

  1. 桌面瀏覽效果最佳,如果你是做 H5 頁(yè)游,那再適合不過(guò)
  2. 再次是 iPhone 瀏覽器、小游戲優(yōu)化效果顯著
  3. 然后是中低端的 Android 也比較推薦

下面是 H5 | Android 測(cè)試鏈接,強(qiáng)烈建議你也來(lái)體驗(yàn)一下,歡迎留言說(shuō)說(shuō)在你的設(shè)備上體驗(yàn)感受。

H5測(cè)試鏈接:

- http://gameview.creator-star.cn/98K/batch-items/index.html

Android測(cè)試包下載

- 鏈接: https://pan.baidu.com/s/12aEvOL9fQrpyB4Xs--OALg?pwd=4znt 提取碼: 4znt 

Cocos Store下載鏈接

- https://store.cocos.com/app/detail/4310

希望今天的分享能夠?qū)Υ蠹矣兴鶐椭蛦l(fā), 曉衡會(huì)繼續(xù)挖掘 Cocos Store 上的優(yōu)秀作品分享給大家,歡迎關(guān)注!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 參考由淺到淺入門批量渲染(一)[https://gameinstitute.qq.com/community/de...
    合肥黑閱讀 1,706評(píng)論 0 0
  • Unity技術(shù)面試題 一:什么是協(xié)同程序? 答:在主線程運(yùn)行時(shí)同時(shí)開啟另一段邏輯處理,來(lái)協(xié)助當(dāng)前程序的執(zhí)行。換句話...
    沐冉閱讀 2,911評(píng)論 1 19
  • 這個(gè)是我剛剛整理出的Unity面試題,為了幫助大家面試,同時(shí)幫助大家更好地復(fù)習(xí)Unity知識(shí)點(diǎn),如果大家發(fā)現(xiàn)有什么...
    dingz閱讀 619評(píng)論 0 0
  • 一:什么是協(xié)同程序? 在主線程運(yùn)行的同時(shí)開啟另一段邏輯處理,來(lái)協(xié)助當(dāng)前程序的執(zhí)行,協(xié)程很像多線程,但是不是多線程,...
    胤醚貔貅閱讀 2,096評(píng)論 0 13
  • 一:什么是協(xié)同程序?答:在主線程運(yùn)行時(shí)同時(shí)開啟另一段邏輯處理,來(lái)協(xié)助當(dāng)前程序的執(zhí)行。換句話說(shuō),開啟協(xié)程就是開啟一個(gè)...
    CrixalisAs閱讀 2,100評(píng)論 1 7