WEBVTT

00:00.000 --> 00:03.799
Blender 3.6 has been released, and it's including a flashy

00:03.800 --> 00:06.280
new feature that will probably get some heads turning.

00:06.980 --> 00:07.980
Simulation nodes.

00:08.500 --> 00:12.540
Yes, simulation has come to geometry nodes, and in this video I will give you

00:12.541 --> 00:14.675
an overview of what to expect from the new

00:14.676 --> 00:17.060
system and how you can get started using it.

00:17.680 --> 00:20.280
There is one thing I want to make clear from the beginning though.

00:20.640 --> 00:23.675
With Blender 3.6, nothing changes in terms

00:23.676 --> 00:26.900
of how physics simulations are done for now.

00:26.901 --> 00:32.180
Rather than taking all of Blender's existing physics simulation systems and

00:32.181 --> 00:35.352
plugging them into nodes, the new feature does

00:35.353 --> 00:38.940
something much simpler, but also much more powerful.

00:39.600 --> 00:43.780
The approach is to build on the vast capabilities that geometry nodes already

00:43.781 --> 00:49.880
have, and add basic functionality to turn all of that into custom simulation systems.

00:49.881 --> 00:56.340
That way, we make sure to build a solid foundation that power users can benefit

00:56.341 --> 01:00.580
from immensely already, and add more high -level features on top of that,

01:01.200 --> 01:07.020
that any artist can use easily later on, in a way that supports and strengthens the

01:07.021 --> 01:09.680
entire ecosystem of geometry nodes in Blender.

01:10.360 --> 01:14.420
So yes, right now I should give the disclaimer that you do need some solid

01:14.421 --> 01:18.280
experience using geometry nodes to benefit from the new feature.

01:18.281 --> 01:21.943
Easier-to-use, one-click solutions using the

01:21.944 --> 01:25.741
new system will follow in future releases.

01:26.100 --> 01:28.610
But hopefully I can give you an idea how this

01:28.611 --> 01:31.400
approach scales up to virtually infinite potential.

01:32.260 --> 01:37.300
That said, the added feature set is, for now, intentionally capped,

01:37.620 --> 01:41.345
relatively compact, and simple to scale it up alongside

01:41.346 --> 01:45.200
other necessary improvements in Blender in future versions.

01:45.201 --> 01:48.850
And there are some obvious current limitations, like

01:48.851 --> 01:52.200
losing the material assignment, that aren't supported yet.

01:52.720 --> 01:57.340
This is just the first major milestone for simulation in geometry nodes.

01:58.040 --> 02:02.365
But let's take a step back and look at what's actually been added in Blender 3.

02:02.366 --> 02:03.680
6 for simulation nodes.

02:04.500 --> 02:07.235
The new elements in the user interface that hint

02:07.236 --> 02:09.780
at the new simulation system are relatively subtle.

02:09.781 --> 02:13.516
In terms of nodes, there's really just a single new entry in

02:13.517 --> 02:17.720
the add menu to make simulation possible, the simulation zone.

02:18.400 --> 02:22.500
When you add it to the node tree, it creates two nodes that are already

02:22.501 --> 02:26.557
connected with a geometry link and this plum-colored panel

02:26.558 --> 02:29.660
that changes automatically when you move them around.

02:30.920 --> 02:34.578
This panel describes the so-called simulation zone and

02:34.579 --> 02:37.300
it indicates which nodes are part of the simulation.

02:37.301 --> 02:42.220
When I insert the simulation nodes in here, nothing changes at first,

02:42.500 --> 02:46.060
because we are just passing through the geometry without doing anything.

02:46.700 --> 02:53.020
Let's just add an extrude node to make a visible change and use a random value node

02:53.021 --> 02:56.040
for a random selection of faces to extrude.

02:56.840 --> 03:01.980
You can see how the simulation zone adapts its shape to include the extrude node.

03:02.740 --> 03:06.680
The random value node, however, is not part of the simulation itself

03:06.681 --> 03:10.780
because it only provides a field that is used by the extrude node.

