5 Obscure Features of PCG in UE5

5 Obscure Features of PCG in UE5

Procedural Generation Framework, or PCG for short, is a great little system which first shipped in Unreal 5.2 and instantly caught my attention.

While there are many examples of all the things you can use it for, most of them use the same basic set of nodes and hardly even venture into more obscure and hidden features PCG has to offer. This is what always happens when a shiny new thing comes out, but it also makes it really hard to find answers to more specific questions and aspects of PCG.

That’s why I’ve decided to compile this short list of things I got working so far - hopefully having them all in one place will save other people some time.

Keep in mind - materials from this article use Unreal Engine 5.3.2 and may become partially outdated after the new version releases.

1.How to use the loop node

So the sensible thing to think when seeing the Loop node for the first time would be to imagine it doing something (in our case - executing a subgraph) for every PCG point you have. But in reality this is not the case. Instead, it runs a loop on every group of points that you need to split beforehand. Those point groups are very easy to miss in the current UI, but they can be found here:

Creating them is rather simple - just use an Attribute Partition node - it will separate all points based on the attribute you choose. So to have the loop running on every point individually, you’ll need to have an attribute with a unique value. Probably the easiest solution would be to copy the point index to a new attribute.

In this example what we get are meshes that get scaled up by their point index attribute, from bottom right to top left corners:

2.Provide HISMs with Per Instance Custom Data

This one is more easily googleable but is too useful to leave out. You can pass attributes to Static Mesh Spawner and later access them in your materials via the Per Instance Custom Data node. In practice this allows you to offload some math from your shader and precompute things like random values, color variation or distances to something and store that on instances.

Here's how it looks with the material applied:

Also, while we are still talking about Static Mesh Spawner - if you’ve used PCG as a component inside a blueprint you may have noticed that changing its mobility setting doesn’t alter the mobility of generated HISMs. This setting only works when using PCG as an actor in the scene. So to change the mobility inside of a blueprint, change it on the parent actor itself - all child components will share the setting.

Another useful thing to have is to provide meshes for the mesh spawner as a string attribute containing reference to a mesh. Top part shows how to assign a mesh via add attribute node and the bottom one does the same thing, but with a more convenient static mesh selector as a custom PCG node.

Here’s what happens inside of that custom node. In the Execute with Context function we get a reference to a static mesh, then create a new attribute utilizing the Mutable Metadata node. After this, inside the Point Loop Body function we can write the mesh reference to that newly created attribute:

3. Filtering points by attributes

The default way to filter points is by copying data into the Density attribute and using the Density Filter node. But if you want to filter by other attributes, then it quickly becomes bothersome to write attributes to density each time, so a more convenient way is to create a custom node.?

For this to work we will override the Point Loop Body function and check our attribute there. Since what is inside the point loop function runs on every point, we need to create a variable to check against and then check for our condition. We plug the result of our check to the Boolean function output. This will exclude every point that failed and give us the rest of the points.

You can make multiple nodes to check different variable types and condition. Things you can use this filter for:

  • Specific point colors
  • Points transforms like rotation or position
  • String attributes like reference to a mesh or material

4. Creating Post-Spawn functions

Sometimes you may want to include extra logic happening after PCG was generated. Common examples would be changing hard-coded HISM settings or triggering an initialization of an actor created with a Spawn Actor node. To do that, there is a thing called the Post-Spawn function which will trigger automatically after every regeneration. Let’s see how to call those in each of the cases mentioned:

Post-Spawn function in a PCG Blueprint

This requires the PCG to be a component inside of a blueprint. After creating a function you want to run in such a blueprint, enable the “Call in Editor” checkbox and add a single variable as input - PCG Tagged Data. Even if you do nothing with it afterwards, without this the function doesn’t trigger. Then find the Post Spawn functions list on the PCG component and add the name there:

This functions counts the amount of instances after generation:

Post-Spawn function on a spawned Actor

This one is more straightforward?- create a function inside the actor you want to spawn, enable the “Call in Editor” checkbox and make sure it doesn’t have any input variables. Then add its name to the list of functions in the node itself:

5. Building PCGs in a functional way

One last thing you can try is to split your PCG logically into multiple stages, each taking points with attributes and passing them onto the next one.

For example, you can separate point generation from multiple sources and then have a single spawner PCG. This will lower the complexity of the individual PCGs, and will let you reuse them for faster iteration time. Also stops them from becoming a noodle mess.

A framework I have in mind when doing this is to split the system into 3 different stages:

  1. Surface Sampling - Here go initial landscape sampling, point erasers, volume and actors sampling.
  2. Point Creation - Here you make groups of points with bounds that match your meshes to then copy them on top of previously made surface points.
  3. Spawning - After you get all the points you can utilize custom nodes to assign and randomize mesh and material attributes, spawn actors or PLA and do any final tweaks.

Looking Forward

There are some things I’ve tried, but want to spend more time with to test and experiment, before writing about them. I am sure that after 5.4 releases this list will become even longer, so there are still lots of things to discover:

  • Using PCG with Geometry Script (PCGGeometryScriptInterop Plugin)
  • Advanced usage of World Ray Hit Query
  • Gameplay-oriented usage of PCG
  • Large-scale PCG graph optimization for faster generation


Mario Cola

B2B Sales | 10 years experience

3 周

Nice article! I'm wrapping my head around HiGrids pitfalls, maybe you already encountered this. Let's say I spawn houses and trees and I set the trees to spawn around the houses: if I set a distance to keep between houses and trees, this distance won't be applied for objects in reference to the neighbour HiGrid and they could even overlap near the boundry. Did you ever encountered this with hierarchical grids?

回复
Auke Huys

Technical Enviromment Artist and Team Lead

4 个月

A really nice article you have written here - didn't knew, that I had to create partitions for every point in order to loop through them. Had some troublesome hours last friday because of this :D That being said, thanks :)

Sergey Filin

Procedural Technical Artist | Houdini Artist | Unreal Tools Developer

6 个月

Awesome! Thank you!

回复

Impressive insights on the PCG features in UE5—your article really helps shed light on some of the lesser-known aspects of procedural generation!

回复

要查看或添加评论,请登录

Ramil Roosileht的更多文章

  • Upgrading Promo Art pipeline of NITRO NATION

    Upgrading Promo Art pipeline of NITRO NATION

    Hey there! I am Ramil Roosileht, senior tech artist working at CM Games. In this article I’d like to tell you about how…

    2 条评论

社区洞察

其他会员也浏览了