PCG TECHNICAL ARTIST — PORTFOLIO 2025/26

王坤昊

把美术规则写成工具,
让工具长出世界。

Houdini HDA × UE PCG开放世界场景程序化生产管线AI + PCG

00SEED一个整数决定整个世界

FIG 00PCG.cook()trees —culled —lots —0 ms

  1. 同一个 seed 永远长出同一个世界;换种子就是换一张地图。

    → 看案例 · AI 批量地图
  2. fbm 噪声 + 河谷走向,生成高度场。

    → 看工具墙 · 地形
  3. D8 汇水,按汇水量下切河道,再长出水系。

    → 看工具墙 · 流水侵蚀
  4. 坡度、日照、水流、岩石四张遮罩,阈值与 Case 01 一致。

    → 看案例 · 野外空间
  5. 候选点按遮罩逐个判定:留下的长成树,不合规则的被剔除。

    → 看案例 · Biome Core
  6. 沿 spline 压平路基、清空走廊植被;待机时可拖铁路控制点实时重算。

    → 看案例 · Spline 工具族
  7. 河谷平地 → 路网 → 街区 → 楼块 → 城墙。

    → 看案例 · 城市空间
SCROLL
01

CASE 01 · OPEN-WORLD ECOSYSTEM

开放世界 PCG 生态定义

野外和城市分开做:野外空间用基于引擎定制的 Biome Core,城市空间用自研 Spline 控件 + PCG。

TIME
2025.12 — 2026.03
ENGINE
UE5 · PCG / PCG Runtime
STACK
Biome Core · LightCraft Spline · HLSL · Gaea
ROLE
系统改造 · 工具实现
01-A

野外空间

基于引擎定制的 Biome Core。

FIG 1-A画 Mask:在地形上用 Spline 圈出生态区
FIG 1-B配置:给每个生态区指定群落,生成植被

四张地形遮罩

MASKS
坡度遮罩 MASK 01 · SLOPEHOVER · SCAN

01坡度遮罩

和植物、石头的生成都有关。

  • 60°–90° 植物无法生成
  • 40°–60° 少量生成

石头等非生物因素也和坡度相关:

  • 坡度缓 大石块少,小石块多
  • 坡度陡 没有大石块,小石块也少
太阳光强度遮罩 MASK 02 · SUNHOVER · SCAN

02太阳光强度遮罩

和植物大小有关:遮蔽强的地方太阳少,植物也少,比如沟壑里完全没有阳光。

和坡度的区别:坡度看地面陡不陡,日照看有没有被遮挡。沟壑不一定陡,但照不到太阳。

日照遮罩对比 1
日照遮罩对比 2
FIG 1-C同一座山的植被分布对比
水流遮罩 MASK 03 · FLOWHOVER · SCAN

03水流遮罩

流水侵蚀地区的植物:少高大植物,多草和灌木。

岩石遮罩 MASK 04 · ROCKHOVER · SCAN

04岩石遮罩

非生物因素,自动剔除遮罩。

岩石 Actor 的 Rock 标签
FIG 1-D岩石 Actor 带 Rock 标签,周围自动剔除

草的层次

LANDSCAPE GRASS TYPE × PCG RUNTIME
BEFORE · 旧版

Landscape Grass Type

把一张 MatID 用噪声随机分成三种 Landscape Grass Type,增加植物多样性。

噪声分区
FIG 1-E噪声分区
采样节点
FIG 1-F采样节点
三种草的分布
FIG 1-G成图
ADD · 补充

PCG Runtime 再叠一层

PCG Runtime 下生成的草可以读取 Landscape Grass Type,用 HLSL 再加一层变化,增加层次感;还能挂载 Niagara 等和玩法相关的内容。

HLSL 与 PCG Graph
FIG 1-H左:HLSL 读 Grass Maps 权重,做密度剔除和按密度缩放 右:GPU 上的 Landscape Point Generator