03:11.620 --> 03:14.014
The actual data that is part of the simulation

03:14.015 --> 03:16.581
is only passed around between these nodes here.

03:17.240 --> 03:19.480
But so far, there is no simulation yet.

03:20.280 --> 03:24.280
But when I go to the next frame, you can see how this extrusion is done

03:24.281 --> 03:27.480
again, and again, and again, the more frames I progress.

03:27.481 --> 03:33.460
The reason for that is that for each frame that I continue, the result of that

03:33.461 --> 03:38.660
previous frame is passed into its input, creating a sort of loop behavior.

03:39.240 --> 03:43.780
Each individual step of the operation is also called a simulation step.

03:44.260 --> 03:48.940
Okay, great, but I want to have a different random selection for each frame.

03:50.320 --> 03:53.599
So let's go to the random value node and plug

03:53.600 --> 03:56.860
in the frame of the scene into the seed input.

03:56.861 --> 04:00.711
And now when I continue frame by frame, you can see how a

04:00.712 --> 04:03.680
different selection is used for the extrusion on each step.

04:04.240 --> 04:09.120
But the result that we had earlier from the setup, using the same seed for every

04:09.121 --> 04:11.660
frame, is still influencing what we see here.

04:12.220 --> 04:15.620
The reason for that is that the simulation just takes whatever it gets from the

04:15.621 --> 04:17.980
previous frame, no matter what you changed.

04:18.360 --> 04:21.373
So to reset the state of the simulation to its

04:21.374 --> 04:24.140
initial state, we need to go to the first frame.

04:24.141 --> 04:26.923
And now if I play back the simulation, you

04:26.924 --> 04:30.421
can see how this works properly as expected.

04:31.260 --> 04:35.220
We get a different selection for the extrusion on every single frame.

04:35.520 --> 04:40.760
You can also see how in the timeline, playing back builds up this purple bar.

04:41.560 --> 04:44.292
And this bar is representing that the frames

04:44.293 --> 04:46.600
of the simulation are written to the cache.

04:46.601 --> 04:51.680
That means I can always go back in the timeline and get any state of the

04:51.681 --> 04:54.360
simulation without having to calculate it again.

04:55.060 --> 04:58.420
But this is only the case as long as the cache is valid.

04:58.840 --> 05:03.300
If I make any change in the node tree that affects the simulation, the color of this

05:03.301 --> 05:07.164
bar gets slightly more faded, indicating that the cache has

05:07.165 --> 05:10.100
become invalid and the simulation needs to be run again.

05:10.101 --> 05:14.380
But of course, if you want to, you can also just change the values in

05:14.381 --> 05:16.840
real time to affect the simulation that way.

05:18.220 --> 05:21.780
A more permanent way of storing the cache is to bake the simulation.

05:22.300 --> 05:27.000
That can be done in the physics properties tab under the new simulation nodes panel.

05:27.680 --> 05:32.680
This will bake the simulation data for the entirety of the scene frame range and

05:32.681 --> 05:35.460
store it on disk in a folder next to the blend file.

05:35.461 --> 05:40.500
You can also see and change that path here in the modifier panel.

05:41.780 --> 05:45.580
Now that the simulation is baked, you can see how the playback is super

05:45.581 --> 05:48.708
smooth, and when I change values, this will not

05:48.709 --> 05:51.440
actually invalidate the cache automatically anymore.

05:52.500 --> 05:55.511
So in this case, if you want to free it again, you

05:55.512 --> 05:58.680
need to do that explicitly by deleting the cache data.

05:59.500 --> 06:03.520
Let's go over another example, to go a bit more into detail, where I show

06:03.521 --> 06:09.621
you how to build a relatively basic particle simulation setup using simulation nodes.

06:09.780 --> 06:14.220
Note, by the way, how what I've shown so far isn't exactly a physics simulation.

06:15.000 --> 06:18.957
The use cases for simulation nodes really go much further

06:18.958 --> 06:22.220
than what we classically have as a simulation and blender.

