mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-09-25 01:32:54 +00:00
完善 docs
This commit is contained in:
@@ -5,9 +5,9 @@ description: "在游戏开发中享受不用关注 Draw Call 的快乐。"
|
||||
|
||||
# 新 UI 渲染批次合并指南
|
||||
|
||||
在官方文档的进阶主题中,有一个 [UI 渲染批次合并指南](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/ui-auto-batch.html),而由于服务包的 **多纹理渲染**、**重构动态图集** 等新特性的出现,有一些内容可能已经过期。
|
||||
在官方文档的进阶主题中,有一个 [UI 渲染批次合并指南](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/ui-auto-batch.html),在服务包的 **多纹理渲染**、**重构动态图集** 等新特性的出现后,对如何合并渲染批次需要有全新的理解。
|
||||
|
||||
如果你未阅读过官方的指南,可以先看一看里面的知识科普部分,而我们将直接从如何实践开始!
|
||||
如果你未阅读过官方的指南,可以先阅读一遍。
|
||||
|
||||
---
|
||||
## 什么是多纹理渲染?
|
||||
@@ -16,19 +16,19 @@ description: "在游戏开发中享受不用关注 Draw Call 的快乐。"
|
||||
|
||||
其根本原因是纹理是使用 uniform 变量传给着色器的,而需要合并批次的话不允许每次渲染都拥有不同的 uniform 变量值。
|
||||
|
||||
服务包实现的合批方法是先设置好多个 uniform 变量,比如将 8 张纹理写入到 "texture1" "texture2" "texture3"... 的 8 个 uniform 变量中,然后编写一个着色器判断应该在渲染时使用哪个 uniform 变量。
|
||||
服务包实现的合批方法是先设置好多个 uniform 变量,比如将 8 张纹理写入到 "texture1" "texture2" "texture3"... 的 8 个 uniform 变量中,然后在着色器里再判断应该在渲染时使用哪个 uniform 变量。
|
||||
|
||||
这样的话如果所有渲染都只用这 8 张纹理的话,就都能合并为 1 个批次。
|
||||
|
||||
这种做法要求设备需要支持采样多个纹理,而在现代绝大多数设备中这不是问题,至少都支持采样 8 张纹理。
|
||||
|
||||
当然除了这种方法,还有另外的一些进行多纹理合批的方法,例如 "Texture Array"、"Bindless",但都有实用性与兼容性的问题。
|
||||
当然除了这种方法,还有另外几种进行多纹理合批的方法,例如 "Texture Array"、"Bindless",但都有实用性与兼容性的问题。
|
||||
|
||||
:::info 提示
|
||||
|
||||
以这种方式实现的多纹理渲染并不是没有弊端的:
|
||||
|
||||
因为会多传递一个顶点属性,并且需要在着色器中去判断该使用哪个纹理,这可能也会造成性能下降,毕竟**合并批次并不一定会提升性能**。
|
||||
因为会多传递一个顶点属性,并且需要在着色器中去判断该使用哪个纹理,导致**合并批次并不一定会提升性能**。
|
||||
|
||||
所以我们建议在多个档次设备中实际测试项目是否使用多纹理渲染的性能差距。
|
||||
|
||||
@@ -43,13 +43,13 @@ description: "在游戏开发中享受不用关注 Draw Call 的快乐。"
|
||||
---
|
||||
## 为你的项目启用动态合图
|
||||
|
||||
在项目之前的开发中,我们可能会关闭动态图集,更倾向于靠静态图集或者自动图集达到降低 Draw Call 的目的。
|
||||
在项目之前的开发中,我们通常会关闭动态图集,更倾向于靠静态图集或者自动图集达到降低 Draw Call 的目的。
|
||||
|
||||
这种选择除了与动态合图存在会占用更多内存的缺点有关之外,更多的是在引擎原来的动态合图中,并不能复用图集的废弃区域,这个重要特性的缺失只能靠在切换场景(Scene)后重置所有图集来解决。
|
||||
导致这个情况最重要的问题是不能复用图集的废弃区域,随着游戏的运行图集会完全用完,引擎只提供了在切换场景(Scene)后重置所有图集的机制来解决这个问题。
|
||||
|
||||
但对于大部分项目来说,这种治标不治本的机制基本等于没有解决这个问题。
|
||||
|
||||
而现在,**服务包几乎重构了整个动态合图系统,解决了以前存在的大部分问题**,你可以启用它了。
|
||||
现在,服务包几乎重构了整个动态合图系统,你可以考虑启用它了。
|
||||
|
||||
:::note 提示
|
||||
|
||||
|
@@ -20,7 +20,7 @@ description: "一般情况下都不需要了解。"
|
||||
|
||||
**大部分项目可以不用关心**。
|
||||
|
||||
```
|
||||
```js
|
||||
cc.macro.ENABLE_NATIVE_TTF_RENDERER = false;
|
||||
```
|
||||
|
||||
|
@@ -14,7 +14,7 @@ description: "了解并上手服务包提供的所有其他新特性。"
|
||||
|
||||
而现在不需要了,高 DPI 文本渲染默认是关闭的,你可以通过
|
||||
|
||||
```
|
||||
```js
|
||||
cc.sp.labelRetinaScale = 2; // 渲染文本时纹理的缩放倍数,默认值为 1.
|
||||
```
|
||||
|
||||
@@ -37,7 +37,7 @@ cc.sp.labelRetinaScale = 2; // 渲染文本时纹理的缩放倍数,默认
|
||||
|
||||
只需要一句代码即可使用 cc.SpriteFrame 替换指定 attachment 的 region 对象:
|
||||
|
||||
```
|
||||
```js
|
||||
this.skel.setRegion('head', 'head', sp.SkeletonData.createRegion(spriteFrame));
|
||||
```
|
||||
|
||||
|
@@ -13,7 +13,7 @@ description: "随心所欲地控制动态合图的使用。"
|
||||
|
||||
你可以通过该接口添加 SpriteFrame 的 Texture 到图集中,内部也是使用该接口。
|
||||
|
||||
```
|
||||
```js
|
||||
cc.dynamicAtlasManager.insertSpriteFrame(spriteFrame);
|
||||
```
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 93 KiB |
@@ -5,4 +5,5 @@ description: "了解如何手动进行多纹理合批。"
|
||||
|
||||
# 多纹理合批
|
||||
|
||||
|
||||
着重介绍管理器。
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
description: "了解实现多纹理渲染的基础。"
|
||||
description: "了解如何手动管理多纹理材质。"
|
||||
toc_max_heading_level: 5
|
||||
---
|
||||
|
||||
# 多纹理材质
|
||||
@@ -11,7 +12,7 @@ description: "了解实现多纹理渲染的基础。"
|
||||
|
||||

