Axıs
技能目录

01 · 渲染与着色器

01 · 渲染与着色器

目标不是"写最牛的 shader",是用最少的 shader 覆盖最多的资产,并留下一个能豪赌的招牌。

1. 渲染路径选型(第一步,决定后面所有事)

路径 优点 缺点 独立游戏建议
Forward 便宜、透明处理好、MSAA 可用 多光源贵 2D / 低多边形 / 移动端首选
Forward+ 多光源便宜(光剔除) 复杂度中 有较多动态光时的首选(Unity URP)
Deferred 多光源极便宜,易做屏幕空间效果 透明难处理、内存高、MSAA 不可用 场景光多且不需要太多透明时
Deferred + Forward(透明) 折中 两套代码 3A 常用,独立游戏一般不必

决策表

你的情况 选什么
2D / 像素 Forward
3D 卡通,光源 ≤ 4 Forward
3D 场景暗、需要很多火把/灯光 Forward+
开放世界 + 大量点光 Deferred
移动端 Forward(禁用延迟)
不确定 Forward+(最稳)

2. 光照策略(独立游戏的性价比之选)

三层光照模型

L0 天光/环境光   → 烘焙(Ambient / Sky Occlusion / 环境 cubemap)
L1 主光(太阳/月亮) → 1 盏实时方向光 + 阴影
L2 补光(火把/灯/特效光) → 烘焙 + Light Probe + 少量实时(无阴影)

预算

项 Low Mid High
实时投影光源 1 1–2 4
无阴影实时光 2 4 8
阴影贴图分辨率 1024 2048 4096
阴影距离 30m 60m 120m
级联数(CSM) 2 3 4

烘焙 vs 实时

烘焙 实时
成本 构建时间 + 内存 每帧成本
动态物体 需要 Light Probe 天然支持
昼夜变化 需多套切换 免费
独立游戏建议 静态环境全烘焙 只留主光实时 + 动态物体用 Probe

技巧:

  • 烘焙 + 探针 是独立游戏的最优解,90% 场景适用。
  • 昼夜循环:烘焙 3–4 套(晨/午/昏/夜),运行时按时间混合(内存翻倍,但每帧成本为零)。
  • Light Probe 密度:每 2–5m 一个,关键路径更密。少了会看到动态物体"跳变"。
  • Reflection Probe:每 10–20m 一个,室内必须单独放。

光照模板(量产关键)

建一套"全局光照模板":一个配置好的场景(天光、主光、雾、后处理、探针密度),所有新场景从这个模板复制。 禁止每个场景重新调光照——那是量产杀手。

3. 母材质体系(独立游戏 TA 的第一生产力)

为什么必须有

  • 风格统一(所有资产共享同一套材质逻辑)
  • 性能好(同一 shader → 可合批)
  • 迭代快(改母材质 = 改所有资产)
  • 新人/外包不会跑偏

建议的母材质清单(3–5 个,覆盖 90%)

# 母材质 覆盖 关键参数
M1 环境 Standard 地面/墙/建筑/道具 Albedo + ORM + Normal + 三平面选项 + 顶点色(湿滑/苔藓/磨损)
M2 角色 Character 主角/敌人/NPC Albedo + ORM + Normal + Rim + 描边 + 受击闪白 + 溶解
M3 透明/特效 粒子/能量/水 加性/Alpha 混合 + 软粒子 + UV 流动 + 溶解遮罩
M4 植被 树/草 双面 + 风摆动 + Alpha Test + 半透光(次表面近似)
M5 天空/背景 天空盒/远景 渐变 + 云流动 + 视差层

超过 5 个母材质 = 你在制造维护债。 新增母材质需评审。

母材质的参数化设计(关键技巧)

把"看起来不同"变成"参数不同":

参数 作用 一个资产变 N 个
_Tint 改色 石材 → 木材 → 冰
_Wear / _Era 磨损程度 新 → 旧 → 废墟
_Wetness 湿度 干 → 湿 → 积水
_Moss 苔藓覆盖 干净 → 长苔
_Snow 积雪 无雪 → 厚雪
_Dissolve 溶解(死亡/消失/出现) 死亡动画
_EmissionPulse 呼吸发光 可交互提示
_HitFlash 受击闪白 打击反馈

这是独立游戏省钱的核心手段:1 套资产 × 10 组参数 = 10 个视觉变体,成本接近零。

4. Shader 技法库(独立游戏高频,按性价比排序)

A 级(必会,成本极低)

技法 用途 成本
Rim / Fresnel 边缘光 主体浮出、风格化 极低
溶解 Dissolve(噪声 + clip) 死亡、出现、消散 极低
UV 流动 水、能量、岩浆 极低
顶点色控制(湿/苔/磨损/描边宽) 免贴图变体 极低
三平面映射 Triplanar 免 UV 的地表/岩壁 低
风摆动(顶点位移噪声) 植被、布料、旗帜 低
受击闪白 打击感 极低
深度淡出软粒子 粒子不穿模 低
卡通分层(step/ramp) 风格化 低
Dithering 抖动 复古/半透明替代 极低

B 级(招牌候选)

