LongCut logo

Leveraging PCG for Building and City Creation | Unreal Fest Bali 2025

By Unreal Engine

Summary

## Key takeaways - **Procedural Thinking for Environment Creation**: Procedural thinking involves identifying patterns and applying similar operations to solve complex environment creation tasks, which is fundamental to leveraging tools like PCG for dynamic city and building generation. [01:46], [01:50] - **PCG Framework for Scalable Cities**: The Procedural Content Generation (PCG) framework in Unreal Engine 5 enables the automation of complex environment creation, allowing developers to build scalable and immersive cities efficiently by managing modular assets and flexible grammar rules. [02:06], [02:11] - **Modular Asset Design for PCG**: Designing modular assets in software like Plasticity and then processing them in Houdini for UV naming and FBX packing is crucial for their effective use within the PCG framework, ensuring they integrate correctly with materials. [03:04], [03:10] - **Grammar for Pattern-Based Generation**: Grammar in PCG provides a structured way to define patterns for elements like walls and floors, recently added in Unreal Engine 5.5, simplifying controls for artists through buttons and presets. [03:23], [03:30] - **Dynamic Building Generation with Attributes**: By adding attributes like 'shrink direction' and 'shrink strength' to floor points, and utilizing noise and rounding nodes, buildings can be procedurally generated with varied floor sizes and shapes. [06:37], [06:45] - **Automated Wall and Corner Module Placement**: Walls and corners can be procedurally generated by splitting floors into cubes, moving them, and using subtraction operations, which then react dynamically to building size changes. [10:24], [11:14]

Topics Covered

  • Why procedural results should be quantized, not random.
  • How can props intelligently adapt to any surface?
  • Create smart assets aware of their environment.
  • How nested procedural tools enable scale and control.
  • How one material can create infinite procedural variations.

Full Transcript

All right, thank you so much for coming.

My name is Daniel Mo. I'm a technical

artist at virtuals and I like to do

portal tools and creating games.

Today we're going to talk about PCG and

buildings. We'll take a short look at

the results and create a similar tool

set. So, first a quick video showing the

results. Heat. Heat.

[Music]

Heat. Heat.

[Music]

All right. So, let's take a closer look

at the buildings tool feature. In this

talk, we're going to mostly focus on

this one, the buildings. We're going to

change the size, floors, and props here.

And we're going to sort of learn

procedural thinking. How can we spot

patterns and use similar operations to

solve them? Here are some buildings

variations. So, we randomize here the

the props, the floors, and here are some

variations

here. Next is the city tool.

We will move the city around. The tool

is showing a preview mode by default. We

can change parameters such as seed and

size and control the results by setting

the minimum and maximum floors for

example. So we kind of control the

ranges. Eventually we will generate the

actual buildings. So it's kind of a tool

that contains the building tool.

Let's view the materials functionality.

The material itself is very basic. No

textures. I'm going to share a few

tricks. First, how to create the mask

that we did and add the variations for

actors or instances. So, we can do both

of them. Here we change the basic

material properties, color, metallic,

roughness.

Modules.

The modules were designed in plasticity.

In Udini, we've done UV naming and

packed in FBX. Here you can see it in

with the material we went over earlier.

Grammar is a fancy way to describe

patterns in the context of building. We

will set walls and floors patterns. It

was added recently in Unreal 5.5.

This shows a button for artists to

interact with predefined wall patterns.

The idea is to kind of simplify the

controls wherever we can, either by

using buttons, presets, or anything that

is simple to do.

We will now set up the project.

We would prioritize logic over just

connecting nodes or doing a step-by-step

tutorial. I hope to deliver value for

both beginners and advanced users.

building tool. So, let's set it up.

Start by enable building the PCG plugin,

edit plugins PCG, and just enable it.

To create assets, simply right click in

your content browser, click the

blueprint class, and choose actor, name

it, and type PCG to do the same.

Open the blueprint.

Add a PCG component and link the PCG

asset to it.

Our goal now is to control the size and

the amount of floors of the building.

Open your blueprint and add three

parameters. Floors, size X, and size Y.

They will be whole numbers, integers.

We are now going to open our newly

created PCG class. We're going to use

the get actor property node and just

read the variables by specifying its

name. We basically read it from the

blueprints.

Next, we're going to use the create

point grid node. It is used for floors

and the size of the building. Here we