REFBiome Core 技术的实际应用:[UFSH2025]《穿越火线-虹》:基于虚幻引擎 | 刘陌桑 · 腾讯天美 J3 工作室

RESULT / 结果

16km²覆盖 4×4 km 主地图 + 3 张测试地图
2 天 → 30min配置一块生态区:手刷 Foliage → 画 Mask + 选群落
48 → 60fps同机位:部分 Foliage 草改由 PCG Runtime 在 GPU 生成
01-B

城市空间

自研 Spline 控件 + PCG。

Foliage Mode 与 LightCraftSpline 参数对照
FIG 1-I左 Foliage Mode / 右 LightCraftSpline:参数对照
PARAMETERS

美术参与定义参数

LightCraftSpline 的植物参数对照 Foliage Mode 来设计(左图虚线为对应关系),参数和美术一起定义;每个参数在面板上都有说明。

参数标注
FIG 1-J主植物 + 伴生植物(ChildPlant)参数标注

使用方式

HOW TO USE
FIG 1-K画 Spline 圈出花坛,PCG 实时长出植物:调试色 → 成图
02

CASE 02 · AI × PCG

AI × PCG

三件已经落地的事:参与混元 AI 训练,搭建素材生产管线,两周产出 1000 张野外地图、渲染成视频进训练集;让模型读懂资产,自动摆出室内场景;在终端里用对话建工具,一句话重建小镇。

TIME
2026.03 — 2026.10
ENGINE
UE5 / UE 5.8 · PCG
STACK
大模型 · Skill · 编辑器 Python
PROJECT
混元 AI 训练
OUTPUT
1000 张野外地图 · 2 周
02-A

野外场景批量生产管线

一套管线、两周 1000 张:把单张地图的手工配置拆成可批量跑的生产管线。

参与混元 AI 训练,我搭建了野外地图的素材生产管线,配合美术同学两周产出 1000 张地图;地图进服务器渲染成视频,作为场景大模型的训练数据。单张从约 6 小时压到约 20 分钟,人工只处理抽检没过的那些。

0单张手工配置
0管线跑通 · 单张约 20 分钟
0配合美术同学 · 2 周

NEED / 需求

训练侧要大量风格统一、可直接使用的野外地图,再逐张渲染成视频喂给模型;单张手工配置的速度跟不上。

PROBLEM / 难点

  • 加入建筑后,地形采样精度不够,建筑会浮空
  • 70 张之后人工配置撑不下去,每张的标准也难统一
  • 光照、植被要逐张检查

SOLUTION / 方案

  1. 先定标准:确认场景标准,再整理地图与光照检查项
  2. 修落位:解决建筑浮空和采样精度问题
  3. 工具化:调用工具批量出图,跑通后配合美术同学扩产,两周 1000 张
  4. 结果:单张从约 6 小时降到约 20 分钟;人工只处理抽检没过的地图,介入比例从 100% 降到约 10%

单张耗时

PER MAP
  • 手工配置逐张调地形 / 散布 / 光照
    每张从头调,标准靠人记
    ~6h
  • 生产管线批量出图 + 抽检
    快 18×
    ~20min

人工介入

MANUAL TOUCH
  • 手工配置每张都要人
    100% 地图需要人工逐项处理
    100%
  • 生产管线只处理抽检未过
    其余 90% 直接出图
    ~10%

管线

PIPELINE
  1. 01地形地形与材质配置
  2. 02生态散布植物生成 · 生态补充
  3. 03建筑落位贴地修正 · 采样精度
  4. 04光照检查统一标准 · 整理 map
  5. 05批量出图工具批量调用
雪地岛屿
FIG 2-A雪地岛屿
针叶林岛屿
FIG 2-B针叶林岛屿
加入建筑,修正浮空
FIG 2-C加入建筑,修正浮空
管线产出:雪地村落
FIG 2-D管线产出:雪地村落
山地 · 道路
FIG 2-E山地 · 道路
荒漠生态
FIG 2-F荒漠生态
地形与材质配置
FIG 2-G地形与材质配置
林地村落
FIG 2-H林地村落
02-B

