Axıs
技能目录

05 · 程序化资产生成(PCG)

05 · 程序化资产生成(PCG)

程序化在独立游戏里只有三种合法用途:省钱、玩法、惊喜。 为了"酷"而做程序化,是独立游戏最烧钱的自杀方式之一。

1. 先问:你为什么需要程序化?

动机 判断 建议
省钱(做 100 棵树太贵) ✅ 合法 用散布 + 变体,不要做完整的生成系统
玩法(roguelike 关卡) ✅ 合法 这是核心系统,值得投入
惊喜(涌现、意外) ✅ 合法 需要精心设计约束
规模(做超大世界) ⚠️ 危险 独立游戏一般不需要超大世界
因为很酷 ❌ 砍

2. 三档程序化投入(按风险递增)

档 技术 成本 风险 独立游戏建议
A 档:参数化变体 材质参数、颜色变体、缩放、旋转、组合 极低 无 必做
B 档:散布与规则 植被散布、碎石、按坡度/高度/曲率分布 低 低 强烈建议
C 档:生成系统 WFC、噪声地形、建筑生成、关卡生成 中高 中高 只在它是玩法时做
D 档:内容生成器 Houdini 管线、可玩的世界生成 高 高 一般不做

3. A 档:参数化变体(零风险,必做)

原理:1 个资产 + N 组参数 = N 个视觉变体。

参数 变体效果
颜色 Tint 木/石/冰/金属
缩放(非均匀) 高矮胖瘦
旋转(Y 轴随机) 打破重复感
材质参数(磨损/湿度/苔藓/积雪) 年代感、地域感
部件组合(头 A + 身 B + 武器 C) 组合爆炸
顶点色扰动 表面变化
细节贴图切换 表面材质变化

重复感破解三招(散布时务必用上):

  1. 随机 Y 轴旋转(最便宜)
  2. 非均匀缩放(0.9–1.1)
  3. 颜色/材质参数微扰(±5%)

独立游戏几乎不需要"做更多资产",只需要"让已有资产看起来不重复"。

4. B 档:散布与规则(强烈建议)

散布规则库

规则 用途 实现
坡度 岩石长在陡坡,草长在缓坡 slope = dot(normal, up)
高度 雪线以上有雪,水边有芦苇 世界 Y
曲率 凸起处长苔,凹陷处积水 曲率贴图/计算
遮罩 手工画的区域遮罩(路径无草) 顶点色/纹理遮罩
密度噪声 自然的不均匀分布 Perlin/Simplex
排斥 物件之间最小距离 Poisson Disk 采样
朝向 朝向路径/水源/太阳 规则向量
生态 树周围长灌木不长草 层级规则

散布实现要点

  • 必须烘焙成实例/合并网格,不要运行时保留几千个 GameObject
  • 用 GPU Instancing
  • 提供"重新随机"(Re-seed)按钮——美术会用它刷到自己满意为止
  • 提供笔刷擦除——艺术家必须能手动覆盖程序化结果
  • LOD + 剔除必须配套,散布最容易炸 DrawCall

散布预算

项 Low Mid
同屏散布实例数 3000 10000
散布种类 5–8 10–15
DrawCall 贡献 < 50(靠 instancing) < 100

5. C 档:生成系统(只在它是玩法时做)

常见算法与适配

算法 用途 复杂度 独立游戏适配
噪声(Perlin/Simplex/Worley) 地形、纹理、密度、云 低 ✅ 常用
Poisson Disk 自然散布点 低 ✅ 常用
元胞自动机 洞穴、腐蚀、生长 低 ✅ 常用(洞穴生成经典)
L-System 植物、分形 中 ⚠️ 少用(不如手做)
WFC(波函数坍缩) 从样本生成布局 中高 ⚠️ 谨慎(可控性差)
BSP / 房间图 地牢布局 中 ✅ roguelike 常用
Marching Squares/Cubes 等值面、洞穴平滑 中 ⚠️ 谨慎
Voronoi / Delaunay 区域划分、生物群系 中 ✅ 有用
语法生成(Grammar) 建筑、任务 高 ❌ 一般不做

生成系统的五条铁律(血泪)

  1. 必须种子化:同一个种子必须生成完全一样的结果。否则无法复现 bug。
  2. 必须可手改:生成后艺术家能手动调整,且调整不被下次生成覆盖(用"覆盖层"机制)。
  3. 必须有确定性顺序:随机数调用顺序不能依赖帧率/线程。
  4. 必须有失败兜底:生成失败时回退到手工关卡,不能卡死加载。
  5. 必须有可视化调试:能画出生成过程的中间状态。