basically create one point for floor per

floor.

With this node, we get the power to sort

of precisely spawn points. It can be a

2D grid like the name of the node. And

it can also be a 3D one or a point above

another point which is just perfect for

floors. Here,

this is how your graph should look like

so far. You will notice a few more

nodes. I added some math nodes such as

converting meters to cm. I'm not going

to focus on them a lot today.

We're going to keep them pretty simple.

Add subtract multiply flow and

modulo.

Here are all flows. I added a gap here

between for visibility. But if you

choose your if you select your create

grid node and press D for debug, they

should appear on top of each other.

Sometimes some floors can be bigger or

smaller than others. We can kind of use

that fact to generate more interesting

buildings. So, let's mess a little bit

with the floor size.

Since every point or cube, which I will

use interchangeably here, can contain

attributes. We're going to add an

attribute for each floor. The first one

will be shrink direction. Add the noise

and round nodes. The noise will generate

a 0ero to one values. The round will

ensure that we get either zero or one.

If the attribute of that flow is zero,

we're going to shrink it from the front.

If it's one, we will shrink it from the

back.

But direction is not really enough. How

strongly do we want to shrink its flow?

40% 60%.

Another attribute can help us answer

this question.

It will be shrink strength. It's going

to be the same idea. 0 to one noise, but

this time we're not really going to use

round at all. So a zero would mean no

shrink and 04.5 would mean 50% shrink.

We can also spice it up a little bit

with some height gradient. So we can

control that lower floors will shrink

more or less depending on what you want.

One problem with shrinking floors is

that we might get some small deviations.

Usually it will look bad and

unintentional.

To fix that, we're going to sort of step

our shrink allowing only few specific

shrink shrink values.

If we allow three values 0, 50, and 100,

a 60% shrink will become 50%. And 10

will become zero, meaning we don't

shrink.

Six to eight steps work well for me, but

honestly, meters per step would be more

reliable.

Before we continue, let's create sort of

two mini tools. We're going to use them

a lot.

This one splits any cube to smaller

cubes. It will measure the size of the

cube and break it down accordingly.

It means that this cube, let's say a 3x3

m, will be sliced to 27 smaller cubes.

Next, we're going to normalize float.

It's another sort of subgraph. So let's

say each flow has an attribute 0 is zero

and one is one up until floor 9. We can

find the maximum and minimum attributes

of those flows and compress them into 0

to one range. So floor zero stays at

zero. Floor 9 now becomes one and the

rest of the floors are somewhere in

between.

So far we just played with attributes.

We didn't really we didn't really do any

shrinking. So let's do it by looping

over each floor.

In the shrink loop, each floor will be

converted to 1 m cubes with the mini

tool we created earlier. The position of

each row of cubes will be normalized

between zero and one.

Filter any row with lower density than

the floor shrink strength. The second

floor is shrinking for 40% from the

front. We just delete values below gray.

This is our graph so far. Most of the

extra stuff that I didn't mention are

just extra controls for the user. For

example, disable shrinking altogether or

allow one direction.

And there it is. We shrank the floors.

They now adapt to the size of the

building. And we've added control for

seed, direction, strength, and steps.

But first, let's do some walls and

corners. We can spawn them. We're going

to start by splitting the floors into

first floor and other floors.

The input of the node will be floors

after we shrink them. The output is

going to be walls as corners. Walls and

corners as modules.

We are going to work with a period of 1

m cubes. This time we're using a 2D

grid. No need for a three-dimensional

one. We will move them around and just

check if they overlap. That's about it.

So to create point grid,

uh yeah, use the create point grid

again. This time we do not want many

cubes stucked vertically. Just one

there.

For the wall, duplicate the cube grid.

We're going to move it 1 m to any side,

either X or Y, and subtract from the

original. Now the wall is just ready as

1 m cubes.

For the corner, it's pretty much the

same idea. We just do it twice. We take

the wall, duplicate it again, and

subtract. So, we now get a corner piece.

Here's our tool so far. The corners here

are blue and the walls are made from 1 m

cubes. It reacts to size changes.

Now we're going to sort of split each

wall or rather combine those modules

since all of them are 1 m and sometimes

we want like 4 m pieces. We we we will

do it in the same in the next slide.

So the logic of the wall split is large

to small. We try here 4 m until we fail,

then 2 m until we fail again, and then