让模型读懂资产,再让它摆场景

UE 5.8 PCG + 大模型:从一个 Volume 出发,自动生成室内结构并摆放资产,再封装成 skill,批量出不同风格。

  1. 01
    Volume 圈定范围用一个 Volume 包住要生成的区域
  2. 02
    模型生成结构 JSON墙壁、地板、窗户、柱子 + 场景信息
  3. 03
    分析资产目录路径、本地 AABB、尺寸、pivot 类型、正面朝向、建议落位面
  4. 04
    落位与堆叠用 5.8 新增的 primitive 摆放,模型可以堆叠且不穿模,人工少量补充
  5. 05
    封装成 skill批量生成不同风格的场景
// 示意:资产元数据字段 { "path": "/Game/Props/SM_Bench", "aabb": [180, 46, 52], "pivot": "bottom_center", "forward": "+X", "place_on": "floor" }
生成结果与对应的 JSON
FIG 2-I生成结果与对应的 JSON
FIG 2-J自动摆场录屏
02-C

对话式建工具

在终端里描述需求,生成并注册 LightCraft 工具架上的新工具;再用工具架一键重建小镇,拖动 Spline 实时重算。

REEL终端对话建工具 → 工具架一键重建小镇 · 录屏 1:39
ALSO俯视图 → 布局 JSON

城镇 / 地图俯视图转成建筑、道路、围栏的布局 JSON,在 Houdini 里一键还原。

ALSO编辑器桥接

让 AI 直接读写 UE 编辑器里的工具面板参数、执行编辑器 Python。

03

CASE 03 · SPLINE TOOLKIT

Spline 构件工具族

一条 Spline 进去,出来一段能直接进项目的铁路。同一套做法后来又做成了围栏、管道、花坛和飘旗。首屏那段可拖动的铁路,就是它的简化版。

TIME
2025.06 — 2026.09
PIPELINE
Houdini Engine → UE
STACK
HDA · VEX · USD · Instancing
ROLE
工具设计 · 实现 · 迭代

NEED / 需求

铁路、围栏、管线这类沿线构件数量大、改得勤。手摆一遍,线一改就全部返工。

PROBLEM / 难点

  • 道岔、交叉口这类拓扑变化
  • 和道路相交时要剔除,还要重排交叉口的枕木
  • 起伏地形上要保证坡度连续,不能贴着地形抖
  • 要能接项目的 USD 流程,资产随时替换

SOLUTION / 方案

  1. 按类型分别输出:轨枕、扣件输出为点云 + unreal_instance 属性,交给 UE 实例化;钢轨和道砟直接程序化建模
  2. 拓扑处理:自动生成道岔;遇到道路时剔除,并重排交叉口枕木
  3. 地形适配:沿线采样高度后平滑,再把路基压进地形
  4. 资产解耦:接入 USD 流程,换掉模型就能复用到别的项目

铁路迭代

ITERATIONS
  1. 2025.06项目适配适配项目铁轨,接入 USD 流程
  2. 2025.07道岔 · 完成版道岔拓扑,HDA 参数面板
  3. 2025.09道路剔除优化交叉口枕木生成逻辑
  4. 2025.10替换项目模型资产与逻辑解耦
  5. 2026.08起伏地形支持高低起伏的地形
