Cocos DrawCall測試(動態合圖、cc.Label的cacheMode)


版本:2.4.3

參考:

Cocos Creator 性能優化:DrawCall(全面!)

【樂府】突破動態合圖-你真的把動態合圖用對了嗎?

cocos文檔-動態合圖 

 

主要是看論壇水友陳皮皮的文章《Cocos Creator 性能優化:DrawCall》,實際測試下drawcall。

 

一 碎圖+動態合圖測試

二 碎圖+AABB+ABAB測試

三 自動合圖測試(Auto Atlas)

四  系統字體文本測試 

五 BMFont文本測試

六 遇到問題

 

一 碎圖+動態合圖測試

使用4張碎圖,理論4碎圖+1調試信息文本 = 5 drawcall,但是實際測試drawcall是2。

 

這是因為web默認開啟了動態合圖。動態合圖會額外占用內存,不同平台內存占用不一樣。

web平台默認開啟動態合圖。

小游戲和原生平台默認關閉動態合圖。

 

現在禁用動態合圖,代碼需要寫在項目腳本中的最外層,不要在start或onLoad中禁用,確保在項目加載過程中即時生效。否則如果在部分貼圖緩存已經釋放的情況下才啟用動態圖集,可能會導致報錯。 

const {ccclass, property} = cc._decorator;

//是否在將貼圖上傳至 GPU 之后刪除原始圖片緩存,刪除之后圖片將無法進行 動態合圖。 
//web平台不需要開啟,因為web平台Image占用內存小。
//小游戲平台默認開啟,避免內存占用過高。
cc.macro.CLEANUP_IMAGE_CACHE = true;
//禁用動態合圖
cc.dynamicAtlasManager.enabled = false;

@ccclass
export default class Helloworld extends cc.Component {
    start(){
        console.log(cc.macro.CLEANUP_IMAGE_CACHE, cc.dynamicAtlasManager.enabled);  //true, false
    }
}

 

關閉動態合圖后,可以看到4碎圖+1調試信息 = 5 drawcall。

 

 

 

1. 動態合圖出現,是因為項目過大貼圖過多,導致很難使用靜態合圖Auto Atlas將圖片合並到一個圖集上。

2.動態合圖會占用內存,在小游戲和原生平台默認關閉。

3.動態合圖最大張數5張,使用完會重建,單張合圖最大2048*2048。

4.如果一直不切換場景,那么隨着動態合圖的數量增長,渲染效率可能會降低,適得其反。

5.動態合圖不用,記得剔除“Dynamic Atlas”模塊以減小引擎包體。

 

 

二 碎圖+AABB+ABAB測試

AABB:來自同一張圖的UI並列排放,drawcall仍然按1個算。

2個icon_001 + 2個icon_002 + 1調試信息 = 3 drawcall

 

 

ABAB:交叉的排放,drawcall會增加。

2個icon_001 + 2個icon_002 + 1調試信息 = 5 drawcall

 

 

總結:

所以來自同一圖集的UI,盡量並列排放,可以減少drawcall。

 

三 自動合圖測試(Auto Atlas)

靜態合圖可以使用TexturePacker或者AutoAtlas。

因為TexturePacker比較麻煩,每次美術增加或修改了UI,你得再用軟件去合圖一次, 所以還是直接使用AutoAtlas。

自動合圖需要構建時才會生效,平時調試時不會生效的。

 

總結:

使用AutoAtlas。

 

四  系統字體文本測試 

1 系統字體文本打斷渲染合批

 

 如果添加系統字體文本label,則會打斷合並批次提交。

2 icon_001 + 1調試信息 + 1文本 = 4 drawcall

 

 

2 文本三種緩存模式

 

 

NONE:

 

沒有任何操作,3個文本會打斷icon渲染合批,並且3個文本算3個drawcall。

2icon_001 + 3文本 + 1調試信息 = 6 drawcall

 

 

BITMAP:

如果關閉動態合圖,則這一項沒用。依然是

2icon_001 + 3文本 + 1調試信息 = 6 drawcall。

如果開啟動態合圖,則icon和文本會合並,2個icon和3個文本相當於1個drawcall。

2icon_001 + 3文本 + 1調試信息 = 2 drawcall

 

CHAR:

共享位圖的最大尺寸為 2048*2048,占滿了之后就沒辦法再渲染新的字符,需要切換場景才會清除共享位圖。

和動態合圖無關,字符會緩存到一張圖上,所以3個文本相當於1個drawcall。

2icon_001 + 3文本 + 1調試信息 = 4 drawcall

 

總結:

 普通界面,關閉動態合圖情況下,選擇CHAR模式,並將文本並列排放,則能減少drawcall。

 

 

五 BMFont文本測試

1. BMFont會打斷渲染合批

2icon_001 + 2BMFont + 1調試信息 = 5 drawcall

 

 

 

 

 2. BMFont沒有緩存模式,可以參與Auto Atlas靜態合圖。

將BMFont的圖片和icon圖標一起靜態合圖

2 icon + 2 BMFont + 1 調試信息 = 2 drawcall

 

 

總結:

大部分BMFont基本都是通用型,可能貫穿游戲很多個界面,所以合圖並到某個界面不合適。

在關閉動態合圖的情況下,和系統字體CHAR模式類似,只能相鄰排放來減少drawcall。

 

六 遇到問題

1 顯示動態合圖的調試信息問題

使用cc.dynamicAtlasManager.showDebug(true)可以顯示動態合圖調試信息,會將動態合圖展示在場景上的一個scrollView中。

代碼寫在onLoad里或者場景中沒有cc.Label,則啥也看不見。

一定要在場景中放一個cc.Label,設置cacheMode為Bitmap,然后在start里移動合圖的node的x和y,才能看得見動態合圖。

        let node: cc.Node = cc.dynamicAtlasManager.showDebug(true);
        node.x = 1000;
        node.y = 0;
        console.log(node.x, node.y, node.width, node.height);

  

 2 使用TexturePacker的合圖能參與動態合圖嗎

這是一個texturepacker的合圖

 

 這是cc.dynamicAtlasManager.showDebug(true)后顯示的調試信息,可以看到texturepacker的合圖參與了動態合圖。

 

 

3 使用autoaltas自動合圖能參與動態合圖嗎

這是autoaltas的自動合圖

 

將劍擺到場景上,cc.dynamicAtlasManager.showDebug(true)顯示的調試信息,可以看到autoaltas的劍能參與動態合圖。

 

 

4 骨骼動畫能不能參與動態合圖

不能

擺一個骨骼動畫到場景中

 

 cc.dynamicAtlasManager.showDebug(true)顯示的調試信息,可以看到骨骼動畫並沒有參與動態合圖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM