mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-12-19 18:43:51 +00:00
更新 v1.0.0 版本文档
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "多纹理渲染",
|
||||
"position": 1,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "multi-render-intro"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 722 KiB |
Binary file not shown.
|
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 组件可以相互代替,所以暂时不支持该组件。
|
||||
|
||||
:::
|
||||
Reference in New Issue
Block a user