最常见的死法:"程序化生成的关卡偶尔会出不可通关的布局"。 解法:生成后跑可解性验证(BFS/可达性检查),失败就重生成(最多 N 次,否则回退到保底布局)。

可解性验证清单

  • 起点到终点可达
  • 所有必需道具可达(或在获得能力后可达)
  • 无孤立区域(或孤立区域有意为之且无奖励)
  • 关键路径宽度足够(角色可通过)
  • 无物件卡住通道
  • 刷怪点不在墙里 / 不在玩家出生点
  • 无重叠的房间

6. D 档:Houdini / 大型生成管线(一般不做)

什么时候值得:

  • 你的招牌就是"程序化的世界"(如 Teardown 的体素、Noita 的像素模拟)
  • 你有专职 TA 且项目 > 18 个月
  • 资产量确实大到手工不可能

什么时候不值得:

  • 团队 < 5 人
  • 只是为了"看起来专业"
  • 没有 Houdini 经验但打算现学(学习曲线 6–12 个月)

折中方案:不买 Houdini,用引擎内置的 PCG 框架(UE5 PCG、Unity 的 Procedural 工具、Godot 脚本)做轻量版。

7. 程序化与美术主权(最容易被忽视的政治问题)

美术通常讨厌程序化,因为"它抢走了我的控制权"。 TA 的正确做法:

做法 说明
程序化产出的东西永远可手改 生成 → 烘焙成资产 → 美术可编辑
参数暴露给美术 滑杆而不是代码常量
提供 Re-seed 按钮 让美术"抽卡"到满意
提供笔刷覆盖 局部手工覆盖程序化
明确边界 "这片区域程序化,那片手工"

铁律:程序化是美术的助手,不是美术的替代品。 一旦美术觉得被替代,他会抵制,你的系统就废了。

8. 程序化纹理与材质

技术 用途 成本
Substance Designer(程序化材质) 可平铺材质 中(学习曲线)
Substance 参数化(.sbsar) 运行时变体 中
噪声 + Shader 合成 免纹理的表面变化 低
顶点色驱动混合 地表混合(草/土/石) 低
三平面 + 高度混合 免 UV 地表 低
运行时绘制(雪/泥/脚印) 交互痕迹 中
Decal 投影 痕迹、涂鸦 低

独立游戏建议:不需要 Substance Designer 也能做程序化材质——用3–5 张噪声贴图 + Shader 混合就能做出大部分效果,成本更低且更可控。

9. 程序化的性能陷阱

陷阱 症状 解法
运行时生成卡顿 掉帧/加载慢 预生成 + 烘焙;或分帧生成
实例太多 DrawCall 高 Instancing + 合并 + LOD
生成结果未合并 几千个 GameObject 烘焙为静态批次
每次进场景重新生成 加载慢 缓存生成结果(按种子存文件)
内存随生成增长 泄漏 回收旧区块
生成不确定 回放/联机不同步 固定种子 + 固定调用顺序

10. 投入决策表

你的情况 建议
3D 场景需要填充植被/碎石 B 档散布工具(1–3 人天)
需要很多敌人/道具变体 A 档参数化(0.5–1 人天)
Roguelike 关卡 C 档:房间图 + 可解性验证(5–15 人天,是核心系统)
开放世界地形 C 档:噪声地形 + 散布(5–10 人天)
想做"程序化城市" 先问这是不是玩法。不是 → 砍
想学 Houdini 除非有 6 个月以上空窗期,否则不要

11. 自检清单

  1. 程序化的动机是省钱/玩法/惊喜中的哪一个?说不出 → 砍。
  2. 结果可复现吗?(种子化 + 确定性)
  3. 美术能手动覆盖吗?
  4. 生成结果烘焙了吗?(不是运行时保留几千对象)
  5. 用 Instancing 了吗?
  6. 有可解性验证吗?(如果生成的是关卡)
  7. 有失败兜底吗?
  8. 有可视化调试吗?
  9. 参数暴露给美术了吗?有 Re-seed 按钮吗?
  10. 性能测过吗?(生成耗时 + 运行时开销)
  11. 关掉程序化,游戏还能做出来吗?能 → 说明它不是必需的,考虑简化。

12. 一句话总结

独立游戏的程序化,90% 的价值在 A 档(参数化变体)+ B 档(散布规则), 这两档风险为零、成本极低、收益立竿见影。 C 档以上只在"它本身就是玩法"时才做。 记住:程序化的目的不是"让电脑做资产",是"让美术不必重复劳动"。