13 KiB
13 KiB
微信小游戏渲染规则
一、定位与适用范围
本文档定义 StrayFog 接入微信小游戏时需要长期遵守的渲染与 Shader 规则,适用于 Unity URP、手写 Shader、Shader Graph、材质、Shader 变体和 AssetBundle 资源。
微信小游戏 Unity 快适配以 WebGL/WebAssembly 构建为基础,再由微信转换插件接入小游戏运行环境。Editor、普通 WebGL 和桌面平台表现不能替代微信开发者工具与真机验证。
本文档不规定具体画面风格,也不替代:
- 微信小游戏资源接入方案中的 CDN、AssetBundle、缓存和卸载规则。
- 相机系统中的 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 已定义的图形平台宏:
#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 的材质属性放入
UnityPerMaterialCBUFFER,并保持所有 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 程序,产生可见卡顿。处理顺序:
- 先减少无用 Shader 和变体。
- 收集首屏、战斗、场景切换实际使用的变体。
- 在可控加载阶段分批预热必要集合。
- 避免一次性 WarmUp 全项目变体导致启动峰值。
- 在微信真机记录首帧、场景首开和特效首次播放时间。
六、纹理、色彩与 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 时,可以在诊断构建中启用;正式包是否保留以开销实测为准。
推荐定位顺序:
- 确认设备、基础库、WebGL 版本和分辨率。
- 确认问题属于 CPU、GPU、内存、下载还是 Shader 首次编译。
- 用 Unity Frame Debugger/Profiler 找到 Pass、材质和 RenderTexture。
- 用微信开发者工具和真机复现。
- 每次只改变一类 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/团结引擎快适配文档
- Unity 2022.3 WebGL
- Unity 2022.3 WebGL Graphics
- Unity Shader Variant Stripping
- Unity Shader Loading
- Unity Graphics Settings
十一、文档关联
| 文档 | 关联原因 |
|---|---|
| FFCard_WeChat 卡牌 Shader 框架 | 本规则在 FFCard_WeChat 中的卡牌业务实现 |
| 微信小游戏资源接入方案 | Shader、材质和 AssetBundle 的加载与卸载边界 |
| 相机系统 | URP Camera Stack 和渲染顺序 |
| 第三方插件 | Spine、UI 特效和微信转换插件的 Shader 风险 |
| 工作流清单 | Unity、平台与真机验证流程 |
| 开发规则 | 平台、资源和生成代码约束 |