Introduction to Geometry Nodes in Blender 2.92 - Tutorial 2 of 2
The 3D assets used in this tutorial:
This is the second of two introductory tutorials on the Geometry Nodes modifier in Blender 2.92.
In the previous tutorial we examined the nodes of the Geometry group (ie Transform and Join, to modify and merge the geometries within the modifier); the ability to create input sockets for Group Input in order to specify parameters in the modifier tab, and the use of some Vector and Utilities nodes (Math, in particular) to perform mathematical operations and combine information.
In this tutorial we will see a different use of Geometry Nodes, as we will use them as particle systems for the "scattering", that is, the distribution of instances of objects on the surface of others; however, all the topics covered in the first tutorial of this mini-series will come in handy here.
The Geometry Nodes modifier allows us to transform the geometry of the object that uses it into a generator of points, which will be distributed on its surface (that is: on its faces).
These points can be used to arrange, in their correspondence, instances of other objects; furthermore, the Geometry Nodes also allows us to assign transformations (position, rotation and resizing) to each of these points, so as to introduce randomness.
In listing these operations, I said three things in particular:
- transform the geometry into a set of points DISTRIBUTED on the surface;
- INSTANCING of the objects in those points;
- modify the characteristics (ie: the ATTRIBUTES) of the points generated and thus influence the instances created.
These three operations translate into as many Geometry Nodes, which we see immediately.
In the scene visible on the screen there is a very simple default Plane (therefore made by just 4 vertices and one face); moreover, using APPEND I imported the 3D models of some pebbles (the “Pebbles”), of a stone (“Stone 1”) and of an object containing blades of grass.
For convenience, I'm grouping the pebbles into a Collection and hiding all these accessory elements, turning them off in an Outliner editor.
As in the case of the watch in the previous tutorial, it is NOT necessary to get these models to follow the tutorial and learn!
I select the Plane and add a Geometry Nodes modifier to the object.
To carry out the first operation, that is to transform the plane into a set of DISTRIBUTED points on its surface, I add a Point DISTRIBUTE node in the middle of the group.
On screen we can see that the Plane has disappeared, replaced by a set of points ... well, in reality that starting information has not been lost, indeed it is still there: the non-destructive way of modeling of Geometry Nodes allows us to add a Geometry Join node between Point Distribute and Group Output and to connect, to one of the two Join inputs, the geometry arriving from Geometry Input (ie: the original Plane).
In this way we have both the original Plane (which we can modify and texturize, for example to give it the appearance of a terrain), and the points distributed on its surface.
The Point Distribute node provides some parameters, among which Density stands out, which allows us to intuitively increase or decrease the amount of points to be distributed on the surface.
In the previous tutorial we saw how to connect a node information to Group Input, so as to be able to modify the values in the modifier interface; it may make sense to do this for the Point Distribute Density parameter.
We then move on to the second operation of the three listed above, that is to INSTANCE another object (or a Collection of objects), placing a copy for each point created by Point Distribute: we then insert a Point INSTANCE node between Point Distribute and Join.
The meaning of the operation is clear: Distribute generates the points and Instance takes the information from these points to create copies of another object ... yes, but which object?
In the Point Instance node there is a selector that allows us to define whether we want to instantiate a single prop or a Collection of objects; the mode choosen (Object, in my case), we can click on the empty box located inside the node and choose the object that interests us (“Stone 1”, in my case).
IMPORTANT NOTE: for a correct result, make sure you have applied the Rotation and Scale transformations of the objects you want to instantiate; you can do this by selecting them and pressing CTRL A, then choosing “Rotation and Scale” from the Apply menu that will appear on screen.
We then adjust the Density parameter of Point Distribute, as desired, until we reach a result that suits us.
The third fundamental operation to do is to modify the parameters of the various points (and, therefore, of the instances generated); actually, it is possible to perform different types of operations, so we are not talking about a single node but the nodes of the Point and Attribute groups.
In both cases, the transformation nodes will be inserted between Point Distribute and Point Instance, because they will have to modify the POINTS created, BEFORE generating the instances from those points.
For example, let's start with the rotation, to be applied to all points: we then add a Point Rotate node between Point Distribute and Point Instance and modify the rotation angles of the particles.
The result is already better than that obtained without this node, but how to introduce randomness to the rotation and, why not, also to the size of these instances?
We are helped by the Attribute Randomize node (from "Random", of course), which we can cascade between Point Rotate and Point Instance (in fact this processing flow always takes place on the geometries, as it is possible to verify by observing the linked Geometry sockets between the various nodes).
Attribute Randomize is a node that allows us to introduce randomness on an ATTRIBUTE of the points, to be specified precisely in the "Attribute" field of the node.
Among the fundamental attributes of a particle we have, needless to say, "rotation" and "scale", so let's start by writing "rotation" in this field and modify the Max value …
The node actually introduces randomness in the orientation of the particles, but these rotate around all their axes, which is not exactly an interesting result: we would like to keep the base orientation given by Point Rotate and rotate the instances randomly only around the vertical axis.
To solve this problem, we need to change the type of operation value from Float (which is a numerical value with comma acting uniformly on the three XYZ axes) to Vector, where we can put 0 for all values except for the MAX of the axis that we are interested in modifying …
But even this operation brings with it a problem: we have lost the rotation given by Point Rotate!
It is a problem of priority, in a certain sense: between Point Distribute and Point Instance, in fact, we must first put Attribute Randomize and then Point Rotate.
Now duplicate Attribute Randomize and add it between the original and Point Rotate to also modify the Scale parameter (to be written, just like rotation, entirely in lowercase, otherwise Blender will not recognize it).
In this case, however, we will have to modify all the parameters min and max XYZ, to obtain interesting results (and perhaps avoid putting 0 for the minimum values, otherwise the objects will lose one or more dimensions).
Regarding the Scale attribute, you may find it more convenient to go back to the Float type, so that you use only one parameter for the minimum scale factor and only one for the maximum ... the choice is yours.
With just these two Attribute nodes, however, we are obtaining a certain diversity from an object which was made up of a single geometry: Stone 1.
If we change the type of object to instantiate in Point Instance from Object to Collection and specify the collection of pebbles, things become much more interesting!
Let's set Object again with Stone 1 in Point Instance, however, to examine another functionality available with Geometry Nodes.
In classical particle systems we can also define on which parts of the geometry to create the particles and on which not; it is done, in particular, with Weight Painting, by defining density values (from 0 to 1) on the various parts of a surface ... well, we can do it here too!
Before proceeding, however, we must increase the number of subdivisions of the Plane, because the Weight Painting (to be operated outside the Geometry Node, on the original geometry) acts on the vertices, so the 4 basic vertices of the Plane are not sufficient.
In a 3D view, then, we go into Edit Mode and subdivide the entire surface a good number of times; then let's switch to Weight Paint mode.
By default, the surface should appear blue, ie “weight 0”; the Point Distribute node will create the points on the areas with weight 1, so we have to paint in the areas on which we want to make the instances appear.
NOTE: if you want to apply the instances everywhere except in particular places, you have to proceed in reverse; in this case, in particular, we use the brush in the areas that we want to EXCLUDE from Point Distribute (and Blender will automatically create a Vertex Group, which should have “Group” as the default name, but we can also rename it to something more significant, such as "Pebbles").
At the end of the operation, open the Weights menu in the 3D window and click on “Invert”, to invert the weights: now, the area we painted will have weight 0, while in the rest of the geometry we will have weight 1.
Obviously, nothing prevents us from modifying the weights at a later time, by varying the value of the Weight parameter in the Tool tab in Weight Paint mode and brushing the surface; we just have to remember that we will NOT insert instances in 0-weighted areas.
In the Geometry Nodes editor, we type the name of the Vertex Group in the Density field of the Point Distribute node ("Pebbles", in our case; pay attention to upper and lower case): the distribution of the points on the original surface will be proportional to the Vertex Weights set by us.
Before concluding this tutorial and therefore the INTRODUCTION to Geometry Nodes mini-series in Blender 2.92, let's see a further example of object instantiation ... but with one more change.
Within the scheme we have defined, we insert a new Point Density node, connecting it to the Geometry socket of Group Input, then let's connect it to a new (empty) Point Instance and connect the two Point Instances available in the scene to a new Join Geometry node, which in turn will be linked to the Join node already available in the scene; in practice, the resulting geometry will be given by the original one joined to the one arriving by two Instance nodes.
In the new Distribute node we set the same Density attribute of “Stone 1”, but in Point Instance we set the High Grass module object as the one to be instantiated.
If necessary, we can insert a Point Rotate node to correctly orient the blades of grass.
Let's also insert a Point Scale node (between Point Rotate and Point Instance), setting in particular the Vector mode, so that we can specify the scale factor of the grass size with a vector.
Let's insert a Combine XYZ node and connect its Vector output to the Factor (vector) input of Point Scale; the blades of grass will disappear, because the Combine XYZ parameters will have a default value of 0.0, so we return XY to 1.0 (or, in any case, to an adequate value for these dimensions).
We then connect the Z input of Combine XYZ to a new Geometry Input port; as you may have guessed, the intention is to adjust the height of the blades of grass in the modifier interface ... but why limit ourselves to a constant value or having to manually change this value?
Let's add a Timeline editor to the Blender window and set a frame range for an animation, for example 240 frames.
Let's go to frame 1, then set 0.0 for the Z parameter (which we can rename at will, as seen in the previous episode with the names of the clock hands); then right-click on the value of this parameter and choose “Insert Keyframe” to record an animation keyframe, in fact.
Let's move to frame 240 of the animation, change the value of Z as desired and insert a keyframe for this parameter at the last frame of our animation too.
We just have to press Play in the Timeline and watch the result of our animation.
Well, that's all for this tutorial too! See you soon!