06:22.221 --> 06:25.458
First off, let's just create a whole bunch of points,

06:25.459 --> 06:28.640
and for that I use the Distribute Points on Faces node.

06:29.580 --> 06:32.348
With that, we can just create a bunch of points

06:32.349 --> 06:35.861
on the input geometry from the base mesh.

06:36.000 --> 06:39.040
At these points, we then feed into the simulation.

06:39.980 --> 06:42.908
Inside of the simulation zone, the main feature of

06:42.909 --> 06:46.000
the simulation is going to just be moving the points.

06:46.160 --> 06:48.480
For that, we'll use the Set Position node.

06:48.481 --> 06:52.680
Let's just give that a go with just some random offset vector.

06:54.240 --> 06:56.310
And yeah, obviously right now this is not very

06:56.311 --> 06:59.120
interesting, but this is going to be the main concept.

06:59.920 --> 07:01.800
Just moving points in a certain direction.

07:02.520 --> 07:05.004
And to keep track of the direction and speed of

07:05.005 --> 07:08.040
that movement, we're going to add a Velocity.

07:08.620 --> 07:12.340
The Velocity is just going to be a vector attribute on the points.

07:12.720 --> 07:15.480
This attribute is also going to be part of the simulation.

07:15.481 --> 07:20.580
So the way to add this is to just click on either the simulation in or output.

07:21.080 --> 07:23.910
And then here in the sidebar, you can see that

07:23.911 --> 07:27.081
there is a simulation state panel that is new.

07:27.180 --> 07:33.420
And when I add another entry, this one pops up both from the input and the output.

07:33.980 --> 07:38.340
This is necessary because for the simulation step, everything that goes into

07:38.341 --> 07:41.096
the simulation output needs to pop up back

07:41.097 --> 07:43.840
out of the simulation input in the next frame.

07:43.841 --> 07:46.840
And then here for the socket type, I can just

07:46.841 --> 07:49.841
select a vector and call this one Velocity.

07:50.960 --> 07:53.680
Now there's two things that I want to do with the Velocity.

07:54.120 --> 07:57.310
First off, I want to keep it around for the next frame,

07:57.311 --> 08:00.720
so I'll pass it right from the input to the output.

08:01.340 --> 08:04.360
And then I want to use that Velocity to move the points.

08:04.840 --> 08:09.460
To make this independent of the frame rate, let's use a scale node and scale

08:09.461 --> 08:12.480
that with the time that has passed since the previous frame.

08:12.481 --> 08:17.020
And then connect that into the offset of the Set Position node.

08:17.500 --> 08:21.680
Now I can just set the initial Velocity for all the points in here.

08:22.160 --> 08:28.040
Let's say one unit per second in the X direction, and play it back like this.

08:28.580 --> 08:30.860
But so far, nothing interesting is happening.

08:31.980 --> 08:36.440
So let's make some changes to that Velocity, instead of just passing it through.

08:37.120 --> 08:39.360
Let's just add a force like Gravity.

08:40.220 --> 08:43.319
And the easiest way to do that is just use a Vector

08:43.320 --> 08:46.401
Input node, which will represent the Gravity.

08:46.780 --> 08:50.860
And then we can use that to modify the Velocity Vector for each frame.

08:51.320 --> 08:55.980
Again, to make this independent of the frame rate, I'll use a scale node.

08:57.320 --> 08:59.320
Scale that with the Delta Time.

09:00.440 --> 09:03.780
And then just simply add this to the Velocity.

09:05.420 --> 09:08.466
That way we have a change in the Velocity on

09:08.467 --> 09:12.501
each frame that is represented by this force.

09:12.820 --> 09:17.249
And if I replace this in the Simulation Output, you

09:17.250 --> 09:20.421
can see that this affects how the points are moving.

09:21.700 --> 09:25.720
So let's set this to something that kind of makes sense, in terms of Gravity.

09:28.020 --> 09:29.980
And that kind of looks right.

