關于creator動態(tài)合圖

在creator中,為了降低DC,提供了一個方法,在項目運行的時候,運行時將內(nèi)存中的任意紋理組合成一張虛擬的圖集,當渲染一張貼圖的時候,動態(tài)合圖系統(tǒng)會自動檢測這張貼圖是否已經(jīng)被加入到了動態(tài)合圖系統(tǒng),如果沒有,并且此貼圖又符合動態(tài)合圖的條件,就會將此貼圖合并到動態(tài)合圖系統(tǒng)生成的大貼圖中。

動態(tài)合圖?是按照?渲染順序?來選取要將哪些貼圖合并到一張大圖中的,這樣就能確保相鄰的 DrawCall 能合并為一個 DrawCall。

注意事項:

在場景加載前,動態(tài)合圖系統(tǒng)會進行重置,?SpriteFrame貼圖的引用和 uv 都會恢復到初始值。

Cocos Creator是如何實現(xiàn)這個功能的呢?

核心思想是數(shù)據(jù)結(jié)構(gòu)中常說的空間換時間, 原理其實并不復雜,就是幀緩存,簡單來說就是將多份spriteFrame繪制到RenderTexture上,并記錄其在新的RenderTexture中所屬的位置和長寬,渲染的時候利用這些信息從RenderTexture所得到的紋理上取所需要的區(qū)域`

```

onstAtlas=require('./atlas');

let_atlases=[];

let_atlasIndex=-1;

let_maxAtlasCount=5;

let_textureSize=2048;

// Smaller frame is more likely to be affected by linear filter

let_minFrameSize=8;

let_maxFrameSize=512;

let_debugNode=null;

functionnewAtlas(){

letatlas=_atlases[++_atlasIndex]

if(!atlas){

atlas=newAtlas(_textureSize,_textureSize);

_atlases.push(atlas);

}

returnatlas;

}

functionbeforeSceneLoad(){

dynamicAtlasManager.reset();

}

let_enabled=false;

/**

* !#en Manager the dynamic atlas.

* !#zh 管理動態(tài)圖集。

*@classDynamicAtlasManager

*/

letdynamicAtlasManager={


/**

? ? * !#en Enabled or Disabled dynamic atlas.

? ? * !#zh 開啟或者關閉動態(tài)圖集。

*@propertyenabled

*@type{Boolean}

? ? */

getenabled(){

return_enabled;

},

setenabled(value){

if(_enabled===value)return;

if(value){

this.reset();

cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LAUNCH,beforeSceneLoad);

}

else{

cc.director.off(cc.Director.EVENT_BEFORE_SCENE_LAUNCH,beforeSceneLoad);

}

_enabled=value;

},

/**

? ? * !#en The maximum number of atlas that can be created.

? ? * !#zh 可以創(chuàng)建的最大圖集數(shù)量。

*@propertymaxAtlasCount

*@type{Number}

? ? */

getmaxAtlasCount(){

return_maxAtlasCount;

},

setmaxAtlasCount(value){

_maxAtlasCount=value;

},

/**

? ? * !#en The size of the atlas that was created

? ? * !#zh 創(chuàng)建的圖集的寬高

*@propertytextureSize

*@type{Number}

? ? */

gettextureSize(){

return_textureSize;

},

settextureSize(value){

_textureSize=value;

},

/**

? ? * !#en The maximum size of the picture that can be added to the atlas.

? ? * !#zh 可以添加進圖集的圖片的最大尺寸。

*@propertymaxFrameSize

*@type{Number}

? ? */

getmaxFrameSize(){

return_maxFrameSize;

},

setmaxFrameSize(value){

_maxFrameSize=value;

},

/**

? ? * !#en Append a sprite frame into the dynamic atlas.

? ? * !#zh 添加碎圖進入動態(tài)圖集。

*@methodinsertSpriteFrame

*@param{SpriteFrame} spriteFrame

? ? */

insertSpriteFrame(spriteFrame){

if(CC_EDITOR)returnnull;

if(!_enabled||_atlasIndex===_maxAtlasCount||

!spriteFrame||spriteFrame._original)returnnull;


lettexture=spriteFrame._texture;

if(textureinstanceofcc.RenderTexture||texture._isCompressed())returnnull;

letw=texture.width,h=texture.height;

if(w>_maxFrameSize||h>_maxFrameSize||w<=_minFrameSize||h<=_minFrameSize

||texture._getHash()!==Atlas.DEFAULT_HASH){

returnnull;

}

letatlas=_atlases[_atlasIndex];

if(!atlas){

atlas=newAtlas();

}

letframe=atlas.insertSpriteFrame(spriteFrame);

if(!frame&&_atlasIndex!==_maxAtlasCount){

atlas=newAtlas();

returnatlas.insertSpriteFrame(spriteFrame);

}

returnframe;

},

/**

? ? * !#en Resets all dynamic atlas, and the existing ones will be destroyed.

? ? * !#zh 重置所有動態(tài)圖集,已有的動態(tài)圖集會被銷毀。

*@methodreset

? ? */

reset(){

for(leti=0,l=_atlases.length;i<l;i++){

_atlases[i].destroy();

}

_atlases.length=0;

_atlasIndex=-1;

},

/**

? ? * !#en Displays all the dynamic atlas in the current scene, which you can use to view the current atlas state.

? ? * !#zh 在當前場景中顯示所有動態(tài)圖集,可以用來查看當前的合圖狀態(tài)。

*@methodshowDebug

*@param{Boolean} show

? ? */

showDebug:CC_DEV&&function(show){

if(show){

if(!_debugNode||!_debugNode.isValid){

letwidth=cc.visibleRect.width;

letheight=cc.visibleRect.height;

_debugNode=newcc.Node('DYNAMIC_ATLAS_DEBUG_NODE');

_debugNode.width=width;

_debugNode.height=height;

_debugNode.x=width/2;

_debugNode.y=height/2;

_debugNode.zIndex=cc.macro.MAX_ZINDEX;

_debugNode.parent=cc.director.getScene();

_debugNode.groupIndex=cc.Node.BuiltinGroupIndex.DEBUG;

cc.Camera._setupDebugCamera();

letscroll=_debugNode.addComponent(cc.ScrollView);

letcontent=newcc.Node('CONTENT');

letlayout=content.addComponent(cc.Layout);

layout.type=cc.Layout.Type.VERTICAL;

layout.resizeMode=cc.Layout.ResizeMode.CONTAINER;

content.parent=_debugNode;

content.width=_textureSize;

content.anchorY=1;

content.x=_textureSize;

scroll.content=content;

for(leti=0;i<=_atlasIndex;i++){

letnode=newcc.Node('ATLAS');


lettexture=_atlases[i]._texture;

letspriteFrame=newcc.SpriteFrame();

spriteFrame.setTexture(_atlases[i]._texture);

letsprite=node.addComponent(cc.Sprite)

sprite.spriteFrame=spriteFrame;

node.parent=content;

}

}

}

else{

if(_debugNode){

_debugNode.parent=null;

_debugNode=null;

}

}

},

update(){

if(!this.enabled)return;

for(leti=0;i<=_atlasIndex;i++){

_atlases[i].update();

}

},

};

/**

*@modulecc

*/

/**

*@propertydynamicAtlasManager

*@typeDynamicAtlasManager

*/

module.exports=cc.dynamicAtlasManager=dynamicAtlasManager;

```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容