we fall back to 1 m, which we know we

always have.

The cuff itself is looking scary, but

it's pretty much the same row duplicated

four times. So let's dive into one row

first. To avoid errors, we will figure

out if there are any points left to fit

walls into. So keep the first point

using attribute filter. Add some

attributes. Uh we will set it to true

and then input it to the branch node. If

there are no points, the attribute the

branch node will interpret that as false

as it didn't really add a true attribute

here. And then it will effectively stop

the flow of the graph outputting to a.

If we do find points to fill wall to fit

walls into filter the ones that fit

using attribute reduce modulo and filter

by range. In this part we get the sort

of remainder the part that won't fit and

we can final it into the next small

module smaller model test below.

Lastly, we divide by the index.

We divide the index by the module size,

floor, and partition.

So, let's take a look at like a 2 m

example. Indices are usually zero and

one. We're going to divide them by two

for 2 m. This will yield 0 and 0.5.

Flowing it will give us zero for both 1

m cubes. So now the indices are 0 0 1 1

22.

We're going to partition the cubes

according to their new index. Basically

grouping each one each cube that are the

same index.

And this is our segmented walls. They

are not 1 m cubes anymore. They are kind

of combined cubes at different sizes

that we wanted.

We are now ready to actually spawn some

actual meshes. Filter the points

according to their type and dimensions

and uh sorry use match and set

attributes to specify which meshes to

spawn and eventually drop a static mesh

spawner.

But how do we actually specify which

meshes do we want to spawn?

We're going to create a struct a

structure. Open it up and add two

variables. One float for the weight and

one mesh for the mesh. Add it into your

blueprint just as a normal attribute.

Set the defaults.

And eventually go to the PCG building

and read it using the same node that we

did earlier. Get actor property.

Here's our building now with real walls

and corners.

You're going to notice some doors here.

Let's see how it was done.

Each wall segment will get a random

noise. The range of the front will be 0

to one. The sides will be zero to 0.5.

We're going to pick a module and just

simply convert it to a door.

It's going to be based on what's the

highest number. So, it will be very

likely that we get some door at the

front and less likely that we get a a

door at the sides.

Here's a zoomed out view of the doors

graph. And here's a video with some

close-ups. We use the building

circumference to determine how many

doors to spawn. We can simply count how

many 1 m cubes we have. And you can look

at it later in the recording to get some

more details.

And here are the doors marked in green.

Here we expose door frequency for this

and seed for the user. For example, I

want a door every 20 m. It will always

spawn one door. So we kind of force it

to spawn a door at the front.

Our graph just became too big for a

simple picture. Here's a video of it

now.

One type of control we want to expose is

SID. It will allow us to kind of

randomize the whole building by just

changing a number or randomize a

specific part of it such as roof pops.

Here's an example of global seed and

individual seeds being added together in

order to sort of determine the final

seed.

And here's another way to do it. I

wanted to stress that mutate seed is

kind of dependent on position.

So we can basically change the seed by

changing a little bit the position of

the building.

This will yield the different seeds if

we move them. And since our calculation

is at water region, it should be

consistent unless we change it.

A common issue is when you kind of move

your PCG graph, but it stays at the same

place at the world center. We can simply

move it to the to the center of the

actor.

We're going to use a new node get actor

data as a single point. This will kind

of give us a point where the actor

centroidid is. And this is where we're

going to keep every to copy everything.

I placed it right before spawning static

meshes. It makes the graph kind of more

stable.

Our building moves now and everybody is

happy.

Let's tackle the most important things

after walls. It will be roofs.

We're going to convert our floors to

cubes once again, but all of them. We're

going to duplicate it and move it

downwards 1 m.

Finally, we're going to just remove the

overlap and we end up with those roof

cubes.

Here we show the graph filtering the

roof locations 1 m cubes. Now, we're

going to just split it into bigger inter

bigger modules.

Let's apply what we learned here uh at

wall segmentation before, but this time

we're going to do it for the roofs. So

we're going from 1D algorithm here to

2D.

We're going to start with large models

4x4 m and then going smaller until we

reach 1 m.

Here we try 2x two. We got to the first

two and then we start failing because

there are just not enough cubes to

satisfy it. So we fall back to one by

one m.

The input of the graph are 1 m roof grid

and the size of the model you would like

to fit. Let's say 4 m or 2 m.