09:31.920 --> 09:36.480
Let's give this some Velocity in the Z direction as well.

09:37.980 --> 09:38.980
And there we go.

09:39.320 --> 09:43.260
So with a pretty small amount of nodes, we have a very, very basic setup already.

09:43.920 --> 09:45.840
So let's take this a few steps further.

09:46.820 --> 09:51.100
First off, I want to get a Random Initial Velocity for each point.

09:52.420 --> 09:55.400
So for that, I'll just use a Random Value node.

09:57.680 --> 10:00.260
Going into totally random directions.

10:03.320 --> 10:04.580
And then it looks like this.

10:05.480 --> 10:09.440
Another thing is I want to continuously add more points to the simulation.

10:10.960 --> 10:15.640
Right now we only get the initial state of the points through the simulation input.

10:16.380 --> 10:21.040
But this node is not the only way to pass in data into the simulation zone.

10:21.041 --> 10:26.100
Instead, you can also just pass it in directly, like this.

10:26.420 --> 10:28.500
I'll just create a Join Geometry node.

10:29.520 --> 10:35.421
And then join that together with the points that we get from the previous frame.

10:36.340 --> 10:41.960
And that way, we add a new set of points every single frame.

10:42.500 --> 10:46.720
Again, this data is just what we get from the previous frame.

10:46.721 --> 10:50.320
Or on the first frame, from the initial step.

10:51.120 --> 10:57.740
And then the data that we pass in directly is calculated for each individual frame.

10:58.300 --> 11:02.303
So if I play this back, you can see how we get a new

11:02.304 --> 11:05.500
set of points joined together every single frame.

11:06.080 --> 11:08.780
But the set of points is always the exact same.

11:09.120 --> 11:11.420
So let's change up the seed for every frame.

11:11.421 --> 11:15.960
That way we get a random distribution every time.

11:17.360 --> 11:21.041
But you can see that only the first initial

11:21.042 --> 11:24.581
points get a random velocity in the beginning.

11:25.440 --> 11:28.560
The other points just start out with a velocity of zero.

11:29.400 --> 11:33.502
The reason for that is that we only pass in the random

11:33.503 --> 11:37.880
value to the initial points in the simulation input.

11:38.680 --> 11:41.640
With the other points are joined into that

11:41.641 --> 11:44.280
same geometry, they don't have that attribute.

11:44.820 --> 11:48.660
So what we need to do is add a capture attribute node.

11:49.080 --> 11:50.360
Set this to vector.

11:50.960 --> 11:56.020
And then in here, capture this field as an attribute.

11:57.480 --> 12:00.860
And then add it together with the velocity of the other points.

12:03.580 --> 12:08.403
That way we combine the velocity attribute of the existing

12:08.404 --> 12:11.960
points with the new captured attribute of the new ones.

12:13.700 --> 12:14.960
And there we go.

12:17.060 --> 12:19.500
But let's make this simulation a bit more interesting.

12:20.340 --> 12:24.440
Right now we only have some initial conditions for the velocity.

12:24.441 --> 12:30.620
And then a single constant force acting on the particles to change that velocity.

12:31.240 --> 12:35.760
Let's add some simple turbulence to them by adding a noise texture node.

12:37.620 --> 12:39.860
Let's connect the viewer to take a look at that.

12:40.420 --> 12:43.540
And right now the noise texture gives values from zero to one.

12:43.840 --> 12:45.660
But we want to center that around zero.

12:46.580 --> 12:49.940
So let's use a map range node.

12:52.240 --> 12:53.240
Turn off the clamp.

12:53.241 --> 12:57.060
And put the from min to 0.5.

12:57.940 --> 13:00.960
And that way we get nice values centered around zero.

13:01.880 --> 13:04.880
Let's connect the two max to a value node.

13:06.640 --> 13:09.540
And then we can control the strength of this field.

13:10.040 --> 13:14.880
Now we can simply add this to the existing gravity force that we created before.

13:17.760 --> 13:20.340
And there we have some turbulence in our simulation.