FIG 3-A拖动控制点,道路剔除区和枕木实时重算(完整录屏 3:40)
完成版 + HDA 参数面板
FIG 3-B完成版 + HDA 参数面板
道路剔除区域
FIG 3-C道路剔除区域
起伏地形适配
FIG 3-D起伏地形适配
替换项目模型后
FIG 3-E替换项目模型后
Houdini 视口:道岔拓扑
FIG 3-FHoudini 视口:道岔拓扑
01分组 · 切线SETUP 02交叉剔除CULL 03枕木SLEEPER 04道岔连接DIVERSION object_merge · set_combine_sleeper set_diversion_groups — 标记道岔一 / 道岔二的点组set_diversion_groups store_diversion_pos — 记录道岔起点位置store_diversion_pos orientalongcurve2 — 沿曲线建立朝向orientalongcurve2 get_tangentu — 求切线方向get_tangentu set_combine_sleeper — 标记需要合并枕木的区段set_combine_sleeper subnet1 — 子网络subnet1 fuse2 — 合并重合点fuse2 attribdelete2 — 清理中间属性attribdelete2 intersectionanalysis — 求交点intersectionanalysis remove_useless_point — 删掉多余的点remove_useless_point group2 — 交叉区域分组group2 find_shortest_dist — 按最短距离处理交叉口find_shortest_dist groupcombine1 — 合并枕木分组groupcombine1 blast5 · not_combine — 去掉不合并的部分blast5 · not_combine resample5 — 按间距重采样resample5 cal_sleeper_width — 计算枕木宽度cal_sleeper_width find_diversion_ends — 找道岔起点和终点find_diversion_ends add1 — 补点add1 get_ending_width — 读取道岔末端宽度get_ending_width fuse1 — 合并重合点fuse1 apply_width_change — 沿道岔改变宽度apply_width_change connect_corresponding — 三次贝塞尔连接道岔两端的对应点connect_corresponding grouptransfer1 — 传递分组(引用 set_combine_sleeper)grouptransfer1 attribwrangle11 — 整理输出属性attribwrangle11 object_merge14 — 输出 OUT_Rail_Road_MeshOUT_Rail_Road_Mesh
FIG 3-GRailTool HDA 内部网络(按实际网络整理,节点名有简化)· 悬停节点看说明

同一套思路,一族工具

TOOL FAMILY
FIG 3-H围栏工具
飘旗工具 · 场景成图
FIG 3-I飘旗工具 · 场景成图
围栏:参数与资产槽
FIG 3-J围栏:参数与资产槽
花坛工具
FIG 3-K花坛工具
管道工具 · 软管
FIG 3-L管道工具 · 软管

取舍:飘旗怎么"飘"

DECISION
OPTION A✕

VAT 贴图

效果最自然,但转成 Spline Mesh 之后形变会很怪。

OPTION B✕

材质噪声

实现简单,但绳子两端也会跟着一起动。

OPTION C✓ 采用

绳子不动 + 顶点色驱动旗面

绳子贴合 Spline 保持静止,旗面按顶点色权重单独飘动。

FIG 3-M飘旗:顶点色驱动的飘动
LightCraft 工具架
FIG 3-N工具架:所有 Spline / PCG 工具的入口
04

CASE 04 · FX & PERFORMANCE

效果实现与性能选型

同一个花房碰撞破碎,用四种做法实测包体和运行开销,按数据选方案;布料模拟也按同样的思路边做效果边压包体;植物交互用 Pivot Painter 2,并写了 Houdini 处理脚本自动给树分层。

TIME
2026.05 — 2026.10
ENGINE
UE5 · Houdini DOP / HDA
STACK
VAT · Skeletal · Chaos GC · Cloth · Pivot Painter 2

花房碰撞:四个方案的包体

MEMORY · MB
  • 骨骼动画Skeletal + Anim + Skeleton
    包体最大
    220MB
  • GC 碎块StaticMesh + GeometryCollection
    实时碰撞,2000 个碎块时明显卡顿
    200MB
  • 蓝图StaticMesh + DataTable + Struct
    包体小,但要从 DT 生成 StaticMesh,每帧读骨骼变换矩阵,开销很大
    60MB
  • VATStaticMesh + Texture
    包体最小
    40MB

帧耗时

