[docs][feat]: 补充微信小游戏渲染与卡牌 Shader 文档
This commit is contained in:
218
modules/frameworks/微信小游戏渲染规则.md
Normal file
218
modules/frameworks/微信小游戏渲染规则.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# 微信小游戏渲染规则
|
||||
|
||||
## 一、定位与适用范围
|
||||
|
||||
本文档定义 StrayFog 接入微信小游戏时需要长期遵守的渲染与 Shader 规则,适用于 Unity URP、手写 Shader、Shader Graph、材质、Shader 变体和 AssetBundle 资源。
|
||||
|
||||
微信小游戏 Unity 快适配以 WebGL/WebAssembly 构建为基础,再由微信转换插件接入小游戏运行环境。Editor、普通 WebGL 和桌面平台表现不能替代微信开发者工具与真机验证。
|
||||
|
||||
本文档不规定具体画面风格,也不替代:
|
||||
|
||||
- [微信小游戏资源接入方案](资源管理/微信小游戏资源接入方案.md)中的 CDN、AssetBundle、缓存和卸载规则。
|
||||
- [相机系统](相机系统/README.md)中的 Base/Overlay Camera Stack 生命周期。
|
||||
- 具体业务项目的 URP Asset、Renderer Feature、质量等级和材质参数。
|
||||
|
||||
## 二、能力基线
|
||||
|
||||
### 2.1 图形 API
|
||||
|
||||
- Unity 2022.3 WebGL 2 对应 OpenGL ES 3.0 级别的渲染能力。
|
||||
- 微信转换配置启用 WebGL 2 时,导出流程必须使用 `OpenGLES3`;关闭时才退回 `OpenGLES2`。
|
||||
- 新项目默认以 WebGL 2 / OpenGLES3 为目标,不为 WebGL 1 主动增加复杂兼容分支。
|
||||
- 若业务必须支持 WebGL 1,应单独确认设备范围、色彩空间、Shader 循环与索引限制,并建立独立真机验收。
|
||||
- 运行时可用 `SystemInfo.graphicsDeviceType`、`SystemInfo.graphicsDeviceName` 和 `SystemInfo.graphicsMemorySize` 记录真实设备能力,不能只读取构建配置。
|
||||
|
||||
### 2.2 平台宏
|
||||
|
||||
Shader 中优先使用 Unity 已定义的图形平台宏:
|
||||
|
||||
```hlsl
|
||||
#if defined(SHADER_API_GLES3)
|
||||
// WebGL 2 / OpenGL ES 3 路径
|
||||
#endif
|
||||
|
||||
#if defined(SHADER_API_MOBILE)
|
||||
// 移动 GPU 低成本路径
|
||||
#endif
|
||||
```
|
||||
|
||||
C# 中微信 SDK 调用继续使用项目约定的 `WeChat` 宏。不要为了 Shader 再建立 `HF_WECHAT_SHADER`、`isMiniGameShader` 等第二套平台开关。
|
||||
|
||||
Shader 平台能力和微信业务 API 是两个边界:
|
||||
|
||||
- Shader 使用图形 API 宏决定可编译能力和质量分支。
|
||||
- C# 使用 `WeChat` 宏隔离微信 SDK。
|
||||
- 不在 Shader 中依赖业务项目名、渠道或微信登录状态。
|
||||
|
||||
## 三、Shader 编写规则
|
||||
|
||||
### 3.1 通用规则
|
||||
|
||||
- URP Shader 必须声明正确的 `RenderPipeline`、`RenderType`、`Queue` 和 `LightMode`。
|
||||
- 手写 URP Shader 的材质属性放入 `UnityPerMaterial` CBUFFER,并保持所有 Pass 布局一致,以兼容 SRP Batcher。
|
||||
- 颜色、法线和普通权重优先使用 `half`;世界坐标、裁剪坐标、深度重建和大范围 UV 计算使用 `float`。
|
||||
- 限制纹理采样、透明叠加、屏幕空间读取、插值变量、动态分支和高次数循环。
|
||||
- 循环次数可确定时使用常量上限;不要依赖无法在 GLES 路径稳定展开的复杂动态循环。
|
||||
- 不使用 Geometry Shader、Tessellation Shader 或桌面平台专属 Shader Model 作为微信小游戏核心表现。
|
||||
- 需要计算深度时必须处理 Reversed-Z、透视除法和线性深度转换,优先使用 URP 提供的深度函数。
|
||||
- 自定义 HLSL 和 Shader Graph Custom Function 必须同时在目标 Unity 版本、WebGL 构建和真机验证,不能只看节点预览。
|
||||
|
||||
### 3.2 Shader Graph
|
||||
|
||||
- Shader Graph 目标必须选择 Universal,并明确 Surface Type、Depth Write、Depth Test、Render Face 和 Cast/Receive Shadows。
|
||||
- Blackboard Keyword 默认选择能剥离未使用组合的定义方式;只有运行时确实会切换所有组合时才保留对应变体。
|
||||
- 控制 Custom Interpolator 数量,避免为少量计算增加大量顶点到片元数据。
|
||||
- 节点预览成功不代表生成的 GLES Shader 一定可用;最终以 WebGL/小游戏构建日志和真机画面为准。
|
||||
- Shader Graph 生成的 Pass 和关键字较多时,应检查生成变体数,不以“图里节点不多”判断成本。
|
||||
|
||||
### 3.3 透明、深度与排序
|
||||
|
||||
- 透明物体默认 `ZWrite Off`,通过 Sorting Layer、Order、Render Queue 或透明排序轴控制顺序。
|
||||
- 只有确实需要参与深度遮挡的透明对象才启用 `ZWrite On`,并验证半透明重叠、Alpha 边缘和粒子遮挡。
|
||||
- 镂空卡片、植被和围栏优先使用 Alpha Clipping 配合深度写入,避免大面积半透明 Overdraw。
|
||||
- 修改 Vertex Position 的 Z 会真实改变几何位置、裁剪和阴影,不等同于只修改透明排序。
|
||||
- 2D/2.5D 场景按 Y 排序时,优先使用 Graphics Settings 的 Custom Axis 或 Renderer 排序字段;只有要与不透明物体进行真实深度测试时才映射顶点深度。
|
||||
- Camera Depth Texture 和 Opaque Texture 会增加带宽或拷贝成本,只在确有深度、水体、折射或屏幕颜色需求时启用。
|
||||
- 使用 Scene Depth 的透明 Shader 必须检查目标相机是否生成深度纹理,以及 Overlay Camera 是否继承了正确结果。
|
||||
|
||||
## 四、URP 与 Renderer 配置
|
||||
|
||||
- 使用单一、明确的 URP Asset 作为微信构建基线,质量等级不得无意覆盖为另一套 Render Pipeline Asset。
|
||||
- 关闭未使用的主光阴影、附加光阴影、软阴影、Light Cookies、HDR、Opaque Texture、Depth Texture 和 Renderer Feature。
|
||||
- Renderer Feature 必须有明确的 LayerMask、Render Queue、Pass Event 和目标 Camera;`LayerMask = 0` 的 Feature 应删除或说明保留原因。
|
||||
- 开启 SRP Batcher,并用 Frame Debugger 或真机渲染分析确认材质布局兼容。
|
||||
- GPU Instancing 只在相同 Mesh/Material 的重复渲染确实受益时启用;必须验证微信目标设备,不把 Editor 批次数直接当作结论。
|
||||
- 移动端默认避免 Deferred;使用 Forward 或项目验证过的 Forward+ 配置。
|
||||
- Render Scale、MSAA、HDR 和后处理一起评估。降低 Render Scale 往往比继续压缩单个片元 Shader 更直接,但必须验证 UI 清晰度。
|
||||
|
||||
## 五、Shader 变体与加载
|
||||
|
||||
### 5.1 变体控制
|
||||
|
||||
- 优先使用 `shader_feature`,只在运行时必须覆盖全部组合时使用 `multi_compile`。
|
||||
- 关键字尽量限制到实际影响的 Shader Stage。
|
||||
- URP Asset 中关闭未使用能力,让 URP 构建预过滤和 Shader Stripping 生效。
|
||||
- 不把 URP Lit、Standard 或其他高变体 Shader 整体加入 Always Included Shaders。
|
||||
- 动态启用关键字时,构建中必须存在对应材质组合或精确的 ShaderVariantCollection。
|
||||
- 调试剥离问题时可以临时开启 Strict Shader Variant Matching;确认完成后再决定正式配置。
|
||||
|
||||
### 5.2 AssetBundle
|
||||
|
||||
- AssetBundle 材质使用的 Shader 必须由主包材质、精确的 ShaderVariantCollection 或经过验证的包含策略保留。
|
||||
- Bundle 中的 Shader、材质和主包 URP 版本必须一致,不能混用不同 Unity/URP 版本生成的结果。
|
||||
- ShaderVariantCollection 只记录真实使用组合,不把所有可能关键字做笛卡尔积。
|
||||
- Bundle 卸载遵循资源管理生命周期;仍有材质或 Renderer 引用时不能假设 Shader GPU 资源已经释放。
|
||||
|
||||
### 5.3 首次使用卡顿
|
||||
|
||||
Unity 第一次渲染某个 Shader 变体时,图形驱动可能创建并上传 GPU 程序,产生可见卡顿。处理顺序:
|
||||
|
||||
1. 先减少无用 Shader 和变体。
|
||||
2. 收集首屏、战斗、场景切换实际使用的变体。
|
||||
3. 在可控加载阶段分批预热必要集合。
|
||||
4. 避免一次性 WarmUp 全项目变体导致启动峰值。
|
||||
5. 在微信真机记录首帧、场景首开和特效首次播放时间。
|
||||
|
||||
## 六、纹理、色彩与 RenderTexture
|
||||
|
||||
- WebGL 2 才支持可靠的 Linear 色彩空间路径;项目选择 Linear 后不得保留未经验证的 WebGL 1 回退。
|
||||
- 纹理的 sRGB、Normal Map、Alpha 和压缩格式必须按用途配置,不能只靠文件名约定。
|
||||
- 微信转换插件的压缩纹理功能和 Unity Texture Importer 是两层配置,启用前应确认产物格式、设备支持、下载体积和运行时内存。
|
||||
- 不把 DXT 当作移动设备通用格式;ASTC、ETC2 和无压缩回退需要按微信设备覆盖范围验证。
|
||||
- 压缩纹理不可用时可能发生解压或回退,导致显存和加载峰值显著增加。
|
||||
- RenderTexture 的格式、MSAA、Depth Buffer 和 sRGB 必须使用目标设备支持的组合。
|
||||
- 临时 RenderTexture 使用 `GetTemporary`/`ReleaseTemporary` 成对管理;长期 RenderTexture 在生命周期结束时显式释放。
|
||||
- 全屏 Blit、Grab、Opaque Texture 和多层后处理按像素数消耗带宽,小游戏上应优先减少次数和分辨率。
|
||||
|
||||
## 七、性能预算与诊断
|
||||
|
||||
性能判断以真机 GPU/CPU 帧时间、内存和发热为准,不只看 Draw Call。
|
||||
|
||||
重点指标:
|
||||
|
||||
- SetPass Calls、Draw Calls、Batches。
|
||||
- Triangles、Vertices。
|
||||
- 透明 Overdraw 和全屏 Pass 数量。
|
||||
- RenderTexture 数量、尺寸和格式。
|
||||
- Shader/Material 数量和首次使用卡顿。
|
||||
- URP 阴影、附加光、后处理和 Renderer Feature 成本。
|
||||
- 纹理下载体积、解码峰值、CPU 内存和 GPU 估算内存。
|
||||
|
||||
微信转换配置提供 Render Analysis、性能分析和 Profile Stats 时,可以在诊断构建中启用;正式包是否保留以开销实测为准。
|
||||
|
||||
推荐定位顺序:
|
||||
|
||||
1. 确认设备、基础库、WebGL 版本和分辨率。
|
||||
2. 确认问题属于 CPU、GPU、内存、下载还是 Shader 首次编译。
|
||||
3. 用 Unity Frame Debugger/Profiler 找到 Pass、材质和 RenderTexture。
|
||||
4. 用微信开发者工具和真机复现。
|
||||
5. 每次只改变一类 URP 或 Shader 配置,记录前后数据。
|
||||
|
||||
## 八、构建与验收流程
|
||||
|
||||
### 8.1 构建前
|
||||
|
||||
- 确认 Unity、URP、Shader Graph 和微信转换插件版本。
|
||||
- 确认微信转换配置启用 WebGL 2。
|
||||
- 检查目标 Quality Level 和实际 URP Asset。
|
||||
- 检查 Graphics Settings 的 Always Included Shaders、Preloaded Shaders、透明排序轴和剥离配置。
|
||||
- 检查 URP Asset、Renderer Feature、Depth/Opaque Texture、HDR、MSAA 和 Render Scale。
|
||||
- 构建日志开启 Shader Variant 统计时,记录编译前后变体数量。
|
||||
|
||||
### 8.2 最低验证场景
|
||||
|
||||
- 冷启动首屏。
|
||||
- 首次打开主要 UI 和 Spine 动画。
|
||||
- 首次进入每个使用独立 Shader 的场景。
|
||||
- 透明 Quad、粒子、Alpha Clipping 和 UI 遮挡。
|
||||
- 水体、Scene Depth、Opaque Texture 和反射效果。
|
||||
- Base/Overlay Camera Stack。
|
||||
- AssetBundle 首次加载、缓存命中和卸载后重新加载。
|
||||
- Android 与 iOS 微信真机至少各一台中低端设备。
|
||||
- 前后台切换、分辨率变化和长时间运行。
|
||||
|
||||
### 8.3 通过标准
|
||||
|
||||
- 没有粉色材质、缺失 Pass、错误关键字或不支持的 RenderTexture 格式。
|
||||
- Editor、普通 WebGL 和微信小游戏的核心画面含义一致。
|
||||
- 首次使用 Shader 不产生不可接受的主线程或 GPU 卡顿。
|
||||
- 透明排序、深度遮挡和 Camera Stack 符合设计。
|
||||
- 变体、纹理和 RenderTexture 不造成不可接受的启动或场景内存峰值。
|
||||
- Unity Console、WebGL 浏览器日志、微信开发者工具和真机日志无本次新增 Shader Error。
|
||||
|
||||
## 九、FFCard_WeChat 当前基线
|
||||
|
||||
以下是项目基线,不是所有 StrayFog 项目的强制配置:
|
||||
|
||||
- Unity:`2022.3.29f1`。
|
||||
- URP:`14.0.11`。
|
||||
- Shader Graph:`14.0.11`。
|
||||
- 微信转换配置:WebGL 2 开启。
|
||||
- URP:SRP Batcher、Depth Texture、Opaque Texture、HDR 和 2x MSAA 开启。
|
||||
- WebGL Quality Level:High。
|
||||
- WebGL Static Batching、Dynamic Batching 和 Graphics Jobs 关闭。
|
||||
- Graphics Settings 使用 Custom Transparency Sort Axis `(0, 0, 1)`。
|
||||
- Preloaded Shaders 为空,Strict Shader Variant Matching 关闭。
|
||||
- 微信压缩纹理、Render Analysis、Emscripten GLX 和 Render Thread 当前关闭。
|
||||
|
||||
这些配置只是后续优化的测量起点。调整前必须保存目标设备、测试场景和基线数据,调整后在微信真机对比。
|
||||
|
||||
## 十、外部依据
|
||||
|
||||
- [微信小游戏 Unity/团结引擎快适配文档](https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/)
|
||||
- [Unity 2022.3 WebGL](https://docs.unity3d.com/cn/2022.3/Manual/webgl.html)
|
||||
- [Unity 2022.3 WebGL Graphics](https://docs.unity3d.com/2022.3/Documentation/Manual/webgl-graphics.html)
|
||||
- [Unity Shader Variant Stripping](https://docs.unity3d.com/cn/2022.3/Manual/shader-variant-stripping.html)
|
||||
- [Unity Shader Loading](https://docs.unity3d.com/cn/2022.3/Manual/shader-loading.html)
|
||||
- [Unity Graphics Settings](https://docs.unity3d.com/cn/2022.3/Manual/class-GraphicsSettings.html)
|
||||
|
||||
## 十一、文档关联
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [FFCard_WeChat 卡牌 Shader 框架](../../business-reference/ffcard-wechat/卡牌Shader框架.md) | 本规则在 FFCard_WeChat 中的卡牌业务实现 |
|
||||
| [微信小游戏资源接入方案](资源管理/微信小游戏资源接入方案.md) | Shader、材质和 AssetBundle 的加载与卸载边界 |
|
||||
| [相机系统](相机系统/README.md) | URP Camera Stack 和渲染顺序 |
|
||||
| [第三方插件](第三方插件.md) | Spine、UI 特效和微信转换插件的 Shader 风险 |
|
||||
| [工作流清单](../../rules/40-工作流清单.md) | Unity、平台与真机验证流程 |
|
||||
| [开发规则](../../rules/20-开发规则.md) | 平台、资源和生成代码约束 |
|
||||
@@ -11,6 +11,7 @@
|
||||
| [事件系统](frameworks/事件系统/README.md) | `CopyToHF/Event/` | CTC/STC 事件派发 | 已完成 |
|
||||
| [资源管理](frameworks/资源管理/README.md) | `CopyToHF/AssetBundle/`、`StrayFog/Core/SFSubPackageV2.cs` | AssetBundle、图集、卸载、分包 V2 和下载 | 已完成 |
|
||||
| [微信小游戏资源接入方案](frameworks/资源管理/微信小游戏资源接入方案.md) | `CopyToGeneral/MinGameModel/`、`SFSubPackageV2.cs` | FFCard_WeChat 微信 CDN、缓存、加载、卸载和资源生命周期接入方案 | 待实施 |
|
||||
| [微信小游戏渲染规则](frameworks/微信小游戏渲染规则.md) | `ProjectSettings/`、URP Asset、Shader、Shader Graph、材质 | WebGL 2、URP、Shader 变体、透明深度、纹理与微信真机渲染规范 | 待验证 |
|
||||
| [音效系统重构方案](frameworks/音效系统重构方案.md) | `StrayFog/Editor/CopyToX/CopyToHF/Audio/`、`CopyToGeneral/Audio/` | 原生音频播放、混音、缓存、并发与资源生命周期设计 | 待验证 |
|
||||
| [相机系统](frameworks/相机系统/README.md) | `GameHFScripte/` | 多相机、堆栈和渲染顺序 | 已完成 |
|
||||
| [实体系统](frameworks/实体系统/README.md) | `GameFunction/GameEntity/` | 实体、System、Model 和实体池 | 已完成 |
|
||||
@@ -39,6 +40,7 @@
|
||||
## 业务参考
|
||||
|
||||
- [PlayBalloons](../business-reference/playballoons/业务参考总入口.md):外部项目业务实现示例,不作为框架规范。
|
||||
- [FFCard_WeChat 卡牌 Shader 框架](../business-reference/ffcard-wechat/卡牌Shader框架.md):GameHFResource 内的 URP 卡牌 Shader 与 Y 轴深度业务实现,不作为通用核心框架。
|
||||
|
||||
## 文档拆分
|
||||
|
||||
|
||||
Reference in New Issue
Block a user