关于 静态合图

前言

动态合图(Dynamic Atlas)。


# 一. 动态合图

Cocos Creator 提供了在项目构建时的静态合图方法 —— 「自动合图」(Auto Atlas)。但是当项目日益壮大的时候贴图会变得非常多,很难将贴图打包到一张大贴图中,这时静态合图就比较难以满足降低 DrawCall 的需求。所以 Cocos Creator 在 v2.0 中加入了 「动态合图」(Dynamic Atlas)的功能,它能在项目运行时动态的将贴图合并到一张大贴图中。当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

动态合图官方文档:https://docs.cocos.com/creator/manual/zh/advanced-topics/dynamic-atlas.html


简单来说,开启动态合图之后,引擎会在运行时帮我们对符合条件(即尺寸小于碎图限制的最大尺寸)的精灵进行合图,达到和提前打包图集一样的效果。

引擎的「动态图集尺寸最大是 2048 * 2048」,可合并的「碎图限制的最大尺寸是 512」,用户可以通过下面的 API 进行修改:

cc.dynamicAtlasManager.maxFrameSize = 512;

「启用动态合图会占用额外的内存」,不同平台占用的内存大小不一样。

小游戏和原生平台上默认会禁用动态合图,但如果你的项目内存空间仍有富余的话建议强制开启:

cc.macro.CLEANUP_IMAGE_CACHE = false;
cc.dynamicAtlasManager.enabled = true;

另外还需要保证纹理的 Premulyiply Alpha(预乘)Wrap Mode(循环模式)Filter Mode(过滤模式) 等信息与动态图集一致才能够动态合批。


# 二. 静态图集参与动态合图

在动态合图的官方文档中有提到:

当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

但其实「只要静态图集满足动态合图的要求(即尺寸小于碎图限制的最大尺寸),也是可以参与动态合图的」

注意:自动图集资源(Auto Atlas)需要在其属性检查器面板中开启 「Texture」 栏下的 「Packable」选项,该选项默认是禁用的。


# 三. 额外补充

「只有纹理开启了 Packable 选项的精灵才能够参与动态合图」,该选项默认开启。

纹理参与动态合图后会修改原始贴图的 UV 坐标,所以在 Shader 中的无法正确计算 UV 坐标,导致 Shader 无效。

「如果需要对精灵使用自定义 Shader,需要禁用其纹理的 Packable 选项。」

也可以在代码中禁用该选项:

let sprite = this.node.getComponent(cc.Sprite);
let texture = sprite.spriteFrame.getTexture();
texture.packable = false;

Packable 官方文档:https://docs.cocos.com/creator/manual/zh/asset-workflow/sprite.html?h=packable