跳到主要内容
版本:1.0.0

新的 Char 缓存模式

新 UI 渲染批次合并指南 中提到 Bitmap 与 Char 缓存模式都支持了废弃字符空间复用的特性,但 Char 缓存模式的内部变化比较大,并且提供了一些可调整的设置项,使用上依旧只需要设置缓存模式即可。


在场景切换时清空所有字符图集

控制在场景切换时是否会清空所有的字符图集,默认为开启状态。

cc.sp.charAtlasAutoResetBeforeSceneLoad = false;
提示

在引擎原来的设计中,该机制不可被关闭,由于旧 Char 缓存模式不支持复用废弃的空间,图集终究会被用完,所以引擎加入了这个治标不治本的功能。

现在推荐关闭该机制,除非你知道你需要。


字符图集的数量与内置材质

现在在内部最多会创建 8 张字符图集,与多纹理材质的最大纹理插槽数一致,如果合理使用缓存模式,8 张应该对所有项目都是足够的。

在这种情况下,可能发生的事是 Char 缓存模式的组件使用了一个普通材质,这个材质只能使用第一张字符图集进行渲染,那么就会导致其他图集上的字就无法渲染出来了。

为了解决这个问题,Char 缓存模式会在内部维护一个使用内置多纹理 Effect 着色器的材质,如果你有特殊的用途,可以通过

const material = cc.Label._shareAtlas.material;

获取、修改或替换该材质。

渲染时内部会先判断当前所使用的是否为多纹理材质,是的话判断是否能在材质纹理插槽中找到字符图集纹理,如果有一个判断不满足则会将组件的材质设为内部维护的材质。

但 Char 字符图集是运行时才创建的,所以暂时无法在使用 Char 缓存模式时直接设置自定义材质

你可以通过代码创建含有当前所有字符图集纹理的自定义材质来解决这个问题,但内部会不断创建新的字符图集(直到 8 张),所以需注意同步更新这个自定义材质,建议有自定义材质需求时使用 Bitmap 缓存模式。


与动态图集合批的注意事项

多纹理材质只有 8 个纹理插槽,默认情况下字符图集自动多纹理合批的数量为 1,也就是说会将第 1 张字符图集纹理放入材质。

你可以自己调整这个分配值,但请注意调整的时机。

下面举一个例子,假设有一个脚本 example.ts 的部分内容是:


class Example extends cc.Component {

onLoad() {
// 1
}

}

// 2

一般情况下,代码位置 2 是当用户脚本被加载时就会被执行,而代码位置 1 可能需要等到引擎首场景加载后的某个时间执行。

增强包会自动调整动态图集的最大数量,这个调整的时机是在代码位置 2 之后的,所以比如你的项目对 Char 缓存模式使用量比较大时,想尝试将动态图集最大数量调整为 6,自动合批的字符图集数量调整为 2,那么你只需要在代码位置 2 修改字符图集自动多纹理合批的数量:

cc.sp.charAtlasAutoBatchCount = 2;

之后增强包会自动将动态图集的最大数量调整为 8 - 2,即 6。

这个自动调整的时机并不意味着你在代码位置 2 修改动态图集的最大数量是无效的,因为一开始动态图集的最大数量为 -1,你打印一下可以看到

console.log(cc.dynamicAtlasManager.maxAtlasCount);      // -1

如果你在代码位置 2 修改了动态图集的最大数量,增强包就不会调整该值了。

cc.dynamicAtlasManager.maxAtlasCount = 5;

这时候动态图集的最大数量是 5,字符图集自动多纹理合批的数量依旧默认为 1,多纹理材质会有 2 个空纹理插槽。

如果这两个数量加起来超过 8 就会使用更多的材质进行渲染,这会导致项目的 Draw Call 数量升高,建议保持加起来的数量不超过 8 张,能保持 1 Draw Call。

cc.dynamicAtlasManager.maxAtlasCount = 13;
cc.sp.charAtlasAutoBatchCount = 3;

比如上面这个设置,这会使得引擎需要用 2 个材质进行渲染,但是可用的动态图集扩充到了 13 张,Char 能自动合批的图集数量扩充到了 3 张,对于某些项目来说可能并不是一件坏事。

增强包使用这个 “7 + 1” 的默认值有以下几点原因:

  • 引擎原本就只有 1 张 Char 字符图集
  • 大多数项目使用 1 张 Char 字符图集是足够的