This is how the split graph works. We're

first indexing and then splitting to

valid or invalid modules.

We're going to set the index of each

cube in X and Y. So the cube of the corn

in the corner will be 0 0. the one next

to it will be zero and one.

Here's a more detailed explanation. You

can read it a little bit later, but the

idea is that we just check how many

cubes occupy each segment and then

determine if it's a valid segment or

not. So, with 2x two, we'll require four

cubes.

Now the roof is present adapting to any

changes including the size of the

building or the shrinking settings that

we set.

So far we made a lot of progress floors,

walls, doors and more.

We are now going to basically set dress

our building adding props, pillars and

floors just to generate some areas with

higher details.

So if the previous section was the

tutorial, this is the final boss. We're

going to do wall props.

The idea is to kind of avoid placing

props on open areas such as windows.

We want to avoid areas that stick out

beyond the wall's baseline, too. This is

a common problem, and usually we tackle

that with tugging areas or something

like that, but I wanted a fully potal

solution that kind of adapts to your

model.

So, we're going to scatter some points

on the walls and the props. We're going

to measure the distance of the props to

the walls using those points. If the

average distance in this case is less

than seven cm, the prop is determined as

valid.

For the main loop, we will loop over

each floor. We're going to input the

locations to test, the walls as points,

and the props as points.

And here's the full process.

If the average distance is too big, we

just discard the prop. We just compare

those points and if the distance is too

big, just discard it.

It's going to avoid windows and it also

adapts to changes of the input measures

or walls.

Here's a look inside a graph where we

use the distance node to compare

distances.

After we've done with the distance test,

we apply weights, remove overlap, and

add coverage attribute.

With the final node being a static mesh

spawner

and those are the results. Our props are

not floating. We didn't have to

explicitly indicate where they should

avoid. And it kind of leads to

interesting patterns.

It's also fast.

The wall props are kind of the most

complex part of this tool. For now,

we're going to speed up and focus more

on the logic.

Starting with the corner props, we're

going to duplicate the corners and move

them 1 m outwards. And that's it.

We're doing a very similar thing here.

Move noise normalize coverage and

SID. Nothing new. Here

are the results. We can change the

corner props coverage or change the

modules and their weight. Let's say we

want more of a specific model or we

don't want this module at all.

For the roof for the roof props, we

simply scatter. If we simply scatter

props on each roof, we're going to

encounter overhang like in this example.

To solve it, we are going to measure

each asset and based on its biggest axi,

we scale down the viable spawn

locations. Basically shrinking the roof

according to each asset. It's going to

help us avoid overhang.

This graph shows how to apply the logic.

We are looping over each each asset and

then shrink the floor the roof according

to it.

Here are the results. there's no

overhang and just many possible

variations.

We also rotate it by 90° increments and

make sure that there's no overlap. More

on that later.

For the exterior props, we are now going

to play with the roof cubes and the

walls cubes. We're going to just move

them around and find if they intersect.

The red cubes here are kind of perfect

for us. They're not floating and they're

close to the walls. A common place for

people to play stuff.

Here's a look at a graph. It's the same

nodes, but different outcomes

and the results. Just one more layer of

interesting stuff we've added to it.

For the railing, it's going to be the

same idea, but this time we're going to

play around with walls and corners.

Move both of them upwards and intersect.

By this time, I kind of hope you start

noticing a pattern. We're just moving

cubes and checking for overlap. Nothing

over complicated.

And this is the graph I've added here.

Uh tall pillars too, in between floors.

try to produce that logic. It's kind of

fun.

It starts to feel more grounded now with

the railing seat parameters are now

exposed for both the railing and the

short pillars.

It simply changes the model

for the foundation pillars.

Buildings usually float on uneven

terrain. Adding a foundation pillars can

sort of solve that so they will not

float and look kind of interesting.

We're going to measure the distance from

the go corners to the ground and then

spawn pillars accordingly.

Many things can be done this way.

This is how it looks applied to the

tool. We can apply this idea to many

assets. shoot rays in different

locations and sort of create a library

of smart assets. Assets that are kind of

aware of their environments. The pillars

here just won't spawn if they are not

needed, which leads to nice behavior and

optimized environments.

For the ground floor, duplicate the

bottom cubes, move them around, add them

to the original, and just spawn tiles

later.

