这是我的第一个完整程序化世界构建基础项目。
这个项目不是要做一套能解决所有程序化城市问题的系统,也不是要展示某个 Houdini 或 UE5 PCG 技巧。我想做的是一条能跑通的跨工具生产管线:
从地形和空间条件出发,在 Houdini 里完成聚落规划,再把规划数据交给 UE5,由 PCG 生成建筑和自然环境。
系统的数据流是:地形与环境约束 → 聚落规划 → 道路/地块/建筑规则 → 规划数据发布 → UE5 → 建筑 PCG/自然环境 PCG → 最终环境
这个项目主要处理三个问题:
不同尺度的生成结果怎么互相约束;
Houdini 和 UE5 怎么分工;
上游得到的信息怎么传给下游。
1. 约束传递
一开始,我把这个问题看成几个生成器:道路生成、地块生成、建筑生成、植被生成。
把这些部分接起来以后,我发现更重要的问题是:上一层的信息能不能影响下一层。
地形限制聚落范围。聚落结构决定道路。道路形成地块边界。地块再提供建筑的尺寸和朝向。进入 UE5 后,道路、建筑、河流和 Landscape 数据继续影响自然环境。
因此整个管线更接近一个逐层收缩自由度的过程:环境 → 结构 → 空间约束 → 语义区域 → 资产变化
道路系统是一个例子。
道路有自己的规划层级,但规划宽度不一定能直接落到场地里。路口空间和地形都可能让道路需要调整。系统要尽量保留原来的道路关系,同时让几何成立。
地块也是一样。一个地块面积很大,不代表里面一定有合适的建筑空间。Houdini 会继续判断建筑能用的区域,再从地块里得到:位置、立面朝向、最大宽度、最大进深、地块类型
这里的关键是这个转换:几何 → 可用空间约束
从这里开始,下游不用再分析原始地块,只需要读取这些约束。
2. 规划数据发布
项目做下去以后,我放弃了“让 Houdini 生成整个世界”的方向。
道路拓扑、地块边界、建筑尺寸这类问题适合放在 Houdini 里处理。它们依赖空间关系和几何计算。
建筑模块、围栏、植物、岩石和场景装饰则更适合放在 UE5 里。它们会跟着资产库和场景需求变化。
所以我把 Houdini 的角色定义成:
规划数据发布器
它不负责完成所有视觉内容。它负责把规划结果交给下游。
比如,一个复杂地块可以在 Houdini 里经过很多计算,但 UE5 不需要知道这些过程。它只需要知道:
建筑在哪里?
应该朝向哪里?
最多可以有多大?
这是什么类型的地块?
道路可以输出几何,也可以保留中心线和层级。河流可以输出样条线。开放空间可以只输出边界,让 UE5 决定里面放什么。
这样一来,Houdini 的输出不再只是“导出的模型”,而是规划数据。
3. 语义数据契约
这个项目里,我最看重的一层设计,是 Houdini 和 UE5 之间的数据接口。
如果只把两者理解成:Houdini → 生成几何 → 导出 → UE5。那么很多信息会在软件切换时丢掉。UE5 不只需要知道几何在哪里。它还需要知道:这是什么、属于哪一类、和其他数据有什么关系。
所以 Houdini 会发布不同类型的数据,比如:建筑规划点、建筑地块边界、道路中心线、河流曲线、桥梁参考数据、开放空间地块、Landscape / 环境遮罩
这些数据可以是点、曲线、几何或属性,但它们都有自己的用途。建筑数据用稳定的标识保持关系。不同数据通过语义层分流。地块类型、朝向和尺寸继续影响建筑生成。这样,两个软件之间传递的就不只是几何,而是一份数据契约:
Houdini:
这是什么?
它在哪里?
它带有什么约束?
UE5:
当前资产系统应该怎样表现它?
UE5 PCG 的职责也随之明确。建筑 PCG 读取 Houdini 提供的空间约束,再把这些约束转成建筑、特殊建筑和场景内容。自然环境 PCG 读取道路、建筑区域、河流、开放空间和 Landscape 遮罩,再用这些数据生成树林、村镇植被和河岸环境。两套系统做的事情不同,但它们都使用同一套规划数据。
这个项目验证了什么
相比某一个算法,我更在意这套工作方式能不能跑通。
第一,多尺度问题需要清楚的职责划分。
每一层只处理自己需要处理的问题,系统才不会失控。
第二,语义数据和几何同样重要。
标识、类型、朝向、尺寸约束、层级等信息,让不同工具和不同生成阶段保持联系。
第三,程序化项目也需要停止边界。
这个系统还可以继续扩展,但当前版本已经完成了核心验证:
环境约束
→ 聚落规划
→ 结构化数据发布
→ UE5 PCG 消费
→ 最终环境
This is my first complete procedural world-building foundation project.
The goal was not to build a universal procedural city system. It was also not a showcase of one Houdini or UE5 PCG technique. I wanted to build and test a complete cross-tool pipeline.
The process starts with terrain and spatial constraints. Houdini handles settlement planning. It then publishes planning data to UE5. UE5 PCG uses this data to generate buildings and natural environments.
The data flow is: terrain and environmental constraints → settlement planning → road / parcel / building rules → planning data publishing → UE5 → building PCG / environment PCG → final environment
The project focuses on three questions:
How can results at different scales constrain each other?
How should Houdini and UE5 divide the work?
How can upstream information be passed to downstream systems?
1. Constraint Propagation
At first, I saw the project as several separate generators. One generated roads. One generated parcels. One generated buildings. One generated vegetation.
After connecting them, I found a more important problem:
Can the result of one layer affect the next layer?
Terrain limits where a settlement can grow.
The settlement structure defines the road network.
Roads create parcel boundaries.
Parcels provide building size and orientation constraints.
In UE5, roads, buildings, rivers, and Landscape data continue to affect the natural environment.
The pipeline gradually reduces the available freedom: environment → structure → spatial constraints → semantic regions → asset variation
The road system is one example.
Roads have planned hierarchy and width. But the planned width does not always fit the real space. Intersections and terrain can force the geometry to change.The system tries to preserve the road plan, but the final geometry must still work.
Parcels have the same problem.A large parcel does not always contain enough usable space for a building. Houdini checks the usable area and extracts: Position, Facade Direction, Maximum Width, Maximum Depth, Parcel Type
The important step is this:
Geometry
↓
Usable Spatial Constraint
After this step, downstream systems do not need to analyze the original parcel again. They only need to read the constraints.
2. Planning Data Publisher
As the project grew, I stopped trying to make Houdini generate the whole final world.
Road topology, parcel boundaries, and building size constraints fit well in Houdini. They depend on spatial relationships and geometry processing.
Building modules, fences, plants, rocks, and scene dressing fit better in UE5. They change with the asset library and the visual needs of the scene.
So I define the role of Houdini as:
Planning Data Publisher
Houdini does not need to create every final visual element.
Its job is to publish planning results for downstream systems.
A complex parcel can go through many calculations in Houdini. UE5 does not need to know those steps.
It only needs to know:
Where is the building?
Which direction should it face?
How large can it be?
What type of parcel is this?
Roads can output geometry, center lines, and hierarchy data.
Rivers can output splines.
Open spaces can output only their boundaries. UE5 can decide what to place inside them.
The Houdini output is no longer only an exported model.
It becomes planning data.
3. Semantic Data Contract
The most important design layer in this project is the data interface between Houdini and UE5.
If the workflow is only: Houdini → generate geometry → export → UE5
then a lot of context is lost when the data moves between tools.
UE5 needs more than geometry.
It also needs to know:
What is this?
What type is it?
How is it related to other data?
Houdini therefore publishes different types of data:
Building Planning Points
Building Parcel Boundaries
Road Center Lines
River Curves
Bridge Reference Data
Open-space Parcels
Landscape / Environmental Masks
The data can be points, curves, geometry, or attributes.
Each type has a clear purpose.
Building data uses stable IDs to keep related data together.
Semantic layers separate different data types.
Parcel type, orientation, and size constraints continue to control building generation.
The connection between Houdini and UE5 becomes more than geometry transfer.
It becomes a data contract:
Houdini:
What is this?
Where is it?
What constraints does it carry?
↓
UE5:
How should the current asset system represent it?
This also makes the role of UE5 PCG clear.
Building PCG reads spatial constraints from Houdini. It converts them into buildings, special buildings, and local scene content.
Nature PCG reads roads, building areas, rivers, open spaces, and Landscape masks. It uses this data to generate forests, settlement vegetation, and riverbank environments.
The two systems generate different content.
But they both use the same planning data.
What This Project Validated
I care more about the workflow than any single algorithm.
First, multi-scale problems need clear responsibilities.
Each layer should only solve the problems it needs to solve.
Second, semantic data is as important as geometry.
IDs, types, orientations, size constraints, and layers keep information connected across tools and generation stages.
Third, a procedural project needs a clear stopping point.
The system can still grow, but the current version already validates the main pipeline:
Environmental Constraints
→ Settlement Planning
→ Structured Data Publishing
→ UE5 PCG Consumption
→ Final Environment