更新至 1.1.0 版本文档

This commit is contained in:
SmallMain 2022-07-13 00:18:48 +08:00
parent e49aac8036
commit b575b856a9
74 changed files with 2249 additions and 9 deletions

View File

@ -37,10 +37,10 @@
### 准备压缩包
1.将对 engine 的改动整合到 Git Patch然后将 Patch 按相应的引擎目录放置在 `patches` 目录并放在压缩包根目录内。
2.编译 JavaScript 引擎和原生模拟器,再将三个引擎目录放到压缩包根目录内,包括类型提示文件
3.`enhance-kit-support` 目录放在压缩包根目录内
4.更新文档的更新日志
5.删除 `engine` 目录中的 `node_modules` 目录,可能导致解压失败
2.删除 `cocos2d-x` 目录中的 `build/build` 目录,没有用处,删除 `engine` 目录中的 `node_modules` 目录,可能导致解压失败
3.编译 JavaScript 引擎和原生模拟器,再将三个引擎目录放到压缩包根目录内,包括类型提示文件
4.`enhance-kit-support` 目录放在压缩包根目录内
5.更新文档的更新日志
### 发布压缩包

View File

@ -30,6 +30,7 @@
- [功能演示](#功能演示)
- [使用方法](#使用方法)
- [更新日志](#更新日志)
- [Enhance Kit v1.1.0](#enhance-kit-v110)
- [Enhance Kit v1.0.0](#enhance-kit-v100)
- [贡献指南](#贡献指南)
- [常见问题](#常见问题)
@ -69,6 +70,13 @@
## 更新日志
### Enhance Kit v1.1.0
- **[新特性] 动态合图在符合条件的情况下会忽略 padding 将纹理加入动态图集**
- [修复] 修复动态图集 maxFrameSize 能设置为超出图集尺寸大小的问题
- [修复] 修复 Spine 动态合图时未判断 attachment 是否存在 region 对象导致报错的问题
- [修复] 修复 Android 平台打包出现 Implicit instantiation of undefined template 错误
### Enhance Kit v1.0.0
- **[新特性] 支持多纹理渲染**

View File

@ -5,9 +5,9 @@ description: "需掌握一定的自定义引擎知识。"
# 手动安装
## Enhance Kit v1.0.0
## 下载 Enhance Kit 压缩包
适配 Cocos Creator v2.4.9 版本,[点此下载增强包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.0.0)
[点此下载压缩包](../update-log.md)
---
## 标准安装

View File

@ -59,6 +59,13 @@ hide_title: true
## 更新日志
### Enhance Kit v1.1.0
- **[新特性] 动态合图在符合条件的情况下会忽略 padding 将纹理加入动态图集**
- [修复] 修复动态图集 maxFrameSize 能设置为超出图集尺寸大小的问题
- [修复] 修复 Spine 动态合图时未判断 attachment 是否存在 region 对象导致报错的问题
- [修复] 修复 Android 平台打包出现 Implicit instantiation of undefined template 错误
### Enhance Kit v1.0.0
- **[新特性] 支持多纹理渲染**
@ -72,7 +79,7 @@ hide_title: true
- [修复] CHAR 缓存模式 hash 计算可能会有重复的问题
- [调整] 默认禁用 Label 原生 TTF 渲染器
[点此](https://smallmain.gitee.io/cocos-enhance-kit/docs/update-log) 查看所有的更新日志。
[点此](./update-log) 查看所有的更新日志。
## 贡献指南

View File

@ -4,10 +4,20 @@ sidebar_position: 7
# 更新日志
---
## Enhance Kit v1.1.0
适配 Cocos Creator v2.4.9 版本,[点此下载压缩包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.1.0)
- **[新特性] 动态合图在符合条件的情况下会忽略 padding 将纹理加入动态图集**
- [修复] 修复动态图集 maxFrameSize 能设置为超出图集尺寸大小的问题
- [修复] 修复 Spine 动态合图时未判断 attachment 是否存在 region 对象导致报错的问题
- [修复] 修复 Android 平台打包出现 Implicit instantiation of undefined template 错误
---
## Enhance Kit v1.0.0
适配 Cocos Creator v2.4.9 版本,[点此下载增强包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.0.0)
适配 Cocos Creator v2.4.9 版本,[点此下载压缩包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.0.0)
- **[新特性] 支持多纹理渲染**
- **[新特性] 重构动态图集,支持多个新特性**

View File

@ -35,8 +35,11 @@ const config = {
({
docs: {
sidebarPath: require.resolve('./sidebars.js'),
includeCurrentVersion: false,
includeCurrentVersion: true,
versions: {
"1.1.0": {
label: "v1.1.0",
},
"1.0.0": {
label: "v1.0.0",
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,9 @@
{
"label": "安装指南",
"position": 2,
"collapsed": false,
"link": {
"type": "doc",
"id": "installation-intro"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,68 @@
---
sidebar_position: 1
description: "推荐使用此方式进行一键安装。"
---
# 使用引擎扩展安装
---
## 前往 Cocos Store 下载
在 Cocos Store 搜索名为 **Cocos Enhance Kit** 的引擎扩展,或者 [点此跳转](https://store.cocos.com/app/detail/3824)。
这个扩展不是免费的,**但其唯一的作用就是帮助你管理增强包的版本(查看、安装和卸载增强包)。**
:::tip 常见问题
- **Enhance Kit 不是开源项目吗???**
Enhance Kit 是完全开源的项目,这个引擎扩展只会为你提供自动化的安装方式,以后也只会有版本管理方面的功能。
你可以选择 [手动安装](./installation-manual.md),也只需要几步即可完成。
- **如何反馈有关这个扩展的问题或建议**
若遇到与这个扩展相关的问题或者建议,不要在增强包的 Github 仓库反馈,请在扩展的 **商店评论区** 进行反馈。
因为这个扩展的收益是个人的,所以也只由个人维护。
:::
---
## 查询信息
安装好扩展后,可在 Cocos Creator 的菜单栏依次点击 **扩展 - 增强包管理 - 查看信息**,会打印当前环境信息。
![plugin-info](./assets/plugin-info.png)
你可以看到当前引擎版本支持一键安装的增强包版本,已安装的增强包版本等信息。
---
## 一键安装
安装好扩展后,可在 Cocos Creator 的菜单栏依次点击 **扩展 - 增强包管理 - 安装增强包 - 安装最新版本**,会自动开始安装增强包。
![plugin-install](./assets/plugin-install.png)
:::note 扩展做了什么事
扩展帮您自动完成了手动安装时需要做的所有步骤,包括自定义引擎和放置 TypeScript 类型提示文件。
:::
预览项目并检查 Devtools Console 打印的是否为 `Cocos Creator SP v2.4.x`,是的话则已经成功安装。
![installedconsole](./assets/installed-console.png)
接下来推荐你从 [入门教程](../start-guide/start-guide-intro.mdx) 开始了解增强包为你的开发都带来了哪些新特性!
---
## 更多特性
在增强包发布新版本之后,你可能还没做好升级的准备,这时候你可以点击 **扩展 - 增强包管理 - 安装增强包 - 安装其它版本** 安装增强包的历史版本。
该扩展会收录增强包发布过的所有版本。
增强包只会适配引擎的最新版本,如果你需要在其它引擎版本上安装增强包,一般需要手动使用 Git Patch。
之后扩展可能会额外适配更多的引擎版本,这取决于大家具体的需求如何。

View File

@ -0,0 +1,14 @@
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
# 安装指南
增强包主要使用 [自定义引擎](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/engine-customization.html) 的方式对引擎进行修改。
但由于自定义引擎不能添加内置资源与扩展内置组件的 Inspector所以还需要安装配套的引擎扩展。
对于使用 TypeScript 的项目,增强包提供了 `creator-sp.d.ts` 类型提示文件。
以下是两种常用的安装方式:
<DocCardList items={useCurrentSidebarCategory().items}/>

View File

@ -0,0 +1,109 @@
---
sidebar_position: 2
description: "需掌握一定的自定义引擎知识。"
---
# 手动安装
## 下载 Enhance Kit 压缩包
[点此下载压缩包](../update-log.md)
---
## 标准安装
**请确保您的项目所使用的引擎版本与增强包适配的引擎版本一致,否则请使用 [补丁安装](#补丁安装)。**
:::tip 提示
建议升级到最新的引擎版本,官方只会对 2.x 版本只会进行维护性更新,所以不用担心其稳定性问题。
如果你的项目引擎版本较低,可以看一看 [使用引擎扩展安装](./installation-engine-plugin.md) ,支持对多个引擎版本进行一键安装。
:::
### 1.替换自定义引擎
下载增强包后,解压压缩包可以看到压缩包内的 `engine` `cocos2d-x` `jsb-adapter` 这三个目录分别是已经整理好的 **JavaScript 引擎**、**Cocos2d-x 引擎** 和 **jsb-adpater**
接着打开 Cocos Creator 菜单的 **项目 - 项目设置 - 自定义引擎**
分别填写 **JavaScript 引擎路径**(对应 `engine` 目录)和 **Cocos2d-x 引擎路径**(对应 `cocos2d-x` 目录)。
![custom-engine](./assets/custom-engine.png)
然后点击 Cocos Creator 主界面右上角的 **编辑器** 按钮,进入到编辑器的资源目录。
![ide-cocos-path](./assets//ide-cocos-path.png)
接着使用压缩包内的 `jsb-adapter` 替换掉编辑器的 `Resources/builtin/jsb-adapter` 目录。
:::info 提示
如果你的项目不需要在原生平台上运行,则只定制 JavaScript 引擎即可。
:::
### 2.安装引擎扩展
:::caution 注意
**请勿将此引擎扩展与 [使用引擎扩展安装](./installation-engine-plugin) 中的引擎扩展混淆!**
**该扩展提供了必需的内置资源,是增强包开源的一部分,请勿同时安装两个引擎扩展,这会引起冲突!**
:::
压缩包内 `enhance-kit-support` 目录即是扩展本身,将其放到项目的 `packages` 目录即可。
增强包需要使用名为 `sp` 的 AssetBundle 存放资源,如果你的项目有使用 AssetBundle请**确保该名称未被占用**。
没有必要将这个 Asset Bundle 设为远程包或者 Zip 压缩,里面只有 Effect 着色器资源。
更多详情可阅读官方的 [安装扩展](https://docs.cocos.com/creator/2.4/manual/zh/extension/install-and-share.html) 文档。
### 3.TypeScript 类型提示(可选)
如果你的项目使用 TypeScript可将压缩包内 `creator-sp.d.ts` 文件拷贝到项目根目录中。
![dts](assets/dts.png)
部分代码编辑器可能需要重启之后类型提示才会生效。
### 4.重启 Cocos Creator
完成以上的步骤后重启 Cocos Creator。
可在项目预览时检查 Devtools Console 打印的是否为 `Cocos Creator SP v2.4.x`,是的话则已经成功安装。
![](./assets/installed-console.png)
接下来推荐你从 [入门教程](../start-guide/start-guide-intro.mdx) 开始了解增强包为你的开发都带来了哪些新特性!
---
## 补丁安装
:::caution 提示
**建议至少将 Cocos Creator 升级到 v2.4.x 版本,增强包所做的改动不保证对 v2.4 版本以下的兼容性。**
补丁安装需要掌握一定的 [Git](https://git-scm.com/doc) 知识和修改引擎源码的能力。
:::
补丁安装实际上就是打 Git Patch**在压缩包内的 `patches` 目录放着最新的 Git Patch 文件。**
这种方式理论上可以在任意版本的引擎上进行,但由于这种方式如果需要正确的进行下去本就需要你拥有相关的知识与能力,所以我们不会说的很细致。
Git Patch 存储了我们所有的源码提交信息,所以你可以只挑选你想要的提交进行应用,在引擎目录去打补丁文件就等同于应用了我们对引擎的改动,之后就可以按照官方的自定义引擎文档去使用了。
打补丁一般使用两种命令:
- 直接提交使用 `git am`
- 只将改动保留到工作区使用 `git apply`
最好在打补丁时加上输出详细信息的命令参数以更好地确认补丁应用的情况。
常见的问题是我们在仓库的 `engine`、`jsb-adapter`、`cocos2d-x` 文件夹存放源码,那么提供的补丁文件对源码的应用路径也会是 `./engine` 这样的二级目录,如果你直接在引擎目录应用补丁,可能会发生没反应、补丁被跳过的问题,需要使用相应的命令参数来修正补丁应用的路径。
在完成自定义引擎的工作后,请别忘了安装引擎扩展哦。(可参考[标准安装的第 2 步](#2安装引擎扩展)进行操作)。

View File

@ -0,0 +1,114 @@
---
sidebar_position: 1
title: 介绍
hide_title: true
---
![logo](/img/logo2.png)
这是一个提供 Cocos Creator 引擎特性增强、修复与优化的**开源非官方增强包**。
该项目使用自定义引擎的方式在符合原始引擎架构设计的基础上为 Cocos Creator 引擎加入新的特性、修复已知问题以及性能优化。
正因为如此,增强包中的大部分特性能像升级引擎版本一样无需改动项目代码即可生效。
:::info 项目的起源
2021 年 2 月Cocos 发布 Cocos Creator 3.0,之后不会再开发 2.x 版本的新特性,但 2.x 在一些方面还并不完善,所以这个非官方的引擎“魔改”合集应运而生。
给项目取名的时候想到相似的事情发生在 2014 年 4 月,官方停止了对 Windows XP 的维护,之后 Harkaz 发布了一个非官方增强包 Service Pack 4 (SP4)。
受到这个命名的启发,遂想将项目取名为 Service Pack。
但是这个名字有点怪怪的,最后在 麒麟子(Kylins) 的帮助下我们为项目想到了一个更好的名字Enhance Kit再次感谢 麒麟子(Kylins)。
:::
## 重要特性
- **支持多纹理渲染**(多纹理材质、多纹理合批)
![demo1](/demo-imgs/demo1.png)
- **支持高 DPI 文本渲染**Label、RichText 组件)
![demo4](/demo-imgs/demo4.png)
- **重构动态合图**(支持自动多纹理合批、优化算法、复用废弃空间等特性)
![demo2](/demo-imgs/demo2.png)
- **重构 Label 组件的 CHAR 缓存模式**(支持自动多纹理合批、多图集、复用废弃空间等特性)
![demo3](/demo-imgs/demo3.png)
- **Spine 组件支持与其它组件合批、合入动态图集与 SpriteFrame 换装**
![demo5](/demo-imgs/demo5.png)
## 功能演示
[Web Desktop 演示项目](https://smallmain.gitee.io/cocos-enhance-kit/demo/v1.0.0/web-desktop/index.html)
[Web Mobile 演示项目](https://smallmain.gitee.io/cocos-enhance-kit/demo/v1.0.0/web-mobile/index.html)(请将设备横屏)
:::note 提示
增强包对引擎的改动完全开源,每个改动会带有原理说明文档,当你发现问题时请与我们进行反馈,如果你有兴致,可以默默帅气地提交一个 PR帮助我们一起完善这个项目。
:::
## 使用方法
请阅读文档的 [安装指南](./installation-guide/installation-intro.mdx) 与 [入门教程](./start-guide/start-guide-intro.mdx)。
## 更新日志
### Enhance Kit v1.1.0
- **[新特性] 动态合图在符合条件的情况下会忽略 padding 将纹理加入动态图集**
- [修复] 修复动态图集 maxFrameSize 能设置为超出图集尺寸大小的问题
- [修复] 修复 Spine 动态合图时未判断 attachment 是否存在 region 对象导致报错的问题
- [修复] 修复 Android 平台打包出现 Implicit instantiation of undefined template 错误
### Enhance Kit v1.0.0
- **[新特性] 支持多纹理渲染**
- **[新特性] 重构动态图集,支持多个新特性**
- **[新特性] 重构 cc.Label 的 Char 缓存模式,支持多个新特性**
- **[新特性] 支持高 DPI 文本渲染**
- **[新特性] Spine 组件支持参与动态图集、与其它组件合批、使用 SpriteFrame 换装**
- [新特性] cc.Label、cc.RichText、cc.Sprite、cc.MotionStreak、Spine 组件支持使用多纹理材质,并支持自动切换材质机制
- [新特性] cc.RichText 支持使用自定义材质
- [修复] 直接修改 Effect 的属性不回导致其变体的 hash 值刷新
- [修复] CHAR 缓存模式 hash 计算可能会有重复的问题
- [调整] 默认禁用 Label 原生 TTF 渲染器
[点此](./update-log) 查看所有的更新日志。
## 贡献指南
非常欢迎你能和我们一起来完善这个项目,请通过 Github 进行:
- 如果你发现了问题请建立 `Issues`
- 如果你有好的想法,请进入 `Discussions`
- 如果你有新的代码提交,请建立 `Pull requests`
**原则上你提交的任何修改都不能影响引擎原有功能,不允许删除引擎原有的特性,请认真思考代码设计。**
## 常见问题
### 为什么要直接修改引擎?
直接修改引擎可能是大部分人认为的下下策,比如我们常听到的:
- 可以通过 “修改对象原型” 等编程技巧将改动做成一个插件脚本
- 没接触过自定义引擎,不知道该如何使用
- 已经修改过引擎了,不能直接进行标准安装,会覆盖原有的修改
以上问题我们都思考过,首先,现在引擎的 2.x 版本已经停止了更新(仅做一些维护工作),也就是说修改引擎不会遇到在官方新版本发布后需要用大量时间去适配的情况。
其次,即使增强包的所有改动都能做成一个插件脚本,但无法兼容原生平台,并且一般都需要大量拷贝代码,包体会增大,可维护性会大幅降低。
最后,我们希望它接近 “原生” 的使用体验,就像引擎本来就有的功能一样,对于没有接触过自定义引擎的人,可以通过引擎扩展一键安装。
对于已经修改过引擎的人,由于增强包提供的是 Git Patch所以可以让你在原有的基础上轻松应用增强包的改动你甚至可以只选取你想要的特性进行应用。
### 启动 Cocos Creator 报 Error: Can not parse this input:undefined 错误
这是你可能忘记安装配套的引擎扩展,所以没有找到增强包的内置资源导致的报错。

View File

@ -0,0 +1,9 @@
{
"label": "入门教程",
"position": 3,
"collapsed": false,
"link": {
"type": "doc",
"id": "start-guide-intro"
}
}

View File

@ -0,0 +1,12 @@
---
sidebar_position: 2
description: "极致地减少游戏 Draw Call。"
---
# 进阶合批指南
:::caution TODO
施工中...
:::

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

@ -0,0 +1,177 @@
---
sidebar_position: 1
description: "在游戏开发中享受不用关注 Draw Call 的快乐。"
---
# 新 UI 渲染批次合并指南
在官方文档的进阶主题中有一个 [UI 渲染批次合并指南](https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/ui-auto-batch.html),批次合并一直是游戏开发中重要的优化手段,如果你未阅读过官方的指南,可以先阅读一遍。
**多纹理渲染**、**新动态图集** 等特性出现后,在进行批次合并时可以变得更加简单且自动化。
---
## 什么是多纹理渲染?
在以前的认识里我们知道相邻的节点使用不同的纹理Texture会导致不能合并批次。
其根本原因是纹理是使用 uniform 变量传给着色器的,而需要合并批次的话不允许每次渲染都拥有不同的 uniform 变量值。
增强包实现的是先设置多个 uniform 变量,比如将 8 张纹理写入到 "texture1" "texture2" "texture3"... 的 8 个 uniform 变量中,然后在着色器里再判断应该在渲染时使用哪个 uniform 变量。
这样的话如果所有渲染都只用这 8 张纹理,就都能合并为 1 个批次。
这要求设备支持采样多个纹理,而在现代绝大多数设备中都至少支持采样 8 张纹理,所以这不是问题。
当然除了这种方法,还有另外几种进行多纹理合批的方法,例如 "Texture Array" 和 "Bindless",但都有实用性与兼容性的问题。
:::info 提示
以这种方式实现的多纹理渲染并不是没有弊端的:
因为会多传递一个顶点属性,并且需要在着色器中去判断该使用哪个纹理,导致**合并批次并不一定会提升性能**。
所以我们建议在多个档次设备中实际测试项目是否使用多纹理渲染的性能差距。
如果你对这种技术有所担心,可以看看这些:
**PixiJS 引擎在 2016 年发布的 v4 版本就已经正式实装了多纹理渲染机制** [资料出处](https://medium.com/goodboy-digital/gpu-multi-texture-sprite-batching-21c90ae8f89b)。
**Phaser 引擎在 v4 与 v3 版本都实装了多纹理渲染机制2019 - 2020年**[资料出处](https://www.patreon.com/posts/39665256)。
:::
---
## 启用动态合图
在之前的开发中我们通常会关闭动态图集,更倾向于靠静态图集或者自动图集达到降低 Draw Call 的目的。
不使用动态图集最重要的原因是其不能复用图集的废弃区域,随着游戏的运行动态图集会完全用完。
引擎只提供了在切换场景Scene后重置所有图集的机制来解决这个问题但对于大部分项目来说这种治标不治本的机制基本等于没有解决。
现在,增强包几乎重构了整个动态合图系统,你可以考虑重新启用动态合图了。
:::note 提示
开启动态图集常见的反对意见是:
在部分小游戏平台里,启用动态图集会有保留 Image 对象导致内存占用大的问题。
建议:
- 实际测试是否启用动态图集的内存占用差距。
- 有没有一种可能,只是说可能,内存占用大更多是因为你的项目根本没做任何资源释放呢?
:::
---
## 充分利用动态合图
一般情况下只需要保持动态图集的默认设置即可,如果出现动态图集很多纹理不会打入或者图集很快用完的情况,可以参考以下建议调整。
### 放宽能参与合图的纹理尺寸限制
**动态图集会自动进行多纹理合批,你可以放心地使用多达 7 张图集而不用担心交叉渲染导致的打断批次!**
你可以根据项目的具体情况来放宽能参与合图的纹理尺寸限制。
```js
cc.dynamicAtlasManager.maxFrameSize = 1024; // 推荐 512、1024 甚至 2048
```
:::tip
增强包会自动将图集的最大数量调整至(设备能同时采样纹理数 - Char 缓存模式自动合批图集数),这个值默认为 `7`
:::
### 无需管理动态图集,只需要释放资源
**动态合图会在纹理被释放的同时释放其在动态图集使用的空间。**
如果动态图集的使用量一直在增长,请检查是否做了资源释放,因为你不需要关心动态图集的使用情况,只需要做好应有的资源释放就能保持动态图集的长期有效。
### 更加细致地优化图集的使用效率
除了通过调整纹理的 `packable` 属性可以控制纹理是否会参与动态合图之外,增强包提供了**控制组件是否默认参与动态合图,控制单个组件是否参与动态合图**的新特性。
可前往 [动态合图](../user-guide/dynamic-batcher/dynamic-batcher-intro.mdx) 的文档了解详情。
你可以考虑将纹理尺寸限制放宽到 `2048`,这听起来貌似有点离谱,但只要规划得当确实可行,比如:
- 禁止优化程度有限但尺寸巨大的纹理参与动态合图
- 分模块存放资源,禁止冷门(如活动界面)的纹理参与动态合图或尽早地释放掉
- 在资源太多的项目中,可考虑控制界面的渲染组件是否参与动态合图
完成上面几点这可能需要一些工作量,但能将动态图集用在刀刃上,发挥更大的作用。
---
## Label 不再是合批噩梦
在之前的开发中我们可能会使用字体图集、调整节点顺序、甚至修改渲染流程来解决 Label 的性能问题。
也是因为引擎提供的 Bitmap 和 Char 两种缓存模式在稍大一点的项目上显得力所不及:
- Bitmap 缓存模式:字体纹理会打入动态图集,但动态图集却无法复用,随着游戏的进行,图集用完则直接失去作用。
- Char 缓存模式的缺点:还是无法复用,并且只有一张图集,图集用完则直接无法渲染,应该没人能接受游戏可能跑着跑着字就全部消失了的情况。
但现在你可以使用这两种缓存模式了,增强包重构了 Char 缓存模式,除了解决了不能复用的问题之外,还支持了多纹理渲染,所以既能与动态图集合批,还有最多 8 张字符图集可以使用。
### 脱胎换骨的 Char 缓存模式
**如果你不知道该选择什么缓存模式,那就遇事不决,先选 Char 缓存模式。**
虽然 Char 模式也有一些缺点,但由于它既能与动态图集一起合批,还是是按字符进行复用的,所以相比 Bitmap 模式它有着更高的性能优势。
不用担心字符图集会被用完,内部会用引用计数自动释放废弃字符所占用的空间。
但 Char 缓存模式不适合下面的场景:
- 无法显示带有像 emoji 的字素簇的字符串,这种字符串现在不能被完美地分割成单个字符,所以 Char 缓存模式也就不能正常显示了。
- 接上条,像聊天消息、输入框这类不可控的内容文本都不建议用 Char 缓存模式。
- Char 缓存模式不支持一些字体样式,可以在官方文档中了解详情。
- 巨大的字体大小(比如几百的)可能会瞬间占满整张字符图集,字符图集虽然有 8 张但也不能这么霍霍。
### 兜底的 Bitmap 缓存模式
即使不能选择 Char 缓存模式Bitmap 缓存模式也能成为批次的最后一道防线。
在解决了动态图集的复用问题后Bitmap 缓存模式的纹理也会使用引用计数自动释放,并且不会有 Char 缓存模式无法显示字素簇的问题。
但当然Bitmap 缓存模式也不是万能的,如果遇到了下面这种情况,就需要考虑使用调整节点顺序这样的老办法来解决了:
- 巨大的字体大小也会瞬间占满整张动态图集,动态图集也不能这么霍霍。
- 在大量的 Label 需频繁改变文本的情况下,请使用性能分析工具检查动态图集的性能消耗,避免合批的弊大于利。
:::caution 注意
无论使用哪种缓存模式,在做缩放动画时不要对 `fontSize` 属性进行缓动,这会导致每帧都需要重新生成文字纹理,造成巨大的性能负担,可以使用节点的 `scale` 来代替。
:::
### 注意事项
- **Char 缓存模式所使用的字符图集与动态图集不是一个东西**
有多种因素导致没有让 Char 缓存模式直接使用动态图集来实现,这个原因在 Char 缓存模式的原理文档中有详细解释。
- **Char 缓存模式依然不能在图集用完的情况下正常渲染**
原因有以下几点:
- 我们认为 8 张数量已经够多了8 张都用完的情况大部分是没有合理搭配使用两种缓存模式
- 8 张是多纹理渲染的上限,这意味着如果超过 8 张1 个 Label 有 100 个字,就可能有 100 个 Draw Call
---
## 总结
以上就是新合批指南的全部内容了,稍微总结一下渲染批次合并的几个要点:
- 启用动态合图,只需要合理地释放资源即可保持动态合图的一直有效
- Label 优先使用 Char 缓存模式,不适合则使用 Bitmap 缓存模式
- 不要优先考虑修改节点顺序这种需要维护成本的优化方式
如果你对批次合并还有着更高的需求,可以阅读 [进阶合批指南](./advance-batcher-guide.md)。

View File

@ -0,0 +1,76 @@
---
sidebar_position: 4
description: "一般情况下都不需要了解。"
---
# 破坏性变更
在添加新特性的过程中,就像引擎升级一样,有些变化在所难免,在这里你可以对变更进行评估是否会对项目造成巨大的影响。
---
### 默认禁用原生 TTF 渲染器
引擎的 Label 在使用 Char 缓存模式并且使用 TTF 字体时,会使用一个原生 TTF 渲染器。
这个渲染器理论上能提升原生平台的 Label 性能,但仅在 Char 缓存模式并且还要使用 TTF 字体时才生效,这也导致了在原生平台上字体样式可能与其它平台不一致的问题。
在重构 CHAR 缓存模式时考虑到这些因素和人力有限的原因,我们暂时不打算适配这个原生 TTF 渲染器,所以直接默认禁用了原生 TTF 渲染器,这个禁用是官方提供的接口,不会造成其它问题。
**大部分项目可以不用关心**。
```js
cc.macro.ENABLE_NATIVE_TTF_RENDERER = false;
```
---
### 动态图集的一些变化
对动态图集的重构虽然保留了所有原有的公开接口,但实现细节与以前不同了。
如果你的项目有在细致地管理动态图集,请注意以下几点:
- **如果你有手动修改 `cc.dynamicAtlasManager.maxAtlasCount` 属性,请考虑删除**
增强包会根据设备最大纹理数和 Char 缓存模式字符图集的相关设置自动调整动态合图的最大图集数量。
这不意味着你不能手动调整了,而是建议你阅读新动态图集和新 Char 缓存模式相关的文档后再考虑是否有必要进行调整。
关于这个你可以从 [新 UI 渲染批次合并指南](./batcher-guide.md) 进行了解。
- **动态图集重复纹理的判断从 `texture._id` 改为使用 `texture._uuid`**
具体的设计原因和原理可查看动态合图的原理文档。
- **`cc.dynamicAtlasManager.insertSpriteFrame(spriteFrame)` 不再检查纹理的 `packable` 属性**
并不是说 `packable` 属性无效了,而是 `insertSpriteFrame` 现在作为将纹理强制加入动态图集的接口使用。
- **如果你的项目依赖动态图集的内部实现细节,请重新检查相关代码**
比如你的项目依赖一些动态图集未公开的类或者接口(引擎在 `creator.d.ts` 声明了的则是已经公开的),则可能需要重新编写。
---
### Char 缓存模式的一些变化
对 Char 缓存模式也进行了重构,内部变化比较大。
- **暂不支持自定义材质**
如果项目中有组件在使用 Char 缓存模式并且设置了自定义材质则可能会失效,具体原因可前往 [新的 Char 缓存模式](../user-guide/text-render/text-char-mode.md) 文档进行了解。
- **如果你的项目依赖 Char 缓存模式的内部实现细节,请重新检查相关代码**
比如你的项目依赖一些 Char 缓存模式未公开的类或者接口(引擎在 `creator.d.ts` 声明了的则是已经公开的),则可能需要重新编写。
---
### 材质 Hash 计算的变化
在解决材质本身 Hash 变化不会更新材质变体的 Hash 的问题时,为了兼顾原生平台与 Web 平台,我们采取了使材质本身的 Hash 值不变并且修改变体 Hash 计算方式的方法来解决这个问题。
解决这个问题后,在两个材质变体一样的情况下,无论怎么修改材质,都不会影响该材质的变体进行合批(在这之前,修改材质后生成的变体无法和之前的变体合批,因为 Hash 值问题)。
但这引入了新的问题,这会导致完全相同的两个材质不能合批,比如你复制了一个 `multi-2d-sprite` 材质,分别使用这两个材质的组件不再会进行合批。
我们考虑了性能、影响程度等多方面因素之后采取了这个实现,因为后者比较少见,并且可以手动解决:
你只需要手动设置该材质的 Hash 值为 `multi-2d-sprite` 材质的 Hash 值即可使两个材质合批。

View File

@ -0,0 +1,59 @@
---
sidebar_position: 3
description: "了解并上手增强包提供的所有其他新特性。"
---
# 上手其它新特性
除了前面提到的多纹理渲染、新动态图集、新 Label Char 缓存模式等特性之外,还有一些其它的也很实用的新特性。
---
## 高 DPI 文本渲染
以前我们会使用将 Label 字号放大一倍Label 节点缩小一倍的方式去解决字体模糊的问题。
而现在不需要了,你可以通过一句代码调整渲染比例:
```js
cc.sp.labelRetinaScale = 2; // 渲染文本时纹理的缩放倍数,默认值为 1.
```
![labelscaledemo](./assets/labelscaledemo.png)
> 图片中,上方的是开启后效果,下面是未开启效果。
**推荐你根据设备像素比devicePixelRatio来动态设置该值并且该值不要大于 `2`,这不会带来更好的效果,但却将字体纹理放大了数倍,会影响到游戏整体性能,影响动态图集的效率。**
可前往 [高 DPI 支持](../user-guide/text-render/text-high-dpi.md) 文档了解更多详情。
---
## 使用 SpriteFrame 进行 Spine 换装
官方文档中介绍了替换 attachment 对象进行换装的方法,但如果动画中有切换 attachment 的关键帧,这种方法就失效了。
还有一种方法是修改 attachment 的 region 对象来进行换装,但这种方法引擎没有直接支持,所以增强包对其进行了支持。
只需要一句代码即可使用 cc.SpriteFrame 的数据修改 attachment 的 region 对象数据:
```js
skeletonComponent.setRegionData('Head', 'Head', new sp.RegionData(spriteFrame));
```
![changespine](./assets/changespine.png)
> 图片中是被换头的小男孩。
这样做是直接修改了 SkeletonData 的数据,所有使用该数据的 Spine 组件都会受到影响(被换头),但我们提供了克隆 SkeletonData 数据的接口,可前往 [Spine](../user-guide/spine/spine-intro.mdx) 文档了解更多详情。
:::tip 提示
还有一个小特性Spine 组件也支持了自动参与动态图集,并且也支持了和其它组件合批。
:::
---
## 给 RichText 使用自定义材质
虽然加上去也简单,但这可能是很少用得到的功能,主要还是我们看到几乎所有渲染组件都可以自定义材质,这个组件却不可以。
可前往 [RichText 自定义材质](../user-guide/text-render/text-richtext.md) 文档了解更多详情。

View File

@ -0,0 +1,8 @@
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
# 入门指南
这个教程会简单地介绍如何利用增强包提供的新特性来更好地使用 Cocos Creator 引擎:
<DocCardList items={useCurrentSidebarCategory().items}/>

View File

@ -0,0 +1,9 @@
{
"label": "原理文档",
"position": 5,
"collapsed": true,
"link": {
"type": "doc",
"id": "theory-guide-intro"
}
}

View File

@ -0,0 +1,12 @@
---
sidebar_position: 3
description: "详细了解新 Char 缓存模式的实现方式。"
---
# 新 Char 缓存模式
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,12 @@
---
sidebar_position: 2
description: "详细了解新动态合图的实现方式。"
---
# 新动态合图
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,12 @@
---
sidebar_position: 4
description: "详细了解高 DPI 文本渲染的实现方式。"
---
# 高 DPI 文本渲染
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,12 @@
---
sidebar_position: 1
description: "详细了解多纹理渲染的实现方式。"
---
# 多纹理渲染
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,12 @@
---
sidebar_position: 5
description: "详细了解使 RichText 支持自定义材质的实现方式。"
---
# 使 RichText 支持自定义材质
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,12 @@
---
sidebar_position: 5
description: "详细了解增强 Spine 的实现方式。"
---
# 增强 Spine
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,10 @@
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
# 原理文档
:::caution TODO
施工中...
:::

View File

@ -0,0 +1,45 @@
---
sidebar_position: 6
---
# 卸载指南
增强包不会对项目进行修改,但就像要将引擎降级一样,这种操作还是有风险的,所以我们提供两种卸载方式以供参考:
:::tip 提示
因为原理是一样的,即使是手动安装的增强包,依然可以通过引擎扩展进行卸载,反之亦然。
:::
---
## 使用引擎扩展卸载
请参考 [手动卸载](#手动卸载) 中提到的 **解除代码依赖与资源依赖**,确保项目不再依赖任何增强包的特性之后再卸载。
在 Cocos Creator 的菜单栏依次点击 **扩展 - 增强包管理 - 卸载增强包** 即可。
![plugin-uninstall](./assets/plugin-uninstall.png)
之后重启即可生效。
---
## 手动卸载
### 1.代码依赖
如果你的是 TypeScript 项目,则可以先删除 `creator-sp.d.ts` 文件,让 TypeScript 对使用了增强包接口的代码发出报错。
之后我们要确保所有代码都不再依赖增强包的特性。
### 2.资源依赖
增强包提供了一些内置资源,像是多纹理 Effect 着色器资源,你可以通过查找 UUID 引用将对增强包内置资源的引用全部移除。
### 3.恢复自定义引擎与删除扩展
打开 Cocos Creator 菜单的项目 - 项目设置 - 自定义引擎,勾选使用内置引擎。
点击 Cocos Creator 主界面右上角的 **编辑器** 按钮,进入到编辑器的资源目录。
然后使用未修改过的 `jsb-adapter` 替换掉编辑器的 `Resources/builtin/jsb-adapter` 目录,最后将增强包的引擎扩展(比如 `enhance-kit-support` 目录)删除。

View File

@ -0,0 +1,32 @@
---
sidebar_position: 7
---
# 更新日志
---
## Enhance Kit v1.1.0
适配 Cocos Creator v2.4.9 版本,[点此下载压缩包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.1.0)
- **[新特性] 动态合图在符合条件的情况下会忽略 padding 将纹理加入动态图集**
- [修复] 修复动态图集 maxFrameSize 能设置为超出图集尺寸大小的问题
- [修复] 修复 Spine 动态合图时未判断 attachment 是否存在 region 对象导致报错的问题
- [修复] 修复 Android 平台打包出现 Implicit instantiation of undefined template 错误
---
## Enhance Kit v1.0.0
适配 Cocos Creator v2.4.9 版本,[点此下载压缩包](https://github.com/smallmain/cocos-enhance-kit/releases/tag/v1.0.0)
- **[新特性] 支持多纹理渲染**
- **[新特性] 重构动态图集,支持多个新特性**
- **[新特性] 重构 cc.Label 的 Char 缓存模式,支持多个新特性**
- **[新特性] 支持高 DPI 文本渲染**
- **[新特性] Spine 组件支持参与动态图集、与其它组件合批、使用 SpriteFrame 换装**
- [新特性] cc.Label、cc.RichText、cc.Sprite、cc.MotionStreak、Spine 组件支持使用多纹理材质,并支持自动切换材质机制
- [新特性] cc.RichText 支持使用自定义材质
- [修复] 直接修改 Effect 的属性不回导致其变体的 hash 值刷新
- [修复] CHAR 缓存模式 hash 计算可能会有重复的问题
- [调整] 默认禁用 Label 原生 TTF 渲染器

View File

@ -0,0 +1,9 @@
{
"label": "使用指南",
"position": 4,
"collapsed": false,
"link": {
"type": "doc",
"id": "user-guide-intro"
}
}

View File

@ -0,0 +1,9 @@
{
"label": "动态合图",
"position": 3,
"collapsed": true,
"link": {
"type": "doc",
"id": "dynamic-batcher-intro"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -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#与动态图集合批的注意事项) 文档。
> 难道真正的原因是...
>
> ![7的意志](./assets/7.png)
---
## 控制纹理是否参与动态合图
可以在编辑器上调整纹理的 `packable` 属性,或者用代码控制:
```js
texture.packable = false;
```
---
## 控制组件是否参与动态合图
使用下面的代码控制组件是否默认激活动态合图机制,默认为开启:
```js
cc.sp.allowDynamicAtlas = false;
```
也可以控制单组件是否激活动态合图机制:
![dynamic-batch-settings](./assets/dynamic-batch-settings.png)
除了在编辑器调整,也可以通过代码控制:
```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;
```

View File

@ -0,0 +1,10 @@
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
# 动态合图
动态合图是一个非常好的合批手段,但是在之前引擎实现的比较简陋,所以增强包重构了动态合图系统,在原有功能基础上增加了许多重要特性。
比如支持复用废弃碎图空间,优化了图集装箱算法,所有图集作为一个整体进行管理等等,你可以阅读下面的文档了解详情:
<DocCardList items={useCurrentSidebarCategory().items}/>

View File

@ -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 全部恢复。
---
## 更多接口
虽然还暴露了其它接口出来,但因为太过于底层所以不推荐使用,如果你想了解可以阅读原理文档。

View File

@ -0,0 +1,9 @@
{
"label": "多纹理渲染",
"position": 1,
"collapsed": true,
"link": {
"type": "doc",
"id": "multi-render-intro"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -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;
```
默认情况下组件会使用全局值,你可以控制单个组件是否强制启用/禁用该机制:
![autoswitchsettings](./assets/autoswitch-settings.png)
除了在编辑器调整,也可以通过代码控制:
```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) 中有提供一些常见的使用案例。

View File

@ -0,0 +1,137 @@
---
sidebar_position: 1
description: "了解如何手动管理多纹理材质。"
toc_max_heading_level: 5
---
# 多纹理材质
增强包在引擎内置了可以直接使用的多纹理 Effect 着色器资源,并且你可以直接使用多纹理材质而不需要编写任何代码。
---
## 创建多纹理材质
你可以正常创建一个材质文件Effect 选择内置的多纹理 Effect 着色器 `multi-2d-universal` 即可。
![material-settings](./assets/material-settings.png)
勾选 `USE_MULTI_TEXTURE` 后可以看到上面有 `texture` - `texture8` 一共 8 个纹理插槽,将需要使用的纹理拖到上面的插槽即可完成多纹理材质的配置。
---
## 在组件中使用多纹理材质
直接拖到组件的 `Materials` 属性上即可。
![material-comp](./assets/material-comp.png)
注意上图中已经在 `cc.Sprite` 组件拖入了刚刚创建的多纹理材质,并且其 `SpriteFrame` 属性设置的是材质中 `texture3` 插槽中的纹理。
![material-final](./assets/material-final.png)
你不需要指定组件要使用的纹理插槽 id组件内部在渲染前会自动查找纹理在材质中的 id。
:::caution 警告
如果组件使用的纹理在材质中找不到,为了保证渲染的正常(毕竟性能只是锦上添花)会在组件的材质变体中将纹理设置到 `texture` 插槽中。
这会导致这个组件的多纹理材质变体之后都不能按预期进行合批,就像 “退化” 成了普通材质。
所以使用时必须要确保纹理在材质中,假如材质变体已经 “退化” 了,那你可以通过重新设置材质的方式使组件持有一个新的材质变体。
:::
:::caution 特别注意
Spine 组件使用多纹理材质时会强制勾选 `enableBatch`,因为不开启就不能合批,那也就没必要使用多纹理材质。
:::
---
## 自定义多纹理材质
上面介绍的多纹理材质都是使用的内置的多纹理 Effect 着色器,你可以直接在内置多纹理 Effect 着色器的基础上修改。
除了直接在内置着色器的基础上修改之外,任何着色器中如果存在一个宏 `USE_MULTI_TEXTURE = true`,则会被认为是多纹理材质。
[演示项目](https://smallmain.gitee.io/cocos-enhance-kit/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);
```
没有特殊情况不需要这么做。

View File

@ -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 组件可以相互代替,所以暂时不支持该组件。
:::

View File

@ -0,0 +1,9 @@
{
"label": "Spine",
"position": 4,
"collapsed": true,
"link": {
"type": "doc",
"id": "spine-intro"
}
}

View File

@ -0,0 +1,14 @@
---
sidebar_position: 2
description: "像其它渲染组件一样在 Spine 组件上使用动态合图。"
---
# 动态合图
你可以像其它渲染组件一样在 Spine 组件上使用动态合图,如果想了解有关动态合图的更多详情,可以阅读 [动态合图](../dynamic-batcher/dynamic-batcher-intro.mdx) 文档。
:::caution 注意
由于引擎实现差异,在原生平台上 Spine 暂不支持与其它组件合批。
:::

View File

@ -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 的原理文档。
:::

View File

@ -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 与 regionRegionData 主要作为 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.gitee.io/cocos-enhance-kit/demo/v1.0.0/web-desktop/index.html) 中找到示范代码。

View File

@ -0,0 +1,9 @@
{
"label": "文本渲染",
"position": 2,
"collapsed": true,
"link": {
"type": "doc",
"id": "text-render-intro"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -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 字符图集是足够的

View File

@ -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;
```
---
## 控制单个组件开关
![reinasettings](./assets/reina-settings.png)
除了在编辑器调整,也可以通过代码控制:
```js
// cc.RenderComponent.EnableType
// GLOBAL: 全局默认值
// ENABLE: 开启
// DISABLE: 关闭
label.enableRetina = cc.RenderComponent.EnableType.ENABLE;
```

View File

@ -0,0 +1,8 @@
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
# 文本渲染
文本渲染一般是游戏性能优化需要重点关注的地方,并且其显示效果也非常重要,所以增强包提供了以下新特性:
<DocCardList items={useCurrentSidebarCategory().items}/>

View File

@ -0,0 +1,9 @@
---
sidebar_position: 3
description: "就像在其它组件里一样使用自定义材质。"
---
# RichText 自定义材质
![richtextsettings](./assets/richtext-settings.png)
像往常一样使用即可。

View File

@ -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 节点下不生效。
:::

View File

@ -0,0 +1,8 @@
{
"tutorialSidebar": [
{
"type": "autogenerated",
"dirName": "."
}
]
}

View File

@ -1,3 +1,4 @@
[
"1.1.0",
"1.0.0"
]

View File

@ -0,0 +1,129 @@
"use strict";
Vue.component("cc-label", {
dependencies: ["packages://inspector/share/blend.js"],
template: `
<ui-prop
v-prop="target.string"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.horizontalAlign"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.verticalAlign"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.actualFontSize"
v-show="!_hiddenActualFontSize()"
:multi-values="multi"
></ui-prop>
<ui-prop type="number"
v-prop="target.fontSize">
:multi-values="multi"
</ui-prop>
<ui-prop
v-prop="target._bmFontOriginalSize"
v-show="_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.lineHeight"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.spacingX"
v-show="_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.overflow"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.enableWrapText"
v-show="!_hiddenWrapText()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.font"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.fontFamily"
v-show="_isSystemFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.enableBold"
v-show="!_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.enableItalic"
v-show="!_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.enableUnderline"
v-show="!_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.underlineHeight"
v-show="!_isBMFont() && target.enableUnderline.value === true"
:indent="1"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.cacheMode"
v-show="!_isBMFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.useSystemFont"
:multi-values="multi"
></ui-prop>
<cc-blend-section :target.sync="target"></cc-blend-section>
<cc-array-prop
v-show="!_isCharCacheMode()"
:target.sync="target.materials"
></cc-array-prop>
<ui-prop v-prop="target.autoSwitchMaterial"></ui-prop>
<ui-prop v-prop="target.allowDynamicAtlas"></ui-prop>
<ui-prop v-prop="target.enableRetina"></ui-prop>
`,
props: {
target: {
twoWay: !0,
type: Object
},
multi: {
type: Boolean
}
},
methods: {
T: Editor.T,
_isBMFont() {
return this.target._bmFontOriginalSize.value > 0
},
_isSystemFont() {
return this.target.useSystemFont.value
},
_hiddenWrapText() {
let t = this.target.overflow.value;
return 0 === t || 3 === t
},
_hiddenActualFontSize() {
return 2 !== this.target.overflow.value
},
_isCharCacheMode() {
return 2 === this.target.cacheMode.value
},
}
});

View File

@ -0,0 +1,73 @@
"use strict";
Vue.component("cc-richtext", {
template: `
<ui-prop
v-prop="target.string"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.horizontalAlign"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.fontSize">
:multi-values="multi"
</ui-prop>
<ui-prop
v-prop="target.font"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.fontFamily"
v-show="_isSystemFont()"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.useSystemFont"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.cacheMode"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.maxWidth"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.lineHeight"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.imageAtlas"
:multi-values="multi"
></ui-prop>
<ui-prop
v-prop="target.handleTouchEvent"
:multi-values="multi"
></ui-prop>
<ui-prop v-show="!_isCharCacheMode()" v-prop="target.customMaterial"></ui-prop>
<ui-prop v-prop="target.autoSwitchMaterial"></ui-prop>
<ui-prop v-prop="target.allowDynamicAtlas"></ui-prop>
<ui-prop v-prop="target.enableRetina"></ui-prop>
`,
props: {
target: {
twoWay: !0,
type: Object
},
multi: {
type: Boolean
}
},
methods: {
T: Editor.T,
_isSystemFont() {
return this.target.useSystemFont.value
},
_isCharCacheMode() {
return 2 === this.target.cacheMode.value
},
}
});

View File

@ -0,0 +1,155 @@
"use strict";
Vue.component("cc-sprite", {
dependencies: ["packages://inspector/share/blend.js"],
template: `
<ui-prop
style="padding-top: 8px"
name="Atlas"
tooltip="{{T('COMPONENT.sprite.atlas')}}"
>
<ui-asset class="flex-1"
type="sprite-atlas"
v-value="target._atlas.value.uuid"
v-values="atlasUuids"
:multi-values="atlasMulti"
></ui-asset>
<ui-button
class="blue tiny"
tooltip="{{T('COMPONENT.sprite.select_tooltip')}}"
@confirm="selectAtlas"
>
{{T('COMPONENT.sprite.select_button')}}
</ui-button>
</ui-prop>
<ui-prop
style="padding-top: 8px"
name="Sprite Frame"
tooltip="{{T('COMPONENT.sprite.sprite_frame')}}"
>
<ui-asset class="flex-1"
type="sprite-frame"
v-value="target.spriteFrame.value.uuid"
v-values="spriteUuids"
:multi-values="spriteMulti"
></ui-asset>
<ui-button
class="blue tiny"
tooltip="{{T('COMPONENT.sprite.edit_tooltip')}}"
@confirm="editSprite"
>
{{T('COMPONENT.sprite.edit_button')}}
</ui-button>
</ui-prop>
<ui-prop
v-prop="target.type"
:multi-values="multi"
></ui-prop>
<div v-if="isFilledType()">
<ui-prop indent=1
v-prop="target.fillType"
:multi-values="multi"
></ui-prop>
<ui-prop indent=1
v-prop="target.fillCenter"
v-disabled="!isRadialFilled()"
:multi-values="multi"
></ui-prop>
<ui-prop indent=1
v-prop="target.fillStart"
:multi-values="multi"
></ui-prop>
<ui-prop indent=1
v-prop="target.fillRange"
:multi-values="multi"
></ui-prop>
</div>
<ui-prop
v-prop="target.sizeMode"
:multi-values="multi"
></ui-prop>
<ui-prop v-if="allowTrim()"
v-prop="target.trim"
:multi-values="multi"
></ui-prop>
<cc-blend-section :target.sync="target"></cc-blend-section>
<cc-array-prop :target.sync="target.materials"></cc-array-prop>
<ui-prop v-prop="target.autoSwitchMaterial"></ui-prop>
<ui-prop v-prop="target.allowDynamicAtlas"></ui-prop>
`,
props: {
target: {
twoWay: !0,
type: Object
},
multi: {
twoWay: !0,
type: Boolean
}
},
data: ()=>({
atlasUuid: "",
atlasUuids: "",
atlasMulti: !1,
spriteUuid: "",
spriteUuids: "",
spriteMulti: !1
}),
created() {
this.target && (this._updateAtlas(),
this._updateSprite())
},
watch: {
target() {
this._updateAtlas(),
this._updateSprite()
}
},
methods: {
T: Editor.T,
selectAtlas() {
Editor.Ipc.sendToPanel("assets", "change-filter", "t:sprite-atlas")
},
editSprite() {
Editor.Panel.open("sprite-editor", {
uuid: this.target.spriteFrame.value.uuid
})
},
allowTrim() {
return this.target.type.value === cc.Sprite.Type.SIMPLE
},
isFilledType() {
return this.target.type.value === cc.Sprite.Type.FILLED
},
isRadialFilled() {
return this.target.fillType.value === cc.Sprite.FillType.RADIAL
},
_updateAtlas() {
if (!this.target)
return this.atlasUuid = "",
this.atlasUuids = "",
this.atlasMulti = !1,
void 0;
this.atlasUuid = this.target._atlas.value.uuid,
this.atlasUuids = this.target._atlas.values.map(t=>t.uuid);
var t = this.atlasUuids[0];
this.atlasMulti = !this.atlasUuids.every((i,e)=>0 === e || i === t)
},
_updateSprite() {
if (!this.target)
return this.spriteUuid = "",
this.spriteUuids = "",
this.spriteMulti = !1,
void 0;
this.spriteUuid = this.target.spriteFrame.value.uuid,
this.spriteUuids = this.target.spriteFrame.values.map(t=>t.uuid);
var t = this.spriteUuids[0];
this.spriteMulti = !this.spriteUuids.every((i,e)=>0 === e || i === t)
}
}
});

View File

@ -0,0 +1,3 @@
'use strict';
module.exports = {};

View File

@ -0,0 +1,16 @@
{
"name": "enhance-kit",
"version": "1.1.0",
"description": "This extension provides support for cocos enhance kit.",
"author": "SmallMain",
"main": "main.js",
"runtime-resource": {
"path": "resources",
"name": "resources"
},
"reload": {
"ignore": [
"resources/**/*"
]
}
}

View File

@ -0,0 +1,12 @@
{
"ver": "1.1.2",
"uuid": "74663d94-6782-4dee-9db9-26127ee8b265",
"isBundle": true,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

View File

@ -0,0 +1,12 @@
{
"ver": "1.1.2",
"uuid": "8ee63b7e-0ac8-4cb5-95f0-85278bfd748a",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}

View File

@ -0,0 +1,152 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
texture2: { value: white }
texture3: { value: white }
texture4: { value: white }
texture5: { value: white }
texture6: { value: white }
texture7: { value: white }
texture8: { value: white }
alphaThreshold: { value: 0.5 }
}%
CCProgram vs %{
precision highp float;
#include <cc-global>
#include <cc-local>
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
#if USE_TINT
in vec4 a_color0;
out vec4 v_color0;
#endif
#if USE_TEXTURE
in vec2 a_uv0;
out vec2 v_uv0;
#if USE_MULTI_TEXTURE
in float a_texId;
out float v_texId;
#endif
#endif
void main () {
vec4 pos = vec4(a_position, 1);
#if CC_USE_MODEL
pos = cc_matViewProj * cc_matWorld * pos;
#else
pos = cc_matViewProj * pos;
#endif
#if USE_TEXTURE
v_uv0 = a_uv0;
#if USE_MULTI_TEXTURE
v_texId = a_texId;
#endif
#endif
v_color = a_color;
#if USE_TINT
v_color0 = a_color0;
#endif
gl_Position = pos;
}
}%
CCProgram fs %{
precision highp float;
#include <alpha-test>
#include <texture>
in vec4 v_color;
#if USE_TINT
in vec4 v_color0;
#endif
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
#if USE_MULTI_TEXTURE
in float v_texId;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D texture4;
uniform sampler2D texture5;
uniform sampler2D texture6;
uniform sampler2D texture7;
uniform sampler2D texture8;
#endif
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
#if USE_MULTI_TEXTURE
if(v_texId < 1.0){
CCTexture(texture, v_uv0, o);
} else if(v_texId < 2.0){
CCTexture(texture2, v_uv0, o);
} else if(v_texId < 3.0){
CCTexture(texture3, v_uv0, o);
} else if(v_texId < 4.0){
CCTexture(texture4, v_uv0, o);
} else if(v_texId < 5.0){
CCTexture(texture5, v_uv0, o);
} else if(v_texId < 6.0){
CCTexture(texture6, v_uv0, o);
} else if(v_texId < 7.0){
CCTexture(texture7, v_uv0, o);
} else {
CCTexture(texture8, v_uv0, o);
}
#else
CCTexture(texture, v_uv0, o);
#endif
#endif
#if USE_TINT
vec4 finalColor;
finalColor.a = v_color.a * o.a;
finalColor.rgb = ((o.a - 1.0) * v_color0.a + 1.0 - o.rgb) * v_color0.rgb + o.rgb * v_color.rgb;
ALPHA_TEST(finalColor);
gl_FragColor = finalColor;
#else
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
#endif
}
}%

View File

@ -0,0 +1,17 @@
{
"ver": "1.0.25",
"uuid": "5dcffc18-b913-460e-a0d9-5d74f4cda12b",
"compiledShaders": [
{
"glsl1": {
"vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\nattribute float a_texId;\nvarying float v_texId;\n#endif\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n v_texId = a_texId;\n #endif\n v_color = a_color;\n gl_Position = pos;\n}",
"frag": "\nprecision highp float;\n#if USE_ALPHA_TEST\n uniform float alphaThreshold;\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\nvarying vec4 v_color;\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nvarying float v_texId;\nuniform sampler2D texture;\nuniform sampler2D texture2;\nuniform sampler2D texture3;\nuniform sampler2D texture4;\nuniform sampler2D texture5;\nuniform sampler2D texture6;\nuniform sampler2D texture7;\nuniform sampler2D texture8;\n#endif\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n #if USE_TEXTURE\n if(v_texId < 1.0){\n vec4 texture_tmp = texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture\n texture_tmp.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture_tmp.rgb * texture_tmp.rgb);\n o.a *= texture_tmp.a;\n #else\n o *= texture_tmp;\n #endif\n } else if(v_texId < 2.0){\n vec4 texture2_tmp = texture2D(texture2, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture2\n texture2_tmp.a *= texture2D(texture2, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture2_tmp.rgb * texture2_tmp.rgb);\n o.a *= texture2_tmp.a;\n #else\n o *= texture2_tmp;\n #endif\n } else if(v_texId < 3.0){\n vec4 texture3_tmp = texture2D(texture3, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture3\n texture3_tmp.a *= texture2D(texture3, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture3_tmp.rgb * texture3_tmp.rgb);\n o.a *= texture3_tmp.a;\n #else\n o *= texture3_tmp;\n #endif\n } else if(v_texId < 4.0){\n vec4 texture4_tmp = texture2D(texture4, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture4\n texture4_tmp.a *= texture2D(texture4, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture4_tmp.rgb * texture4_tmp.rgb);\n o.a *= texture4_tmp.a;\n #else\n o *= texture4_tmp;\n #endif\n } else if(v_texId < 5.0){\n vec4 texture5_tmp = texture2D(texture5, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture5\n texture5_tmp.a *= texture2D(texture5, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture5_tmp.rgb * texture5_tmp.rgb);\n o.a *= texture5_tmp.a;\n #else\n o *= texture5_tmp;\n #endif\n } else if(v_texId < 6.0){\n vec4 texture6_tmp = texture2D(texture6, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture6\n texture6_tmp.a *= texture2D(texture6, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture6_tmp.rgb * texture6_tmp.rgb);\n o.a *= texture6_tmp.a;\n #else\n o *= texture6_tmp;\n #endif\n } else if(v_texId < 7.0){\n vec4 texture7_tmp = texture2D(texture7, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture7\n texture7_tmp.a *= texture2D(texture7, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture7_tmp.rgb * texture7_tmp.rgb);\n o.a *= texture7_tmp.a;\n #else\n o *= texture7_tmp;\n #endif\n } else {\n vec4 texture8_tmp = texture2D(texture8, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture8\n texture8_tmp.a *= texture2D(texture8, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture8_tmp.rgb * texture8_tmp.rgb);\n o.a *= texture8_tmp.a;\n #else\n o *= texture8_tmp;\n #endif\n }\n #endif\n o *= v_color;\n ALPHA_TEST(o);\n gl_FragColor = o;\n}"
},
"glsl3": {
"vert": "\nprecision highp float;\nuniform CCGlobal {\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n vec4 cc_time;\n mediump vec4 cc_screenSize;\n mediump vec4 cc_screenScale;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\nin float a_texId;\nout float v_texId;\n#endif\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n v_texId = a_texId;\n #endif\n v_color = a_color;\n gl_Position = pos;\n}",
"frag": "\nprecision highp float;\n#if USE_ALPHA_TEST\n uniform ALPHA_TEST {\n float alphaThreshold;\n };\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\nin vec4 v_color;\n#if USE_TEXTURE\nin vec2 v_uv0;\nin float v_texId;\nuniform sampler2D texture;\nuniform sampler2D texture2;\nuniform sampler2D texture3;\nuniform sampler2D texture4;\nuniform sampler2D texture5;\nuniform sampler2D texture6;\nuniform sampler2D texture7;\nuniform sampler2D texture8;\n#endif\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n #if USE_TEXTURE\n if(v_texId < 1.0){\n vec4 texture_tmp = texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture\n texture_tmp.a *= texture(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture_tmp.rgb * texture_tmp.rgb);\n o.a *= texture_tmp.a;\n #else\n o *= texture_tmp;\n #endif\n } else if(v_texId < 2.0){\n vec4 texture2_tmp = texture(texture2, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture2\n texture2_tmp.a *= texture(texture2, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture2_tmp.rgb * texture2_tmp.rgb);\n o.a *= texture2_tmp.a;\n #else\n o *= texture2_tmp;\n #endif\n } else if(v_texId < 3.0){\n vec4 texture3_tmp = texture(texture3, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture3\n texture3_tmp.a *= texture(texture3, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture3_tmp.rgb * texture3_tmp.rgb);\n o.a *= texture3_tmp.a;\n #else\n o *= texture3_tmp;\n #endif\n } else if(v_texId < 4.0){\n vec4 texture4_tmp = texture(texture4, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture4\n texture4_tmp.a *= texture(texture4, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture4_tmp.rgb * texture4_tmp.rgb);\n o.a *= texture4_tmp.a;\n #else\n o *= texture4_tmp;\n #endif\n } else if(v_texId < 5.0){\n vec4 texture5_tmp = texture(texture5, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture5\n texture5_tmp.a *= texture(texture5, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture5_tmp.rgb * texture5_tmp.rgb);\n o.a *= texture5_tmp.a;\n #else\n o *= texture5_tmp;\n #endif\n } else if(v_texId < 6.0){\n vec4 texture6_tmp = texture(texture6, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture6\n texture6_tmp.a *= texture(texture6, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture6_tmp.rgb * texture6_tmp.rgb);\n o.a *= texture6_tmp.a;\n #else\n o *= texture6_tmp;\n #endif\n } else if(v_texId < 7.0){\n vec4 texture7_tmp = texture(texture7, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture7\n texture7_tmp.a *= texture(texture7, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture7_tmp.rgb * texture7_tmp.rgb);\n o.a *= texture7_tmp.a;\n #else\n o *= texture7_tmp;\n #endif\n } else {\n vec4 texture8_tmp = texture(texture8, v_uv0);\n #if CC_USE_ALPHA_ATLAS_texture8\n texture8_tmp.a *= texture(texture8, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #if INPUT_IS_GAMMA\n o.rgb *= (texture8_tmp.rgb * texture8_tmp.rgb);\n o.a *= texture8_tmp.a;\n #else\n o *= texture8_tmp;\n #endif\n }\n #endif\n o *= v_color;\n ALPHA_TEST(o);\n gl_FragColor = o;\n}"
}
}
],
"subMetas": {}
}