mcpField
S
shader-graph-best-practices

shader-graph-best-practices

github.com/adevra开发1655 次安装31 周前更新
代码仓库

关于 shader-graph-best-practices

shader-graph-best-practices 是用于 Unity Shader Graph 编写与优化的技能,尤其面向移动平台。内容包括节点效率、精度、自定义光照、纹理用量和全屏效果。

主要功能

  1. 01控制节点数量与图形精度
  2. 02用 Sub Graph 组织可复用逻辑
  3. 03通过 Custom Function 节点编写 HLSL
  4. 04减少纹理采样与高开销节点
  5. 05用 Unlit 图形实现自定义光照
  6. 06在 Unity 6 中设置全屏效果

适用场景

  1. 01检查移动端 Shader Graph 的效率
  2. 02通过自定义图形逻辑实现简化光照
  3. 03减少图形中的重复纹理采样
  4. 04将全屏效果合并到一个渲染通道

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/adevra/unity-shader-agent-skills --skill shader-graph-best-practices

安装后在 Claude Code 中输入/shader-graph-best-practices确认已加载。

详细介绍

面向移动设备的 Unity Shader Graph 最佳实践

触发条件

当用户在 URP 或 HDRP 中使用 Unity Shader Graph(基于节点的可视化着色器编辑器)时,使用此技能。触发词包括:“Shader Graph”、“基于节点的着色器”、“子图”、“自定义函数节点”、“移动端 Shader Graph”、“Shader Graph 优化”、“自定义光照 Shader Graph”、“Shader Graph 精度”,或 Unity 中的任何可视化着色器创作工作流。用户提及 Ben Cloward、Cyanilux 或 Daniel Ilett 的 Shader Graph 教程时,也应触发此技能。


核心规则

  1. 面向移动设备时,节点数应控制在 100 个以内。 每个节点都会编译为着色器指令。节点数超过约 100 个时,移动 GPU 会达到指令缓存限制,性能会急剧下降。使用子图来整理结构,但子图不会减少指令数量。

  2. 将图形级精度设为 Half,以适配移动设备。在 Graph Inspector 中,将 Precision 改为 "Half"。只有位置和 UV 才需要将单个节点覆盖设为 "Float"。

  3. 使用子图来整理结构,而非优化性能。 子图能提高可读性,但编译时会内联,不会减少指令数量。不过,子图可在多个图形间复用,从而减少整个项目的维护工作。

  4. 自定义函数节点是解决问题的后备方案。 当 Shader Graph 无法高效表达某项功能(或简单操作需要使用太多节点)时,可用 HLSL 编写自定义函数节点。这对访问光照、复杂数学运算和特定平台分支尤其有用。

  5. Shader Graph 会自动生成所有必需的通道(ForwardLit、ShadowCaster、DepthOnly、DepthNormals、Meta)。你不必像使用 HLSL 那样操心多通道问题,但也无法单独优化各个通道。


在 SHADER GRAPH 中自定义光照

Shader Graph 的默认 Lit 目标使用 PBR(基于物理的渲染)。对于移动设备,通常需要更简单的光照。可使用 Cyanilux 的自定义光照子图:

安装自定义光照节点

Cyanilux/URP_ShaderGraphCustomLighting 软件包会将以下子图节点添加到 Shader Graph:

  • MainLight — 方向、颜色、阴影衰减
  • AdditionalLights — 遍历附加光源(在移动设备上谨慎使用)
  • AmbientSH — 球谐环境光
  • MainLightShadows — 阴影采样
  • Cel/Toon Shading — 基于阶梯的光照
使用方式
  1. 将图形目标设为 Unlit(而非 Lit)——这会禁用 Unity 的 PBR 光照
  2. 添加 Cyanilux 的 MainLight 子图,以获取光照方向和颜色
  3. 计算自定义漫反射:saturate(dot(Normal, LightDirection)) * LightColor
  4. 从 AmbientSH 子图添加环境光
  5. 与反照率纹理相乘
  6. 输出到 Unlit 图形的 Color 输出端口

这样你就能完全控制光照的复杂度——这对移动设备至关重要,因为 PBR 的多纹理 GGX/Smith BRDF 往往开销过高。


节点效率技巧

合并运算
BAD:  Multiply → Add → Multiply → Saturate  (4 nodes)
GOOD: Custom Function node with: saturate(a * b + c) * d  (1 node)
使用 Shader Graph 变量(Cyanilux)

ShaderGraphVariables 软件包会添加 Register Variable 和 Get Variable 节点。这可以避免在复杂图形中重复计算相同的值,相当于代码中的局部变量。

纹理采样效率
  • 使用单个 Sample Texture 2D 节点并拆分通道,而不是多次采样同一纹理
  • 对于法线贴图,将 Sample Texture 2D 节点的 Type 设为 Normal——它会自动处理解包
  • 将遮罩打包到单张纹理的 RGBA 通道中(参见 texture-packing-variant-stripping 技能)
在移动设备上避免使用开销较大的节点
节点开销替代方案
菲涅尔效果中手动计算:1 - saturate(dot(ViewDir, Normal)),然后使用 Power
沃罗诺伊高预先烘焙到纹理中
梯度噪声高使用 Simple Noise,或预先烘焙到纹理中
三平面映射高(3 次纹理采样)仅用于特定网格,不要用于地形
从高度生成法线高改用实际法线贴图
自定义渲染纹理高尽可能预先烘焙

全屏着色器图(UNITY 6+)

Unity 6 引入了用于后处理效果的全屏着色器图。与 URP 的 Full Screen Pass Renderer Feature 配合使用:

  1. 创建一个以 Full Screen 为目标的新着色器图
  2. 该图会接收 URP 的摄像机颜色和深度作为输入
  3. 应用后处理效果(晕影、颜色校正等)
  4. 将 Full Screen Pass Renderer Feature 添加到 URP Renderer
  5. 指定全屏着色器图材质

移动设备注意事项:每个全屏通道都会执行一次全屏 blit。尽可能将效果合并到一个全屏图中。


着色器图 + 移动设备检查清单

  • 图级精度设置为 Half
  • 在需要时将 Position 和 UV 节点覆盖为 Float
  • 节点总数 < 100
  • 不使用 Voronoi 或 Gradient Noise 节点(改为预先烘焙)
  • 如果光照简单,使用 Unlit 目标 + 自定义光照,而非 Lit 目标
  • 纹理采样 ≤ 4
  • 大面积表面不使用 Triplanar
  • 使用 Sub Graphs 进行组织和复用
  • 可切换功能的关键字使用 shader_feature(而非 multi_compile)
  • 在目标分辨率下通过着色器图预览进行测试

参考资源

代码仓库
教程
重要人物
  • Ben Cloward — 曾任 Unity Shader Graph 团队成员,目前就职于 ILM。每周发布 Unreal 和 Unity Shader Graph 教程。
  • Cyanilux — 维护最活跃的 URP Shader Graph 代码仓库,涵盖自定义光照、代码模板和变量。
  • Daniel Ilett — Shader Graph 基础系列作者,也是 Building Quality Shaders for Unity 一书的作者。
  • MinionsArt(Joyce) — “Shaderwitch”,以 GIF 为主的快速着色器技巧,共有 200 个教程。
  • Gabriel Aguiar — VFX Graph + Shader Graph 教程(传送门、水、龙卷风)。

来源

评论

支持 Markdown