13:21.100 --> 13:24.280
Change up the scale to make that a bit more clear.

13:27.060 --> 13:28.740
And crank up the strength.

13:30.220 --> 13:32.240
Now that's a bit more interesting already.

13:36.250 --> 13:40.010
Another thing I want to do is keep track of each particle's lifetime.

13:40.910 --> 13:44.370
Another thing I want to do is keep track of each particle's lifetime.

13:45.330 --> 13:49.990
So on top of the existing data that we're keeping track of in the simulation already.

13:49.991 --> 13:55.350
I'm going to also add another attribute called the age.

13:56.770 --> 13:59.970
Which is just going to be an integer to count up the frames.

14:01.370 --> 14:07.370
In the simulation we're simply going to add one to the age for each frame.

14:09.050 --> 14:13.110
But now by default we have a bit of a problem that's not super obvious at first.

14:13.111 --> 14:17.451
But this little dot inside of the diamond shape indicates

14:17.452 --> 14:20.810
that we have a single value for each of the particles.

14:22.370 --> 14:25.790
It's not actually an attribute, it's just a single value.

14:26.830 --> 14:29.650
That is another feature of simulation nodes.

14:30.150 --> 14:34.770
You don't necessarily need to operate on your geometry data with attributes.

14:35.290 --> 14:38.930
You can also just simulate individual values.

14:38.931 --> 14:45.350
So right now there's no way for the system to know that the age is supposed to be an

14:45.351 --> 14:49.090
attribute that is different for each point on this geometry.

14:49.730 --> 14:53.490
There's nothing that ties the age to the geometry right now.

14:53.770 --> 14:58.410
So to make sure that this happens we need to use another capture attribute node.

15:02.070 --> 15:04.830
And then pass the age through that.

15:06.070 --> 15:07.990
And now you can see that the dot appeared.

15:07.991 --> 15:13.210
And now you can see that the dot disappeared because now this is actually

15:13.211 --> 15:16.050
an attribute on the geometry in the simulation.

15:16.950 --> 15:19.974
We can keep track of the age for example by connecting

15:19.975 --> 15:22.830
the viewer and then looking at the spreadsheet editor.

15:24.390 --> 15:28.470
So the points that exist from the very beginning just count up more and more.

15:29.250 --> 15:32.553
But if I scroll down a bit you can see that the last points

15:32.554 --> 15:36.610
that are just newly created just have a single age of one.

15:36.611 --> 15:40.714
Now this age parameter we could for example use

15:40.715 --> 15:44.110
inside of a shader to create all sorts of effects.

15:44.390 --> 15:50.170
Like changing the color over the lifetime of a particle or inside of the simulation.

15:51.130 --> 15:53.452
For example to just delete some of the points

15:53.453 --> 15:56.411
when they reach the end of their lifetime.

15:56.490 --> 16:05.270
So let's create a delete geometry node and plug it in here to delete every point

16:05.271 --> 16:11.410
where the age is greater than let's say 20.

16:13.090 --> 16:16.370
So the particles stay alive for only 20 frames.

16:17.550 --> 16:19.330
And then they disappear.

16:20.610 --> 16:24.130
Now let's actually do something outside of the simulation itself.

16:24.131 --> 16:29.690
I want to make use of the velocity that we get for each particle.

16:30.810 --> 16:36.210
Now something that is important to note is that you should never use the velocity

16:36.211 --> 16:41.930
right out of the simulation zone itself to pass it out to some other node outside.

16:42.810 --> 16:46.139
Every connection that you make from inside a simulation

16:46.140 --> 16:49.670
zone to the outside will still be part of that simulation.

16:49.671 --> 16:54.533
So if you want to get data out of the simulation, the

16:54.534 --> 16:59.010
only way is through the simulation output such as this.

16:59.210 --> 17:02.150
Note that this is different for the other way around.

17:02.390 --> 17:08.850
As I shown before, you can pass in data from outside of the simulation zone just

17:08.851 --> 17:11.990
like this, but out only through the output.