We now have the floor. It's possible to

control the size, scale, tiles, and

railing.

This is the ground floor and foundation

pillars graph. It kind of made sense to

place them at the same general area.

And here's the full graph. We went

almost over all of it.

Here

are the full results of the building.

Here we randomize pretty much

everything. I added a random button that

kind of changes all of the variables.

Seed usually can change most of the

stuff, but I wanted to keep the floors

stable. For example, so if the user

wants three floors, he can still change

the seed, but keep the floors. This

boton kind of randomize everything.

Next is the city tool. We're going to go

over it much faster. This is also a

simpler tool than our building.

To create uh first create two assets,

one blueprint, one PCG, just like we

created for the buildings, but this time

for the city.

add some variables. Since we want to

vary the buildings within range, we're

going to use a minimum and maximum

scheme. So, let's say a minimum of one

floor and a maximum of 10 floors.

You see those vector 2D at the bottoms,

which is just two floats, two simple

numbers. We will use it for minimum and

maximum.

So, we're going to start with the same

node, read variables, create point grid,

and this time we are going to move the

points randomly and X and Y. We don't

want them to be a perfect grid.

This is the point grid before we moved

it. We're going to pretty much assign

attributes to each cube. Each cube will

be a building according to its will

spawn a building according to its size

and place.

We're going to randomize the X and Y

size of the buildings. We're copying the

size to scale to get an accurate debug

preview. And we now use the attribute

normalize graph again. It is back, but

this time we don't really normalize it

from the 0 to one. We normalize it to

what the user wants. Accord. So let's

say 0 to nine for the flows.

One issue with our approach is the

overlap here.

To solve that, we can use selfing which

I kind of love.

It removes uh sorry it removes kind of

overlap from everything. It's a really

valuable node.

Next, let's rotate each building by 90°

steps. We're going to use the floor

operation here and just do a few simple

maths to to sort of get it.

Here's our rotated non-over overlapping

buildings. In a full city, we can think

to sort of rotate the buildings toward

the road or do some more interesting

layouts.

We're going to randomize the possible

flows.

I wanted to mention that kind of

real-time feedback and quick iteration

speeds are really valuable.

Every environment can kind of enjoy this

flexibility even just as a blockout

tool.

Why use a cubes for buildings and

neighborhoods where can Well, we can

create a blockout tool. The artist

doesn't have to guess how many floors

the cube is or continuously measure it.

and then center it like on the ground.

So for the shrink strength range, we're

going to randomize this one, too. We're

going to shrink buildings a little bit

less less frequently um if they are

taller.

It kind of makes sense because we want

the taller buildings to not have many

many variations, but on smaller

buildings, we want many interesting

shapes.

This is the guy we're randomizing. How

much do we shrink?

For the props, we're going to use the

distance node. We will spawn less less

props if the buildings are kind of

closer to each other.

This is just a simple experiment, but

you can play with whatever logic you

find interesting.

For the roof pops, we will use regular

attribute noise, resulting in more

frequent coverage variations than the

special noise, which is kind of

consistent in space

for the doors. Nothing complicated here.

It's the same pattern, noise, and

normalize to range. We're just doing it

over and over again in the CD tool or in

many other tools, too.

We're going to alternate between our

wall types large to small that we

created and grammar that we're going to

create later.

So about grammar, as I said, it's

basically like patterns.

It can help us achieve interesting ones

such as alternating between modules or

specifying the start and end module and

end module.

We're going to move the city to the

actor centroidid. It's a really common

operation and we've done it with the

building earlier, but now just for the

city.

Next, we want to kind of determine the

height of each building.

We don't really want it to float, but we

don't want it to sink on uneven

terrains.

To solve that, we're going to convert

our building to one metal cubes at the

base.

We're going to shoot some rays toward

the bottom and then check what is the

highest point that kind of snaps to the

terrain.

Then we're going to copy the height of

the highest no highest cube marked in

red here for the rest of the building.

Convert the base of the building to 1 m

cubes. Once again,

rate to the landscape. Find the highest

cube and copy its height to our

unmodified building. This is the only

attribute we need from here.

And finally, we're going to actually

spawn the buildings. We will do that by

spawning the blueprint actors we created

for the buildings.

So the building blueprint contains a PCG

graph and we're now using like a

blueprint within and the PCG within it.

We're going to override the blueprint