STAT UNIT · 同机位 · 多出的 ms
  • 骨骼动画Game + GPU 蒙皮
    骨骼数多,蒙皮开销随碎块数上涨
    2.6ms
  • GC 碎块Chaos 物理
    2000 个碎块时物理线程吃满
    9.8ms
  • 蓝图Game 线程
    每帧从 DT 读骨骼变换矩阵
    5.4ms
  • VATGPU 顶点偏移
    只多一次贴图采样
    0.4ms
✓ 采用 VAT

包体最小(40 MB),帧耗时也最低:播放只在 GPU 上做顶点偏移,不跑物理、不读骨骼矩阵。代价是破碎过程预先烘焙,不能实时响应碰撞——花房破碎是固定演出,这个代价可以接受。

FIG 4-AVAT 与骨骼动画:UE 内效果与性能对比

布料模拟

CLOTH
FIG 4-B布料模拟
FIG 4-C按角色动画调整布料
FIG 4-D布料材质优化,减小包体
FIG 4-E · NOT PUBLIC
布料最终效果

最终效果用在项目里,画面未脱敏,这里不放。上面三段是同一套做法的过程录屏。

植物交互 · Pivot Painter 2

PIVOT PAINTER 2

草要被踩出压痕,树和灌木被角色碰到要逐级摆动。Pivot Painter 2 把每根枝条的轴心和层级烘进贴图,摆动全在顶点着色器里算,不走骨骼也不走物理。手工给一棵树分层太慢,我在 Houdini 里写了处理脚本,把整棵树自动拆成 PP2 需要的层级。

— 移动鼠标 = 角色碰撞 · 悬停看元素
  1. 01
    每个元素一个轴心主干、枝、细枝、叶各是一个刚体元素,只绕自己的轴心转
  2. 02
    烘进贴图轴心位置写进 RGB,层级和父级写进 A;每个顶点的 UV 指向自己那一格
  3. 03
    着色器里逐级叠加先转父级再转子级:叶跟着枝,枝跟着干,全在顶点着色器里算
PIVOT POS · RGB
LEVEL / PARENT · A
FIG 4-F原理演示:鼠标当作角色推开枝叶,悬停元素看它在贴图里的那一格和父级链;关掉「逐级叠加」,子级不再跟随父级,这就是 PP2 要存层级的原因
FIG 4-GUE 场景交互:草地压痕 / 角色植物碰撞,左上角可分别开关(录屏 1:44)

Houdini 处理脚本

HDA · PivotPainter2.0
  1. 01
    导入树模型直接读 FBX,可选把 SpeedTree 的遮罩转进 Alpha
  2. 02
    拆分主干 / 枝 / 叶主干按面组选取,叶子按材质分离;三部分分色显示,一眼能查错
  3. 03
    求每根枝的轴心按距离搜索父级,自动修复错位的枝条轴心,轴心可视化检查
  4. 04
    合并层级自动合并到 PP2 支持的层数:主干单独一级,叶子并入最末一级
  5. 05
    逐枝处理并输出for-each 遍历每根枝条:补面、测量、排序,输出 UE 用的 Pivot Painter 数据
FIG 4-HHoudini:拆分主干 / 枝 / 叶 → 轴心可视化 → 层级合并 → 节点网络(录屏 0:58)
∑

工具墙

主案例之外的 Houdini / UE 工具。悬停或点按查看说明与截图。

A

地形 · 水系

3 个工具 · HOUDINI / UE PCG / GAEA
01
HOUDINI · UE地形流水侵蚀 · 河流

Houdini 里做流水侵蚀,生成冲沟与沉积;沿路径切出河道并与地形融合,再进 UE 出图。悬停自动播放,拖动底部进度条可定位到任意一帧。

0:00 / 0:36
地形侵蚀 · 水系路径01-A
UE PCG地形侵蚀 · PCG 寻路

在地形上摆几个目标点,PCG 沿地势寻路,长出分叉的冲沟走向;红框是最终收敛出的水系路径。

