更新 v1.0.0 版本文档
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "使用指南",
|
||||
"position": 4,
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "user-guide-intro"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "动态合图",
|
||||
"position": 3,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "dynamic-batcher-intro"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,99 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
description: "了解调校动态合图的方式。"
|
||||
---
|
||||
# 调整合图设置
|
||||
|
||||
---
|
||||
## 动态图集最大数量为什么是 7
|
||||
|
||||
在前面的文档中有提到动态图集的最大数量默认为 **设备能同时采样纹理数 - Char 缓存模式自动合批图集数**。
|
||||
|
||||
因为设备能同时采样纹理数固定为 `8`,而 Char 缓存模式自动合批图集数默认为 `1`,所以动态合图的最大数量默认值为 `7`。
|
||||
|
||||
这样就只需要使用 1 个材质,也就是能在 1 Draw Call 里完成所有参与动态合图的纹理(包括 Bitmap 缓存模式 Label)与 Char 缓存模式 Label 的渲染。
|
||||
|
||||
一般情况下不推荐直接修改 `maxAtlasCount`,请参考 [新的 Char 缓存模式](../text-render/text-char-mode.md#与动态图集合批的注意事项) 文档。
|
||||
|
||||
> 难道真正的原因是...
|
||||
>
|
||||
> 
|
||||
|
||||
---
|
||||
## 控制纹理是否参与动态合图
|
||||
|
||||
可以在编辑器上调整纹理的 `packable` 属性,或者用代码控制:
|
||||
|
||||
```js
|
||||
texture.packable = false;
|
||||
```
|
||||
|
||||
---
|
||||
## 控制组件是否参与动态合图
|
||||
|
||||
使用下面的代码控制组件是否默认激活动态合图机制,默认为开启:
|
||||
|
||||
```js
|
||||
cc.sp.allowDynamicAtlas = false;
|
||||
```
|
||||
|
||||
也可以控制单组件是否激活动态合图机制:
|
||||
|
||||

|
||||
|
||||
除了在编辑器调整,也可以通过代码控制:
|
||||
|
||||
```js
|
||||
// cc.RenderComponent.EnableType
|
||||
// GLOBAL: 全局默认值
|
||||
// ENABLE: 开启
|
||||
// DISABLE: 关闭
|
||||
label.allowDynamicAtlas = cc.RenderComponent.EnableType.ENABLE;
|
||||
```
|
||||
|
||||
如果一个纹理参与动态合图但是组件不参与,那么使用该组件进行渲染时就不会参与,但如果同时在其它参与的组件上渲染,那么依然会被打入动态图集。
|
||||
|
||||
:::caution 注意
|
||||
|
||||
组件有脏检查标记,修改后可能需要对渲染组件调用 `comp.setVertsDirty()` 才会生效。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 是否自动多纹理合批
|
||||
|
||||
控制图集纹理是否会自动添加到多纹理合批管理器,默认为开启状态,如果关闭也就意味着**失去了自动进行多个图集纹理合批的特性**。
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.autoMultiBatch = false;
|
||||
```
|
||||
|
||||
---
|
||||
## 在场景切换时清空所有图集
|
||||
|
||||
控制在场景切换时是否会清空所有的动态图集,默认为开启状态。
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.autoResetBeforeSceneLoad = false;
|
||||
```
|
||||
|
||||
:::tip 提示
|
||||
|
||||
在引擎原来的设计中,该机制不可被关闭,由于旧动态合图不支持复用废弃的空间,图集终究会被用完,所以引擎加入了这个治标不治本的功能。
|
||||
|
||||
但现在,我们认为该机制可以关闭,你只需要管理好纹理资源的释放即可,因为纹理资源释放的同时会释放使用的动态图集空间。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 不进行复用的区域空间大小
|
||||
|
||||
在实际的测试中,我们发现废弃空间出现碎片化的现象,比如尺寸 5 * 2 这样的非常小的废弃空间,当碎图尝试加入图集的时候会在这些废弃空间中寻找,这些数量多的小废弃空间无法被复用,却要在每次加入时遍历判断一次。
|
||||
|
||||
所以我们加入了 `ignoreRectSize` 设置,当废弃空间尺寸小于这个值就不会被遍历到(但是能合并为大的废弃空间时还是会合并),这能提升大约 50% 的理论性能。
|
||||
|
||||
这个值默认为 `10`,如果你的项目有很多小于 10 * 10 的纹理,可以考虑进行调整:
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.Atlas.ignoreRectSize = 2;
|
||||
```
|
||||
@@ -0,0 +1,10 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
# 动态合图
|
||||
|
||||
动态合图是一个非常好的合批手段,但是在之前引擎实现的比较简陋,所以服务包重构了动态合图系统,在原有功能基础上增加了许多重要特性。
|
||||
|
||||
比如支持复用废弃碎图空间,优化了图集装箱算法,所有图集作为一个整体进行管理等等,你可以阅读下面的文档了解详情:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
description: "随心所欲地控制动态合图的使用。"
|
||||
---
|
||||
|
||||
# 手动管理合图
|
||||
|
||||
有时候你可能需要更细致地去控制哪些纹理加入动态图集,考虑到这一点,服务包在保留原来所有接口的基础上完全开放了动态图集相关的所有接口。
|
||||
|
||||
---
|
||||
## 访问图集数组与已用空间集合
|
||||
|
||||
你可以通过
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.atlases
|
||||
```
|
||||
|
||||
和
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.rects
|
||||
```
|
||||
|
||||
分别访问到图集数组与所有图集的已用空间集合。
|
||||
|
||||
---
|
||||
## 添加 SpriteFrame 到动态图集
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.insertSpriteFrame(spriteFrame);
|
||||
```
|
||||
|
||||
可以将 SpriteFrame 所使用的纹理添加到动态图集,这是引擎原有接口,但服务包对其做了一点修改,这个接口不再会检查纹理的 `packable` 属性,也就是变成了一个强制添加的接口。
|
||||
|
||||
这样设计的原因是你可以将所有纹理的 `packable` 都设为 `false`,或者直接将 `maxFrameSize` 设为 `0`,然后完全手动地进行动态合图。
|
||||
|
||||
---
|
||||
## 从动态图集删除 SpriteFrame
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.deleteSpriteFrame(spriteFrame);
|
||||
```
|
||||
|
||||
可以使 SpriteFrame 取消使用动态图集纹理,这不一定会将 SpriteFrame 的纹理从动态图集删除,因为可能还会有其它 SpriteFrame 在使用,只有没有 SpriteFrame 在使用时才会删除纹理。
|
||||
|
||||
---
|
||||
## 从动态图集删除 Texture
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.deleteTexture(texture);
|
||||
```
|
||||
|
||||
这个接口与 `deleteSpriteFrame` 相似,但是它会直接删除纹理,并且会使使用该纹理的 SpriteFrame 全部恢复。
|
||||
|
||||
---
|
||||
## 更多接口
|
||||
|
||||
虽然还暴露了其它接口出来,但因为太过于底层所以不推荐使用,如果你想了解可以阅读原理文档。
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "多纹理渲染",
|
||||
"position": 1,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "multi-render-intro"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 722 KiB |
|
After Width: | Height: | Size: 93 KiB |
@@ -0,0 +1,125 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
description: "了解如何手动进行多纹理合批。"
|
||||
---
|
||||
|
||||
# 多纹理合批
|
||||
|
||||
在 [新 UI 渲染批次合并指南](../../start-guide/batcher-guide.md#充分利用动态合图) 中提到了动态合图与多纹理渲染结合后,能让多张图集纹理在同一批次渲染。
|
||||
|
||||
如果你阅读过 [多纹理材质](./multi-material.md) 文档的话,肯定知道能使用 `MultiHandler` 的接口来动态设置材质的纹理插槽来实现。
|
||||
|
||||
但是这种完全手动的方式实现起来比较麻烦,比如你需要使用一个纹理时,还得找到该纹理所在的材质并设置到渲染组件上。
|
||||
|
||||
为了能更方便地进行多纹理合批,服务包封装了一个自动切换多纹理材质的机制与多纹理合批管理类 `cc.sp.MultiBatcher`。
|
||||
|
||||
动态图集与字符图集使用的是一个全局的多纹理合批管理器实例,可以通过 `cc.sp.multiBatcher` 访问。
|
||||
|
||||
---
|
||||
## 开关自动切换多纹理材质
|
||||
|
||||
要让动态合图自动进行多纹理合批,首先要解决设置材质的问题,当切换成动态图集的纹理时,需要自动将组件的材质设置为有动态图集纹理的材质。
|
||||
|
||||
所以我们增加了一个机制,在支持的组件内使用开启了该机制的纹理进行渲染时,会提前切换为该纹理关联的材质(只要支持多纹理渲染就支持自动切换材质)。
|
||||
|
||||
这个机制默认是开启的,可以通过全局开关来控制默认值:
|
||||
|
||||
```js
|
||||
cc.sp.autoSwitchMaterial = false;
|
||||
```
|
||||
|
||||
默认情况下组件会使用全局值,你可以控制单个组件是否强制启用/禁用该机制:
|
||||
|
||||

|
||||
|
||||
除了在编辑器调整,也可以通过代码控制:
|
||||
|
||||
```js
|
||||
// cc.RenderComponent.EnableType
|
||||
// GLOBAL: 全局默认值
|
||||
// ENABLE: 开启
|
||||
// DISABLE: 关闭
|
||||
sprite.autoSwitchMaterial = cc.RenderComponent.EnableType.ENABLE;
|
||||
```
|
||||
|
||||
:::caution 注意
|
||||
|
||||
组件有脏检查标记,如果修改全局开关或者修改纹理关联的材质,需要对所有使用该纹理的渲染组件调用 `comp.setVertsDirty()` 重新检查。
|
||||
|
||||
:::
|
||||
|
||||
:::caution 特别注意
|
||||
|
||||
如果 Spine 组件所使用的 `SkeletonData` 同时使用了多个纹理,那么只会遍历数据以找到的第一个纹理为主执行自动切换机制。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 设置纹理的关联材质
|
||||
|
||||
:::info
|
||||
|
||||
每个纹理只能关联一个材质,如果同一个纹理,不同的渲染组件需要使用不同材质就需要手动设置。
|
||||
|
||||
:::
|
||||
|
||||
关联材质的接口有两种用法:
|
||||
|
||||
```js
|
||||
const bool = texture.linkMaterial(material);
|
||||
const bool = texture.linkMaterial(material, index);
|
||||
```
|
||||
|
||||
第一句代码会自动将纹理设置到材质的空插槽中,然后将该材质设置为该纹理的关联材质,如果没有空插槽会返回 `false`。
|
||||
|
||||
第二句则是强制将纹理设置到指定的插槽中,并将该材质设置为该纹理的关联材质。
|
||||
|
||||
想要解除两者的关联可以使用:
|
||||
|
||||
```js
|
||||
texture.unlinkMaterial();
|
||||
```
|
||||
|
||||
获取关联的材质可以使用:
|
||||
|
||||
```js
|
||||
const material = texture.getLinkedMaterial();
|
||||
```
|
||||
|
||||
---
|
||||
## 多纹理合批管理器
|
||||
|
||||
手动关联材质就意味着你需要手动创建并管理创建的所有材质,如果是大量纹理需要关联材质就会比较麻烦。
|
||||
|
||||
所以我们封装了一个小巧的多纹理合批管理器 `cc.sp.MultiBatcher`。
|
||||
|
||||
这个管理器有点像动态合图管理器,它会持有一个材质数组,初始化后会使用内置的多纹理 Effect 着色器创建一个材质并放在数组中。
|
||||
|
||||
你可以传给管理器一个纹理,它会查找所有材质的空插槽,如果没有材质有空插槽则会创建一个新材质,然后把纹理与材质关联。
|
||||
|
||||
### 如何使用
|
||||
|
||||
创建管理器并初始化可以使用:
|
||||
|
||||
```js
|
||||
const batcher = new cc.sp.MultiBatcher();
|
||||
batcher.init();
|
||||
```
|
||||
|
||||
传入纹理可以使用:
|
||||
|
||||
```js
|
||||
const material = batcher.requsetMaterial(texture);
|
||||
```
|
||||
|
||||
会返回关联的材质,如果纹理本来就已经有关联的材质,则会直接返回已关联的材质。
|
||||
|
||||
清空内部数组可以使用(这不会取消纹理的关联):
|
||||
|
||||
```js
|
||||
batcher.reset();
|
||||
```
|
||||
|
||||
### 它的用途
|
||||
|
||||
在 [进阶合批指南](../../start-guide/advance-batcher-guide.md) 中有提供一些常见的使用案例。
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
description: "了解如何手动管理多纹理材质。"
|
||||
toc_max_heading_level: 5
|
||||
---
|
||||
|
||||
# 多纹理材质
|
||||
|
||||
服务包在引擎内置了可以直接使用的多纹理 Effect 着色器资源,并且你可以直接使用多纹理材质而不需要编写任何代码。
|
||||
|
||||
---
|
||||
## 创建多纹理材质
|
||||
|
||||
你可以正常创建一个材质文件,Effect 选择内置的多纹理 Effect 着色器 `multi-2d-universal` 即可。
|
||||
|
||||

|
||||
|
||||
勾选 `USE_MULTI_TEXTURE` 后可以看到上面有 `texture` - `texture8` 一共 8 个纹理插槽,将需要使用的纹理拖到上面的插槽即可完成多纹理材质的配置。
|
||||
|
||||
---
|
||||
## 在组件中使用多纹理材质
|
||||
|
||||
直接拖到组件的 `Materials` 属性上即可。
|
||||
|
||||

|
||||
|
||||
注意上图中已经在 `cc.Sprite` 组件拖入了刚刚创建的多纹理材质,并且其 `SpriteFrame` 属性设置的是材质中 `texture3` 插槽中的纹理。
|
||||
|
||||

|
||||
|
||||
你不需要指定组件要使用的纹理插槽 id,组件内部在渲染前会自动查找纹理在材质中的 id。
|
||||
|
||||
:::caution 警告
|
||||
|
||||
如果组件使用的纹理在材质中找不到,为了保证渲染的正常(毕竟性能只是锦上添花)会在组件的材质变体中将纹理设置到 `texture` 插槽中。
|
||||
|
||||
这会导致这个组件的多纹理材质变体之后都不能按预期进行合批,就像 “退化” 成了普通材质。
|
||||
|
||||
所以使用时必须要确保纹理在材质中,假如材质变体已经 “退化” 了,那你可以通过重新设置材质的方式使组件持有一个新的材质变体。
|
||||
|
||||
:::
|
||||
|
||||
:::caution 特别注意
|
||||
|
||||
Spine 组件使用多纹理材质时会强制勾选 `enableBatch`,因为不开启就不能合批,那也就没必要使用多纹理材质。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 自定义多纹理材质
|
||||
|
||||
上面介绍的多纹理材质都是使用的内置的多纹理 Effect 着色器,你可以直接在内置多纹理 Effect 着色器的基础上修改。
|
||||
|
||||
除了直接在内置着色器的基础上修改之外,任何着色器中如果存在一个宏 `USE_MULTI_TEXTURE = true`,则会被认为是多纹理材质。
|
||||
|
||||
[演示项目](https://smallmain.github.io/cocos-service-pack/demo/v1.0.0/web-desktop/index.html) 中有自定义材质的示范代码。
|
||||
|
||||
:::tip 提示
|
||||
|
||||
是否为多纹理材质的判断逻辑流程:
|
||||
|
||||
1. 获取材质当前使用的 Technique 中的第一个 Pass
|
||||
2. 判断这个 Pass 是否 `USE_MULTI_TEXTURE = true`
|
||||
3. 是的话,这个材质即为多纹理材质
|
||||
|
||||
在某些情况下通过代码修改材质可能需要调用 `material.updateMultiSupport()` 来触发这个流程。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 通过代码设置纹理插槽
|
||||
|
||||
每个多纹理材质都对应着一个多纹理材质管理器,这是服务包新增的一个工具类,其主要用处是便捷、高性能地管理多纹理材质上面的纹理插槽。
|
||||
|
||||
通过 `material.getMultiHandler()` 可以获取到管理器实例,请使用这个实例来操作多纹理材质的纹理插槽。
|
||||
|
||||
比如:
|
||||
|
||||
```js
|
||||
// 获取管理器实例
|
||||
const handler = material.getMultiHandler();
|
||||
|
||||
// 设置 `texture` 纹理插槽
|
||||
handler.setTexture(0, texture);
|
||||
|
||||
// 置空 `texture2` 纹理插槽
|
||||
handler.setTexture(1, null);
|
||||
|
||||
// 直接移除指定纹理
|
||||
handler.removeTexture(texture.getImpl());
|
||||
|
||||
// 将纹理自动设置到材质的空插槽
|
||||
handler.autoSetTexture(texture);
|
||||
```
|
||||
|
||||
从上面的代码中可以看出操作纹理插槽的时候并不是传入插槽的名称,而是需要提供下标。
|
||||
|
||||
下标 `0` - `7` 分别对应着名称为 `texture` - `texture8` 的插槽。
|
||||
|
||||
可以使用这两个函数进行转换:
|
||||
|
||||
```js
|
||||
// index to name
|
||||
cc.sp.propertyIndex2Name(0); // return: "texture"
|
||||
|
||||
// name to index
|
||||
cc.sp.propertyName2Index("texture"); // return: 0
|
||||
```
|
||||
|
||||
:::caution 注意
|
||||
|
||||
注意区分材质 `cc.Material` 与材质变体 `cc.MaterialVariant`。
|
||||
|
||||
:::
|
||||
|
||||
:::caution 警告
|
||||
|
||||
请勿直接通过材质原始的 `setProperty` 接口修改多纹理材质的纹理插槽。
|
||||
|
||||
如果你必须这么做,需要调用 `material.getMultiHandler().syncTextures()` 来同步插槽数据到 `MultiHandler` 上。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 强制设置材质的类型
|
||||
|
||||
如果你想将某个材质强制视为多纹理材质或非多纹理材质,可以:
|
||||
|
||||
```js
|
||||
// 视为多纹理材质
|
||||
material.setMultiSupport(true);
|
||||
|
||||
// 视为非多纹理材质
|
||||
material.setMultiSupport(false);
|
||||
```
|
||||
|
||||
没有特殊情况不需要这么做。
|
||||
@@ -0,0 +1,30 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
# 多纹理渲染
|
||||
|
||||
:::tip 提示
|
||||
|
||||
多纹理渲染属底层设施,如果你不是准备手动使用多纹理材质或者多纹理合批管理器的话,请跳过本特性文档。
|
||||
|
||||
:::
|
||||
|
||||
多纹理渲染在 [新 UI 渲染批次合并指南](../../start-guide/batcher-guide.md#什么是多纹理渲染) 中有所介绍。
|
||||
|
||||
其原理非常简单,并且为了让它能以最简单的方式在引擎中使用,已经在内部做好了封装:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
|
||||
:::caution 注意
|
||||
|
||||
- **支持的渲染组件**
|
||||
|
||||
cc.Sprite、cc.Label、cc.RichText、cc.MotionSteak、Spine 组件。
|
||||
|
||||
- **不支持的渲染组件**
|
||||
|
||||
cc.ParticleSystem、TiledMap 组件:这两个组件当前的引擎实现会强制打断合批,暂时不支持。
|
||||
|
||||
DragonBones 组件:因人力有限,并且这个组件与 Spine 组件可以相互代替,所以暂时不支持该组件。
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Spine",
|
||||
"position": 4,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "spine-intro"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
description: "像其它渲染组件一样在 Spine 组件上使用动态合图。"
|
||||
---
|
||||
|
||||
# 动态合图
|
||||
|
||||
你可以像其它渲染组件一样在 Spine 组件上使用动态合图,如果想了解有关动态合图的更多详情,可以阅读 [动态合图](../dynamic-batcher/dynamic-batcher-intro.mdx) 文档。
|
||||
|
||||
:::caution 注意
|
||||
|
||||
由于引擎实现差异,在原生平台上 Spine 暂不支持与其它组件合批。
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,22 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
# Spine
|
||||
|
||||
服务包解决了 Spine 在 Cocos Creator 中的三大痛点:
|
||||
|
||||
- 不参与动态合图
|
||||
- 无法与其它组件合批
|
||||
- 不能使用 SpriteFrame 换装
|
||||
|
||||
你可以阅读下面的文档了解详情:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
|
||||
:::caution 注意
|
||||
|
||||
由于引擎这部分的 C++ 实现与 JavaScript 实现在一些细节上不太一样,比如一些内部函数的执行时机。
|
||||
|
||||
所以当你在 Web 平台上测试得出的一些结论请不要想当然地以为在原生平台上也一样,具体实现差异请阅读 Spine 的原理文档。
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
description: "随心所欲地更换 Spine 动画的部份纹理。"
|
||||
---
|
||||
|
||||
# SpriteFrame 换装
|
||||
|
||||
引擎提供了一个替换插槽的 attachment 对象进行换装的方法,可以在 [Spine 组件参考](https://docs.cocos.com/creator/2.4/manual/zh/components/spine.html) 官方文档进行了解。
|
||||
|
||||
但是使用替换插槽的 attachment 对象这种方法比较绕,并且 Spine 动画中有切换 attachment 的关键帧时这种方法就没用了。
|
||||
|
||||
而 attachment 对象持有一个 region 对象,这个对象类似引擎的 SpriteFrame,所以我们可以通过修改 region 对象的数据来进行换装。
|
||||
|
||||
---
|
||||
## 认识 RegionData
|
||||
|
||||
请勿混淆 RegionData 与 region,RegionData 主要作为 SpriteFrame 和 region 对象之间的桥梁,实现两者的相互转换。
|
||||
|
||||
将 SpriteFrame 转换为 RegionData:
|
||||
|
||||
```js
|
||||
const regionData = new sp.RegionData(spriteFrame);
|
||||
```
|
||||
|
||||
将 RegionData 转换为 SpriteFrame:
|
||||
|
||||
```js
|
||||
const spriteFrame = regionData.toSpriteFrame();
|
||||
```
|
||||
|
||||
将 attachment 对象的 region 数据转换为 RegionData :
|
||||
|
||||
```js
|
||||
const regionData = new sp.RegionData(attachment);
|
||||
```
|
||||
|
||||
将 RegionData 数据更新到 attachment 对象上:
|
||||
|
||||
```js
|
||||
regionData.assignToAttachment(attachment);
|
||||
```
|
||||
|
||||
:::caution 注意
|
||||
|
||||
Spine 的 Region 支持 `0`、`90`、`180`、`270` 四种旋转角度,而 Cocos Creator 的 SpriteFrame 只支持 `0` 与 `270` 两种旋转角度,所以如果是 RegionData 转为 SpriteFrame 则可能导致方向不同的问题。
|
||||
|
||||
**要进行换装的话使用的是 SpriteFrame 转为 RegionData,所以不用担心这个问题。**
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 使用 SpriteFrame 修改 Region 数据
|
||||
|
||||
虽然使用上面的 RegionData 即可实现使用 SpriteFrame 换装的需求,但我们还在 Spine 组件上提供了两个更方便的接口:
|
||||
|
||||
只使用 `regionData.assignToAttachment(attachment)` 只会修改 SkeletonData 的数据,但不会触发 Spine 组件的渲染更新。
|
||||
|
||||
推荐直接使用:
|
||||
|
||||
```js
|
||||
skeletonComponent.setRegionData('Head', 'Head', new sp.RegionData(spriteFrame));
|
||||
```
|
||||
|
||||
在修改的同时刷新组件的渲染实现换装,并且不会打断当前正在播放的动画。
|
||||
|
||||
还提供了一个通过 attachment 名称获取 RegionData 的接口:
|
||||
|
||||
```js
|
||||
a.getRegion(slotName, attachmentName);
|
||||
```
|
||||
|
||||
---
|
||||
## 注意事项
|
||||
|
||||
|
||||
### 多实例问题
|
||||
|
||||
由于是直接修改 Spine 组件所使用 SkeletonData 的 attachment 数据,所以所有 Spine 组件都会受到影响。
|
||||
|
||||
如果你只想替换其中一个组件,那么就可以克隆这个 SkeletonData 让每个组件都使用不同的 SkeletonData 实例进行渲染。
|
||||
|
||||
服务包提供了一个克隆数据的接口来实现这个需求:
|
||||
|
||||
```js
|
||||
const clonedSkeletonData = skeletonData.clone();
|
||||
```
|
||||
|
||||
使用以上代码克隆 SkeletonData 后再进行换装,赋值给 Spine 组件,那么替换操作就只会对这个 Spine 组件生效。
|
||||
|
||||
---
|
||||
以上所有用法你可以在 [演示项目](https://smallmain.github.io/cocos-service-pack/demo/v1.0.0/web-desktop/index.html) 中找到示范代码。
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "文本渲染",
|
||||
"position": 2,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "text-render-intro"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 86 KiB |
@@ -0,0 +1,106 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
description: "详细了解该缓存模式重构后的所有新特性。"
|
||||
---
|
||||
# 新的 Char 缓存模式
|
||||
|
||||
在 [新 UI 渲染批次合并指南](../../start-guide/batcher-guide.md#充分利用动态合图) 中提到 Bitmap 与 Char 缓存模式都支持了废弃字符空间复用的特性,但 Char 缓存模式的内部变化比较大,并且提供了一些可调整的设置项,使用上依旧只需要设置缓存模式即可。
|
||||
|
||||
---
|
||||
## 在场景切换时清空所有字符图集
|
||||
|
||||
控制在场景切换时是否会清空所有的字符图集,默认为开启状态。
|
||||
|
||||
```js
|
||||
cc.sp.charAtlasAutoResetBeforeSceneLoad = false;
|
||||
```
|
||||
|
||||
:::tip 提示
|
||||
|
||||
在引擎原来的设计中,该机制不可被关闭,由于旧 Char 缓存模式不支持复用废弃的空间,图集终究会被用完,所以引擎加入了这个治标不治本的功能。
|
||||
|
||||
现在推荐关闭该机制,除非你知道你需要。
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
## 字符图集的数量与内置材质
|
||||
|
||||
现在在内部最多会创建 8 张字符图集,与多纹理材质的最大纹理插槽数一致,如果合理使用缓存模式,8 张应该对所有项目都是足够的。
|
||||
|
||||
在这种情况下,可能发生的事是 Char 缓存模式的组件使用了一个普通材质,这个材质只能使用第一张字符图集进行渲染,那么就会导致其他图集上的字就无法渲染出来了。
|
||||
|
||||
为了解决这个问题,Char 缓存模式会在内部维护一个使用内置多纹理 Effect 着色器的材质,如果你有特殊的用途,可以通过
|
||||
|
||||
```js
|
||||
const material = cc.Label._shareAtlas.material;
|
||||
```
|
||||
|
||||
获取、修改或替换该材质。
|
||||
|
||||
渲染时内部会先判断当前所使用的是否为多纹理材质,是的话判断是否能在材质纹理插槽中找到字符图集纹理,如果有一个判断不满足则会将组件的材质设为内部维护的材质。
|
||||
|
||||
但 Char 字符图集是运行时才创建的,所以**暂时无法在使用 Char 缓存模式时直接设置自定义材质**。
|
||||
|
||||
你可以通过代码创建含有当前所有字符图集纹理的自定义材质来解决这个问题,但内部会不断创建新的字符图集(直到 8 张),所以需注意同步更新这个自定义材质,建议有自定义材质需求时使用 Bitmap 缓存模式。
|
||||
|
||||
---
|
||||
## 与动态图集合批的注意事项
|
||||
|
||||
多纹理材质只有 8 个纹理插槽,默认情况下字符图集自动多纹理合批的数量为 1,也就是说会将第 1 张字符图集纹理放入材质。
|
||||
|
||||
**你可以自己调整这个分配值,但请注意调整的时机。**
|
||||
|
||||
下面举一个例子,假设有一个脚本 `example.ts` 的部分内容是:
|
||||
|
||||
```js
|
||||
|
||||
class Example extends cc.Component {
|
||||
|
||||
onLoad() {
|
||||
// 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 2
|
||||
|
||||
```
|
||||
|
||||
一般情况下,代码位置 2 是当用户脚本被加载时就会被执行,而代码位置 1 可能需要等到引擎首场景加载后的某个时间执行。
|
||||
|
||||
服务包会自动调整动态图集的最大数量,这个调整的时机是在代码位置 2 之后的,所以比如你的项目对 Char 缓存模式使用量比较大时,想尝试将动态图集最大数量调整为 6,自动合批的字符图集数量调整为 2,那么你只需要在代码位置 2 修改字符图集自动多纹理合批的数量:
|
||||
|
||||
```js
|
||||
cc.sp.charAtlasAutoBatchCount = 2;
|
||||
```
|
||||
|
||||
之后服务包会自动将动态图集的最大数量调整为 `8 - 2`,即 6。
|
||||
|
||||
这个自动调整的时机并不意味着你在代码位置 2 修改动态图集的最大数量是无效的,因为一开始动态图集的最大数量为 `-1`,你打印一下可以看到
|
||||
|
||||
```js
|
||||
console.log(cc.dynamicAtlasManager.maxAtlasCount); // -1
|
||||
```
|
||||
|
||||
如果你在代码位置 2 修改了动态图集的最大数量,服务包就不会调整该值了。
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.maxAtlasCount = 5;
|
||||
```
|
||||
|
||||
这时候动态图集的最大数量是 5,字符图集自动多纹理合批的数量依旧默认为 1,多纹理材质会有 2 个空纹理插槽。
|
||||
|
||||
如果这两个数量加起来超过 8 就会使用更多的材质进行渲染,这会导致项目的 Draw Call 数量升高,建议保持加起来的数量不超过 8 张,能保持 1 Draw Call。
|
||||
|
||||
```js
|
||||
cc.dynamicAtlasManager.maxAtlasCount = 13;
|
||||
cc.sp.charAtlasAutoBatchCount = 3;
|
||||
```
|
||||
|
||||
比如上面这个设置,这会使得引擎需要用 2 个材质进行渲染,但是可用的动态图集扩充到了 13 张,Char 能自动合批的图集数量扩充到了 3 张,对于某些项目来说可能并不是一件坏事。
|
||||
|
||||
服务包使用这个 “7 + 1” 的默认值有以下几点原因:
|
||||
|
||||
- 引擎原本就只有 1 张 Char 字符图集
|
||||
- 大多数项目使用 1 张 Char 字符图集是足够的
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
description: "一行代码开启高清文本渲染。"
|
||||
---
|
||||
# 高 DPI 支持
|
||||
|
||||
可阅读 [上手其它新特性](../../start-guide/new-features.md#高-dpi-文本渲染) 了解基本的使用方法,除了注意性能以外,没有其它的注意事项。
|
||||
|
||||
---
|
||||
## 调整全局开关
|
||||
|
||||
使用下面的代码控制组件是否默认开启高 DPI 支持:
|
||||
|
||||
```js
|
||||
cc.sp.enableLabelRetina = false;
|
||||
```
|
||||
|
||||
---
|
||||
## 调整渲染缩放比例
|
||||
|
||||
使用下面的代码调整内部渲染的缩放倍数:
|
||||
|
||||
```js
|
||||
cc.sp.labelRetinaScale = 2;
|
||||
```
|
||||
|
||||
---
|
||||
## 控制单个组件开关
|
||||
|
||||

|
||||
|
||||
除了在编辑器调整,也可以通过代码控制:
|
||||
|
||||
```js
|
||||
// cc.RenderComponent.EnableType
|
||||
// GLOBAL: 全局默认值
|
||||
// ENABLE: 开启
|
||||
// DISABLE: 关闭
|
||||
label.enableRetina = cc.RenderComponent.EnableType.ENABLE;
|
||||
```
|
||||
@@ -0,0 +1,8 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
# 文本渲染
|
||||
|
||||
文本渲染一般是游戏性能优化需要重点关注的地方,并且其显示效果也非常重要,所以服务包提供了以下新特性:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
description: "就像在其它组件里一样使用自定义材质。"
|
||||
---
|
||||
# RichText 自定义材质
|
||||
|
||||

|
||||
|
||||
像往常一样使用即可。
|
||||
@@ -0,0 +1,16 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
# 使用指南
|
||||
|
||||
在 [入门教程](../start-guide/start-guide-intro.mdx) 里,你应该对如何更好地使用安装服务包后的引擎已经有所了解了。
|
||||
|
||||
通过该指南你可以更详细地了解服务包为引擎添加的每个特性与改动:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
|
||||
:::caution 注意
|
||||
|
||||
在几乎所有平台上引擎都是使用 WebGL 渲染模式,所以服务包的大部分特性都未支持引擎的 Canvas 渲染模式,部分特性在 3D 节点下不生效。
|
||||
|
||||
:::
|
||||