|
||||
|
||||
可以看到上面有 `texture` - `texture8` 一共 8 个纹理插槽,将需要使用的纹理拖到上面的插槽即可完成多纹理材质的配置。
|
||||
勾选 `USE_MULTI_TEXTURE` 后可以看到上面有 `texture` - `texture8` 一共 8 个纹理插槽,将需要使用的纹理拖到上面的插槽即可完成多纹理材质的配置。
|
||||
|
||||
## 在组件中使用多纹理材质
|
||||
|
||||
@@ -37,30 +38,84 @@ description: "了解实现多纹理渲染的基础。"
|
||||
|
||||
## 自定义多纹理材质
|
||||
|
||||
上面介绍的多纹理材质都是使用的内置的多纹理 Effect 着色器,**如果你也创建了一个拥有多个纹理插槽的 Effect 着色器,直接使用并不会被直接识别为多纹理材质。**
|
||||
上面介绍的多纹理材质都是使用的内置的多纹理 Effect 着色器,你可以直接在内置多纹理 Effect 着色器的基础上修改。
|
||||
|
||||
除了直接在内置着色器的基础上修改之外,任何着色器中如果存在一个宏 `USE_MULTI_TEXTURE = true`,则会被认为是多纹理材质。
|
||||
|
||||
[演示项目](TODO) 中有自定义材质的示范代码。
|
||||
|
||||
## MultiHandler
|
||||
:::tip 提示
|
||||
|
||||
这个是服务包新增的一个工具类,其主要用处是便捷、高性能地管理多纹理材质上面的所有纹理。
|
||||
是否为多纹理材质的判断逻辑流程:
|
||||
|
||||
虽然你可以直接通过 `cc.Material` 上的接口来设置纹理插槽,但是出于性能考虑,**多纹理材质必须使用该类实例来进行纹理增删改的相关操作,否则可能导致不能正确渲染。**
|
||||
1. 获取材质当前使用的 Technique 中的第一个 Pass
|
||||
2. 判断这个 Pass 是否 `USE_MULTI_TEXTURE = true`
|
||||
3. 是的话,这个材质即为多纹理材质
|
||||
|
||||
它有以下接口:
|
||||
在某些情况下通过代码修改材质可能需要调用 `material.updateMultiSupport()` 来触发这个流程。
|
||||
|
||||
### `setTexture(index: number, texture: cc.Texture2D): void`
|
||||
:::
|
||||
|
||||
设置纹理插槽上的纹理,
|
||||
## 通过代码设置纹理插槽
|
||||
|
||||
每个多纹理材质都对应着一个多纹理材质管理器,这是服务包新增的一个工具类,其主要用处是便捷、高性能地管理多纹理材质上面的纹理插槽。
|
||||
|
||||
当我们说 “多纹理材质” 时,指的是持有 `cc.sp.MultiHandler` 实例的材质。
|
||||
通过 `material.getMultiHandler()` 可以获取到管理器实例,请使用这个实例来操作多纹理材质的纹理插槽。
|
||||
|
||||
并且使用内置多纹理 Effect 着色器的材质会自动持有一个 `cc.sp.MultiHandler` 实例。
|
||||
比如:
|
||||
|
||||
也就是说**使用自行创建的有多个纹理插槽着色器的材质不会被直接识别为多纹理材质。**
|
||||
```js
|
||||
// 获取管理器实例
|
||||
const handler = material.getMultiHandler();
|
||||
|
||||
:::tip
|
||||
// 设置 `texture` 纹理插槽
|
||||
handler.setTexture(0, texture);
|
||||
|
||||
// 置空 `texture2` 纹理插槽
|
||||
handler.setTexture(1, null);
|
||||
|
||||
##
|
||||
// 直接移除指定纹理
|
||||
handler.removeTexture(texture.getImpl());
|
||||
```
|
||||
|
||||
从上面的代码中可以看出操作纹理插槽的时候并不是传入插槽的名称,而是需要提供下标。
|
||||
|
||||
下标 `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);
|
||||
```
|
||||
|
||||
但是这么做好像没有什么意义。
|
||||
|
@@ -13,7 +13,7 @@
|
||||
--ifm-color-primary-light: #6440b1;
|
||||
--ifm-color-primary-lighter: #6943b9;
|
||||
--ifm-color-primary-lightest: #7b59c3;
|
||||
--ifm-code-font-size: 80%;
|
||||
--ifm-code-font-size: 85%;
|
||||
--ifm-code-padding-horizontal: 0.3rem;
|
||||
--ifm-global-radius: 0.3rem;
|
||||
--ifm-code-border-radius: 0.2rem;
|
||||
|
Reference in New Issue
Block a user