河道01-B
HOUDINI · UE河道

沿路径切出河道,并与地形融合。

Biome Core × Gaea 地形与植被02
UE BIOME CORE · GAEABiome Core × Gaea 地形与植被

用 Biome Core 和 Gaea 生成地形与植被,两者本地联通,全程只需在 UE 里操作。

Biome 区域遮罩02-A
UE BIOME COREBiome 区域遮罩

在 UE 里划分 Biome 区域,驱动对应的地形与植被生成。

B

DCC 工具

HOUDINI · USD · MAYA
窗框破碎03
HOUDINI窗框破碎

塑钢断裂、金属爆炸形变,以及窗框边缘的玻璃碎渣。

石头高模磨损04
HOUDINI石头高模磨损

给石头高模批量做边缘磨损和细节。

视角剔除不可见面05
HOUDINI HDA视角剔除不可见面

按给定视角删掉看不到的面,用于远景减面。

2UV 工具 · 树木适配06
HOUDINI2UV 工具 · 树木适配

让 2UV 拆分工具适配树木这类复杂模型。

LOP 下的 USD 模型处理07
HOUDINI · USDLOP 下的 USD 模型处理

在 LOP 里批量处理 USD 模型的 HDA。

Lightmap UV 拆分08
HOUDINI · USDLightmap UV 拆分

解决 LOD 无法选择编辑、USD 导入导出后数据变化等问题。

HDA 接入 Maya 工具架09
HOUDINI · MAYAHDA 接入 Maya 工具架

Houdini 生成 JSON 驱动 Maya 本地工具,HDA 直接放上 Maya 工具架。

C

UE 场景

UE PCG · 蓝图 · HOUDINI USD
围墙工具10
UE 蓝图 · PCG围墙工具

第一个工具,迭代到现在这版:沿 Spline 放样,多种模块按权重随机,缩放、偏移、间距和端头收口都能调。

彩旗工具11
UE PCG · 蓝图彩旗工具

在场景里画一条 Spline,PCG 沿线挂出下垂的彩旗串,旗面配色随机。

线缆工具12
UE · HOUDINI · USD线缆工具

在 UE 里选中挂点一键生成线缆,Houdini 端经 LOP / USD 调用 HDA 计算形状。

藤蔓工具13
UE · USD藤蔓工具

点选主枝、画避让曲线,Cook USD 后藤蔓沿屋面生长。

D

实时 Demo

THREE.JS · 参数化复现
藤蔓生长 · 实时交互 Demo
LIVE 可交互 · 点击放大
THREE.JS · WEBGL · 实时 藤蔓生长 · 可交互复现

上面那张「藤蔓工具」干的是给建筑表面长植被:给主枝走向和避让曲线,程序铺主干、分叉、挂叶,Cook 成 USD 进 UE。这个 Demo 用 three.js 复现了同一套生长规则,拖着就能试。

ME

关于

PCG 方向技术美术,做开放世界场景的程序化工具和生产管线。

做工具习惯从美术需求倒推:先想清楚美术要调什么,再决定哪些参数暴露出来、哪些交给规则。做效果则先把几种方案都实测一遍,用包体和帧耗时的数据来选。

  • HOUDINIHDA · VEX · USD / LOP · DOP 模拟 · Houdini Engine
  • UNREALPCG / PCG Runtime · Biome Core · 蓝图 · Scriptable Tools · 编辑器 Python
  • SHADER / FXHLSL · VAT · 布料模拟 · Pivot Painter 2
  • PIPELINEUSD 导入导出 · Maya 工具架集成 · 批量生产
  • AI大模型驱动的布局生成 · Skill / 工具链封装
+

附录

上一份工作的述职报告,作为补充材料。左右方向键或点缩略图翻页。

述职报告 第 1 页
述职报告 · 白露影视 UE 地编 / TA · 2024.07 – 2025.03 · 仅供在线浏览01 / 38