Files
UnityAI/modules/frameworks/微信小游戏渲染规则.md

13 KiB
Raw Blame History

微信小游戏渲染规则

一、定位与适用范围

本文档定义 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 的材质属性放入 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 当前关闭。

这些配置只是后续优化的测量起点。调整前必须保存目标设备、测试场景和基线数据,调整后在微信真机对比。

十、外部依据

十一、文档关联

文档 关联原因
FFCard_WeChat 卡牌 Shader 框架 本规则在 FFCard_WeChat 中的卡牌业务实现
微信小游戏资源接入方案 Shader、材质和 AssetBundle 的加载与卸载边界
相机系统 URP Camera Stack 和渲染顺序
第三方插件 Spine、UI 特效和微信转换插件的 Shader 风险
工作流清单 Unity、平台与真机验证流程
开发规则 平台、资源和生成代码约束