variables and this is why we generated

all of those v variables earlier. It's

going to enable us full control as if we

placed those buildings manually and just

change some parameters.

This is really valuable because after we

generated many buildings, we can come

and just like change one specific

building.

And there's the city PCG graph compared

to our building. It's kind of light.

And there's the result. We move it

around and it adapts to height.

We are changing the seed and the size

and the different ranges we created such

as minimum and maximum flows or minimum

and maximum size.

Eventually, we generate the actual

buildings. I did add here like a preview

mode which is snappy and kind of shows

you how it's going to roughly look. We

can even make the preview preview mode

better by showing the shrinking presets.

So let's view the material setup.

Two simple material uh create two simple

materials. color, roughness, metallic,

the usual.

To alternate the secondary color of some

buildings, drop an actor position and

round node. It's going to generate a

0ero to one uh values for each actor,

which might sound familiar by now.

We're going to add a mask. So, where

would the first and second material be?

The trick here is to calculate the mask

at the default position of the model

before removing it or rotating it.

Expanding on this idea is kind of

interesting.

Blend the material using the mask we

created on the previous slide.

And now we want to kind of add color and

roughness variations to some assets. for

example, AC unit will be nice if some of

them were a bit more dirty or a bit

darker in this example.

So, similar to speed's color variation

node, but here we control the U

saturation and values individually.

The key nodes here will be per instance

random, which gets us a 0 to one value

per piece.

It's the same as the attribute noise we

used in the PCG graph, but this time

we're doing it in materials.

Use the remap node, which is like

attribute normalize, but we kind of

assume a 0ero to one inputs because we

don't actually measure the darkest and

the brightest pixel here.

And one more thing we can do is use RGB

to HSV node which is just just perfect

for variations.

Since we don't want to vary just the red

channel or the green channel, we want to

vary the U or the saturation.

This is the complete graph

and this is the material results. We're

changing parameters such as colors

and we can enable inter actor

variations. So one of those buildings

are gold uh tint and summer is blue or

red

and the per instance variations which

kind of screws the modules

but it's useful for AC units.

For the modules,

I really enjoy plasticity. It helped me

design a huge selection of models. It's

a modeling software using ns similar to

card and things like that. It's

intuitive to use and well designed. So,

if you like hard surface, I really

recommend you checking it out.

Here's a top view of the models. It took

several iterations to come up with the

dimension and kind of make sure

everything fits, but the process is

satisfying.

Here's a top view of the props. Each

cube grid is 1 m, so you kind of get a

scale for fence.

In your DNA, we use to name, UV, and

center the kit. We can also use the DNA

to visualize anomalies like pieces with

many polygons or pieces with holes.

Those are marked in red here. It's very

useful

for grammar.

Grammar, as I said, is a way to sort of

describe patterns. In this example,

we're going to use it for walls and

floors. It's available since 5.5.

Here's the graph.

We're going to start by converting a

cube to a spline. Each flow will have a

sort of base plan for it.

We're going to use the wall extraction

process we did earlier. Everything is

the same, but we just take the corners

and input them into a create spline

node.

So now we get a spline at the base of

each floor. We kind of do it because

grammar expects lines as input.

Starting with the vertical grammar

flows.

What kind of flow pattern do we want? Do

we want one first and one last floor

flow with many middle floors in between?

Or maybe we want one first floor and

then alternate between different assets.

Let's call them middle and last floors

for this example.

To the left, the grammar section was

taken from Epic's example. They have a

really great example in engine.

We force the direction of the spline and

convert the spline to points.

If the right side of the in the right

side of the graph, we will classify each

wall segment and apply different grammar

depending if it's the front, sides or

back.

For the horizontal grammar, it will be

for the walls. I prefer readable naming

over concise. So I chose wall 1 M1 which

is like the first module of the 1 m

dimension walls which is a bit more

accessible than what I usually see like

W1 or W1A. I think it's worth the extra

the extra letters.

Here we load the modules. We do that by

reading the same strat from earlier.

We're going to merge all of the possible

wall modules. We're going to allow scale

for some or all of the modules. Not

allowing scale will kind of fail the the

segmentation process, but the scale

should be really really minor if if your

pieces fit.

Extract mesh info is one more example by

Epic, which kind of finds the dimensions

of each module. Use that. It's really

nice.

This is the actual grammar segmentation.