技法 用途 成本
描边(背面外扩/后处理) 卡通风格 中
屏幕空间水/折射 水面 中
体积光/光轴 氛围 中
视差映射 Parallax 深度感 中
高度混合 Height Blend 自然地表过渡 中
GPU 粒子 大量粒子 中高
次表面近似(SSS) 皮肤、叶子 中
程序化天空 昼夜 中
高度雾/体积雾 氛围 中

C 级(谨慎,除非它是你的招牌)

屏幕空间反射 SSR · SSGI · 实时 GI · 复杂流体 · 光线追踪 · 毛发 · 高级布料 · 全场景曲面细分

原则:C 级技术一次只允许上一个,且必须有降级方案。

5. Shader 性能优化(硬技能)

检查清单

项 规则
纹理采样 每个 shader ≤ 5 次采样(移动端 ≤ 3)
精度 能用 half 就用 half(位置/时间除外)
分支 避免动态分支;分支两边复杂度要对等
数学 避免 pow/sqrt/sin/cos/log/exp,用近似或 LUT
计算位置 能放顶点着色器的就别放片元
能放 CPU 的 每帧算一次的放脚本里传参
discard/clip 禁用或可关闭(破坏 early-Z)
透明 能不用就不用(破坏 early-Z + overdraw)
通道打包 Rough/AO/Metal 打包成 ORM,一次采样
依赖纹理读取 避免在片元里用计算出的 UV 采样(无法预取)

变体治理(独立游戏最容易翻车的一项)

变体来源:keyword(multi_compile / shader_feature)、光照模式、雾模式、阴影、实例、质量档。

爆炸原因

  • 用了 multi_compile 而非 shader_feature(前者无条件编译所有组合)
  • 材质上开了很多 keyword 但只有 1 个在用
  • 每个母材质都带全套光照/雾变体

治理三步

  1. 用 shader_feature 替代 multi_compile(只编译被材质实际用到的)
  2. 剥离:Player Settings 中剥离不需要的光照/雾/阴影变体
  3. 预热:Shader Variant Collection(Unity)/ PSO Caching(UE)/ RenderingDevice 预热(Godot);或首屏隐藏相机渲染所有材质

预算:总变体 ≤ 5000,单 shader ≤ 200,首屏编译 ≤ 3s。

6. 合批与 Draw Call

技术 适用 说明
Static Batching 静态环境 内存换 DrawCall,注意别把大场景全合了
Dynamic Batching 小网格 Unity 老方案,限制多
GPU Instancing 同网格同材质多实例 植被/碎石/人群首选
SRP Batcher URP 按 shader 合批,母材质策略的直接收益
Impostor / Billboard 远景 远景植被用面片
遮挡剔除 室内/密集场景 必须开
LOD 一切 见下

目标:DrawCall < 800(Low)/ 1500(Mid)

7. LOD 策略

距离 LOD 减面比 额外
0–10m LOD0 100% 全材质
10–30m LOD1 50% 简化材质
30–80m LOD2 20% 单材质
80m+ Billboard/Impostor 2 tri
超出 Cull — 用雾遮住切换

独立游戏技巧:

  • 自动生成 LOD(引擎自带或脚本),不要手做
  • 雾是 LOD 的朋友:雾浓时可以更早切换 LOD 而不被察觉
  • 角色 LOD 同时降骨骼数(见 04-character-and-animation.md)

8. 渲染调试方法(TA 的日常)

症状 第一步 工具
掉帧 先分 CPU/GPU Profiler(Unity)/ Unreal Insights / Godot Profiler
GPU 慢但不知道哪 逐 pass 关闭 RenderDoc / Frame Debugger / GPU Visualizer
透明很贵 看 overdraw Overdraw 视图
DrawCall 多 看 Frame Debugger
内存爆 Memory Profiler / Stat 按类别查(纹理通常占 50%+)
闪烁 查深度精度/z-fighting 调整 near/far plane
加载慢 查 shader 编译 + 纹理加载 预热 + Addressables/流式

铁律:只在真机、Development Build、真实玩法下 Profile。 编辑器和空场景的数据全是假的。

9. Shader 规格单模板

见 templates/04-shader-spec.md

10. 自检清单

  1. 渲染路径定了吗?理由是什么?
  2. 母材质 ≤ 5 个吗?覆盖了 90% 资产吗?
  3. 光照模板建了吗?新场景是从模板复制的吗?
  4. 纹理通道打包了吗?
  5. Shader 变体总数有上限吗?有剥离和预热吗?
  6. 每个 shader 有降级/关闭开关吗?
  7. 真机 Profile 过吗?数据是多少?
  8. 招牌技术是哪一个?其余的技术投入有没有被质问过?
  9. DrawCall / 面数 / 透明层 在预算内吗?
  10. 材质参数化了吗?(1 个资产能变出几个变体?)

11. 一句话总结

独立游戏的渲染能力不来自"会写多少 shader", 来自**"3 个母材质 + 1 个招牌技术 + 一张被严格执行的预算表"**。 你的 shader 越通用,你的团队越快;你的招牌越集中,你的游戏越容易被记住。