17:12.730 --> 17:17.550
Let's use the length of the velocity vector to get the speed.

17:17.551 --> 17:26.130
Use a map range node to map it to a smaller range that we can visualize like this.

17:26.490 --> 17:29.510
But let's use a color ramp for a better visualization.

17:30.550 --> 17:33.910
Let's just change the colors to something like this.

17:35.750 --> 17:37.090
And there we go.

17:39.950 --> 17:44.050
Let's crank up this density by the way to get a lot more points.

17:44.950 --> 17:50.030
Because this is a very simple simulation still, the performance is still quite good.

17:50.430 --> 17:56.630
Now, because we are piping through the actual group input geometry into the

17:56.631 --> 17:59.153
simulation zone directly like this, we also

17:59.154 --> 18:03.050
have direct real time influence with the mesh.

18:03.950 --> 18:09.410
So if I just play the simulation and go into edit mode, you can see that I can

18:09.411 --> 18:13.270
change the mesh and see the updates in real time.

18:14.010 --> 18:22.030
So you can interact with the inputs like the mesh itself or all of the parameters

18:22.031 --> 18:26.670
that we are using in the setup in real time to affect how it behaves.

18:29.750 --> 18:31.630
Just as you would expect from a simulation.

18:32.870 --> 18:37.210
Let's add one more element to this simulation for some more interactivity.

18:37.211 --> 18:43.150
I want to add a separate force that is controlled with an empty object.

18:43.590 --> 18:49.450
For that I'll just drag the empty into the node editor to get an object info node.

18:50.010 --> 18:53.230
I'll set this to relative to get the relative location.

18:53.810 --> 18:57.672
And then do just a little bit of vector math to get

18:57.673 --> 19:01.290
a force that draws the particles towards this empty.

19:02.330 --> 19:09.891
Let's take the location of the empty and then subtract the position of the particles.

19:12.270 --> 19:18.730
Now this vector, let's just normalize it and also get its length.

19:20.890 --> 19:25.090
And I want it to be stronger the closer the particles are to the empty.

19:25.091 --> 19:30.877
So I'll use a divide node and divide one by the

19:30.878 --> 19:35.690
distance and use that to scale the direction vector.

19:37.530 --> 19:42.430
Then just another scale so that we get more control over the strength.

19:43.450 --> 19:46.570
And let's add this to the existing forces.

19:48.570 --> 19:54.890
Let's mute this link holding down control and alt, right click drag to get rid of

19:54.891 --> 19:58.790
the original forces so we can see better what this does.

20:00.610 --> 20:03.450
Right now it doesn't do much because it isn't strong enough.

20:03.850 --> 20:05.750
So let's turn that up.

20:07.430 --> 20:11.470
And now you can see how the particles are drawn to the empty.

20:14.960 --> 20:16.660
Let's crank that up even higher.

20:16.661 --> 20:22.780
Now we got a really strong effect like this.

20:24.060 --> 20:27.020
Let's turn these initial forces back up for the full picture.

20:27.940 --> 20:28.940
And there we go.

20:29.040 --> 20:33.340
This is our final basic custom particle simulation setup.

20:35.080 --> 20:38.288
Of course, this is just one of the infinite use

20:38.289 --> 20:41.201
cases of what you can do with simulation nodes.

20:42.040 --> 20:46.028
But I hope this gave you a bit of a solid idea of what

20:46.029 --> 20:49.140
things you can do with it and how to work with them.

20:50.100 --> 20:53.480
In case you do feel like some of the things in this video went a little bit

20:53.481 --> 20:57.600
over your head, I can recommend you to check out the Geometry Nodes from Scratch

20:57.601 --> 20:59.900
course that we have on the Blender Studio platform.

21:00.680 --> 21:04.160
In this course I go over everything that you need to know to understand how

21:04.161 --> 21:06.120
geometry nodes work and how to work with them.

21:06.740 --> 21:07.820
But that's it from me.

21:08.040 --> 21:10.040
Have a great rest of your day and goodbye.