It's the subdivide node to the left.

All of this the grammar se the grammar

section will be output into this sort of

yeah redirection node. Forgot it exact

name

to easily enable gunner toggle this

parameter. We're using an enum here.

Enums are great because we kind of get a

drop- down menus with selections that

are easy to understand for the users. We

could use a boolean here, but it won't

be as clear as selection, and we will

lose the option to include a few more

options if we want more than two.

The results are the ability to change

grammar in a bit more intuitive way,

either by clicking a button or editing

the strings.

We are now done by the with the project

setup. I wanted to show some idea of

what we can tackle next.

We can explore additional city elements,

roads, sidewalks, parks, and many more

things that I didn't include here.

We can improve the city layout. The city

here is the city layout is pretty basic

here.

We can create splinebased buildings,

ones that are not just square. Grammar

is already a huge help toward it and

geometry script can generate custom

sized roofs, floors, pipes, and more on

the fly.

PCGX is looking awesome. It's a plugin

that seems to address many of the needs

for complex city layout, having more

special nodes and things that can

measure if they are inside of each

other.

Interiors can be both challenging and

super interesting to tackle with PCG

and many more additional paths. Unreal

5.6 six features, interactive UI,

different styles, and combining it with

geo generation, pipes, and more.

Final thoughts.

PCG is not easy. It's sometimes simple,

but can easily get complex for certain

tasks.

A full complexity is a significant

challenge.

Geometry generation is currently basic

within PCG, but you can complement it

with geometry script.

Most spline vertex and face operations

could simplify the graphs and do certain

actions more easily like cubes to

splines.

PCG is super useful. Some buildings,

fences, biomes, and many tools are

totally viable now.

PCG can also be useful for level design

or gray boxing early in development

and it can also be used in the later

stages to scatter points on the

landscape or any mesh that we want

filter them and then spawn meshes

accordingly such as vegetation extra

rocks everything

is also stable it's fast and many

feature I kind of expected to have were

there a lot of nodes

It supports importing and editing point

clouds. So using an amic we can make it

much more useful basically deciding what

do we want to spawn. We can take the

point cloud and spawn additional points

around it.

And one more point that I wanted to say

is that anybody can sell those tools in

a huge marketplace which makes it a lot

more relevant now.

In the future, I hope Epics Epic keeps

developing PCG. Some things I would be

happy to see are animation or in general

just the ability to simulate and animate

anything using PCG. Maybe even author

blueprint or move characters using it.

One more thing is smaller graph. I want

less nodes. So let's say inline

constants are coming 5.6. six which will

make the graph significantly smaller. It

is nice.

Highle nodes such as selfining or just a

fence or building nodes will be great

because one of the workflows we can do

is to take those highle nodes, break

them down and change them a little bit

and get another tool al together

and advanced tutorials. It will help us

explore and learn what's possible.

We're done.

feel free to ask.

Thank you so much.

Thank you so so much. Feel free to ask

me questions either now or later. I will

be here and in the dev launch.

>> Um so what what would be your approach

to add more directability in the tools?

Like say the art director wants like I

don't want this building here or the

upper floor is too tall on this one or

the prop on that generated on the corner

like like being you generate everything

but still have access to like the

certain layers to prune and direct.

Right. So this is a really really cool

feature of PCG. Once we spawn those

building octals we can just click on one

of them and change all of the parameters

as if we just placed it manually. So we

can change the flows, we can change its

um its location or size without

regenerating the whole city. So this is

one approach we would go and using

splines and things like that to even

have more directability.

Um Paul if this was covered I came in

later but uh was there any actual engine

code changes involved or was this

completely it's one 100% PCG. Um Mudini

was used to just import the modules and

sort of pack them into an FBX. It was

easy because when I kind of change the

modules it automatically like picks

them, center them and export it as just

one file so I can reimpport in Unreal.

Got it. And also another question is um

was this uh is this being used with

world partition or like without because

we have tried using uh PCGS on our side

and the moment you get involved with

level instances and other things things

might go wrong at least it did for us.

>> I see yeah I didn't explore world

partition um I didn't check performance

a lot but I saw that it ran very very

quickly. So, let's say still capped at

120 fps for full HD. So, for now, I

didn't touch it, but yeah, it's

definitely something we should explore.

Thank you. Thank you.

Loading...

Loading video analysis...