Main

Procedural Balloons Animation using Blender 4.0+ and Geometry Nodes

Procedural Balloons Animation using Blender 4.0+ and Geometry Nodes 💾 Download project files for all video tutorials: https://docs.google.com/spreadsheets/d/1XpNJ7Al-t53uABys9pB5OU78IzTU9g9ymtC7dtw699k/edit?usp=sharing Boosty: https://boosty.to/cubedel Gumroad: https://cubedeletion.gumroad.com/

Cube Deletion Society

1 day ago

Balloons take off and bounce off the ceiling. I’ll show you such a not very complicated setup in geometry nodes in this video. You will need Blender 4.0 or later. First, I'll create the ball itself using polygonal modeling and Node-Based Tools modeling tools. These are the same geonodes that were used exclusively as modifiers before version 4, but from version 4 you can use them to create your own tools for editing the mesh or hair guides. This is an object type called Curves. Don't confuse them
with a regular curve. After creating the model, I will add the usual geonode modifier, with which I will customize the animation of one ball taking off, and show how to animate several balls, for this you need to add a little variety and natural wobble and rotation. And then all that remains is to solve the problem of rotating balls intersecting with the ceiling using cycles or a Repeat Zone. And at the end of the video I will show you how to set up these materials. You can also download the pr
oject file. Link below the video. The node tree for this animation is built without simulation nodes, it is just an approximate imitation. This approach is good because there is no need to recalculate and bake the simulation. But only the balls will not be able to collide with each other and compress when colliding with the ceiling. Simulation is the calculation of values ​​in each frame. It always contains a solver - an algorithm responsible for calculating the interaction of geometry. Typicall
y, the solver calculates the change in position based on the previous frame and the next one after the current one , taking into account the changed geometry. This approach is good for computing physics simulations such as fluid, particle, or fabric simulations. But I won't use simulation. My task is to make the most believable imitation of the movement of balloons. Collision with the ceiling, bounces and vibrations in the air flow will not be real. To begin with, I create a sphere using the UV-
Sphere primitive, setting the radius close to the real size. Remember the radius, you will need it right away. The number of segments can be set at your discretion; it is better to increase the detail a little. In edit mode, I select everything and lower the geometry to the radius value. This is necessary so that the center of the ball’s local coordinates, or origin, is at the highest point of the object. It is relative to the origin that the ball will rotate when it is under the ceiling. I go t
o the side view, turn on the X-Ray mode, select the lowest point and click on the Proportional editing icon. I activate the Grab Tool with the G key, rotate the mouse wheel to increase the radius of influence, press the Z key to snap to the vertical axis, and move the selection down to get the desired shape. Using the Ctrl+ key combination on the pad, I expand the selection. Then using the Inset command I shift the polygons inwards, and with the Extrude command I extrude downwards. I press Ctrl+
R and using the Loop Cut tool I will add loops - additional edge loops. By pressing the S key, I will scale this area a little using proportional editing and delete the lowest vertex. Now we need to change the shape of the tie on the ball using polygonal modeling tools , which I will do right now . In order to create a node tool, you need a geometry nodes editor. It needs to be switched to Tool mode. Since this is a tool, there is no need to select any object and assign a geonode modifier to it.
But it’s better to experiment on a copy of the ball, so I’ll create it with Shift+D and place it next to it. First I'll create a noise distortion tool so that the tie will be naturally deformed. I create a new node tree with the New button. And in it there is a node for changing the position of the geometry Set Position, I connect it between Group Input and Group Output. I add a Selection node and connect it to the socket of the same name in Set Position. The Selection node allows you to use me
sh elements selected in edit mode ; this node works only in node tools and does not work in the geonodes modifier. I add a noise texture node Noise Texture. To make the noise truly three-dimensional, you need to use the color socket value. Now the noise is moving the vertices diagonally. To fix the problem, I will pass the noise texture through the Map Range conversion node in Vector mode. This is one way to correct the range. We need to convert the color vectors from the range 0, 0, 0 to 1,1,1
into a new range from -1,-1,-1 to 1,1,1. I connect the Map Range node to the Offset socket of the Set Position node. Between Map Range and Set Position I will add a Vector Math node in Scale mode. This is the intensity of the displacement. I connect it to the Group Input node. In the sidebar of the geonode editor, in the Group tab, I will rename the newly created input socket to Noise Intensity. And I’ll set the default value to 0.1. I will also display some noise parameters in Group Input. Thes
e are Noise Scale, Detail and Roughness. I will rename the tool itself to NoiseDeform. I'll rename the Scale socket to Noise Scale. In the face selection mode, holding down the Alt key and clicking in the desired direction relative to the center of the face, I will select a loop or loop of faces. I’ll expand the selection with the Ctrl+ combination on the pad. I launch my tool, which I called NoiseDeform, by clicking on the leaf icon in the viewport header. All displayed parameters appear in the
tool widget, and you can use them to adjust the intensity of the deformation. The next tool I'll make is to turn the edge loop into a tubular ring. In the header of the geonode editor, in the same Tool mode, I create a new node tree, calling it TubesFromEdges. I add a Selection node and a Separate Geometry node in Edge mode to separate the edge loop from the rest of the geometry. I turn these edges into a curve using the Mesh to Curve node to turn this curve back into a mesh, but with thickness
. To do this, I create a Curve To Mesh node and connect the geometry to the Curve socket, and create and connect a Curve Circle node to the Profile Curve socket of the Curve to Mesh node. I display the radius and number of segments in Group Input. Before using the tool, I will slightly adjust the shape of the tie by scaling it. All that remains is to select the desired loop and launch the second custom tool TubesFromEdges. As soon as I launched the tool, a ring of the selected edges was created,
but the ball itself disappeared. I cancel the tool to make adjustments to it. When creating a node tool that generates geometry, it is always worth keeping in mind whether the original geometry should be preserved. In this case it should, so I'll create a Join Geometry node and combine the original geometry from the Group Input with the tube geometry generated from the selected edges. You can move on to setting up the animation. I'll create two planes for the floor and ceiling. The floor is at
level 0, and the ceiling will be raised to a height of 3.5 meters. I add a geonode editor panel and, in Modifier mode, create a node tree with the New button for the active ball. This command assigns a modifier and immediately creates a datablock of geometric nodes in it. I pull a connection from the geometry socket of the Group Input node, this is the mesh of the ball itself, and create a Set Position node for changing the position. I pull a connection from its Offset socket and look for a node
that collects a vector value from three numeric ones - Combine XYZ. Having pulled out a connection from socket Z, I look for the Frame socket of the Scene Time animation node, it transmits the current value of the frame or second from the timeline. Here you will need a timeline to play the animation. If it is missing, create a new panel by dragging the corner and select it from the list. I set the animation range from 1 to 300 frames. I change the frame rate in the Output settings in the Proper
ties panel. I set it to 30 frames per second. If you turn on the animation, the ball will fly up through the ceiling at a speed of one meter per frame. I convert the range to change the speed and limit the flight to the ceiling height. To do this, I’ll create a Map Range node in Float mode and connect it between Scene Time and Combine XYZ. I will convert the time range into distance traveled. I want the movement to start not immediately from the first frame, but a little later from 25, and for t
he ball to take off at a believable speed. Empirically, I got a range from 25 to 160 frames, these are the values ​​I will enter into the fields of the boundaries of the original range From Min and From Max, and in the fields of the converted range To Min and To Max I will enter 0 and 3.5, respectively. But now the ball at the start is below the floor, so in To Min I will enter a new starting value - 0.4 This is slightly more than the distance from the top point of the ball, its origin, to its l
owest point. This is better, but the ball is still moving unnaturally, too linearly. And here you need to accelerate at the very beginning, but without slowing down at the end. A little math. You need to raise the range to a power greater than 1, but less than 2. But if you raise the range that exists to a power, then the maximum value will not be 3.5 but much more than 3.5 to a given power. I use a range whose boundaries do not change when raised to a power. And this is a range from 0 to 1. The
refore, I use two Map Range nodes and duplicate the existing one. In the first node I will replace the converted range with a single one, and in the second I will replace the original one. The range of frames is compressed, and I raise it to a power with the Math node in Power mode, and then it is converted to the desired distance to the ceiling. After several trials, I found a degree of 1.75. The ball accelerates, but at the very end it still looks unnatural; it does not bounce back. I add a va
lue conversion node using a Float Curve after Power before the second Map Range node. And here you need to work with the chart, literally draw these damped waves of rebounds, from 3 to 5 waves. The value of the second point is approximately 0.55 in X. The first two points and all the top ones should be with a fracture, that is, in Vector mode. Now there is a natural movement. Now you need to make more balls. I’m creating a node for a mesh primitive of a Mesh Circle, you can select any Fill Type
fill mode, except None, 32 vertices, radius 2.75. Now you need to distribute points over its surface using the Distribute Points on Faces node, along which the balls will be placed. To turn points into balls, I use the Instance on Points node, add the resulting points to the Points socket, and the ball geometry from Group Input to the Instance socket. From the output of the Instance on Points node, I connect the geometry to the Set Position node instead of one ball. Now there are a lot of balls
and they intersect. In the Distribute points On Faces node, I change the mode to Poisson Disk, Distance Min 0.4m, Density Max 6.480. But now all the balls move as one object. I need to add variety, for this I use a random frame offset for each instance object. I draw a connection from the Frame socket of the Scene Time node and look for the Math node in Subtract mode, this is the usual subtraction of numbers. Frame must be connected to the upper Value socket of the subtraction node , and to the
second one must be added a node for generating random values ​​in a given Random Value range in Float mode. The range is at your discretion, in my case Min -4, and Max 50. And each ball starts a little later or a little earlier than the others, which made the animation more natural. The animation is almost ready, all that remains is to add rotation. The rotation of individual instances is specified by the Rotate Instances node. To generate rotation that simulates air movement, I use the Noise Te
xture noise texture node in 4D mode. If you connect noise from the Color socket directly to the Rotation socket of the Rotate Instances node, then the rotation will be incorrect - that’s all the balls will be turned diagonally. Therefore, it is necessary to transform the range of noise values ​​using the Vector Math node in Subtract mode, and subtract the vector (0.5, 0.5, 0.5). Noise values: Scale 1.0, Detail 0.5, Roughness 0.67. I will connect Seconds from the Scene Time node to socket W. This
way you can simulate air movement. To slow down the movement, I will multiply the seconds by 0.25 with the Math node in Multiply mode. After Subtract I add a Vector Math node in Scale mode. If these rotation vectors are simply multiplied by a number, then the movement of the balls will be too chaotic. Therefore, you can use a copy of the very first Map Range node with a saved connection from the Frame socket, and connect it as the Scale value of the vector mathematical Scale node. The To Min va
lue in this case will be responsible for the intensity of rotation at the beginning of the balls’ path, and the To Max value at the end of the path, under the ceiling. I'll set 0 and 1.5. If the balls seem too stationary at the beginning of the journey, you can increase the To Min value a little. Now you can observe that when rotating the balls cross the ceiling. To prevent this from happening, I compensate for this by moving each ball a distance from the highest point to its origin, which defin
itely will not rise above the ceiling level. To determine the coordinates, I use the coordinate of the ball’s overall box; this box can be obtained using the Bounding Box node. But there is a problem. If you turn all instances into dimensional boxes, then the boxes will rotate along with the instances. Such bounding boxes will not help you find the highest point. Dimensional boxes must be in global coordinates. To get them, you need to use the Realize Instances node to convert the instances into
a mesh in front of the Bounding Box node. But if you transform everything at once, you will get one large dimensional box, which also will not help solve the problem with displacement, since each ball has its own displacement, which, moreover, changes over time. To get a suitable dimensional box for each ball, you will have to use cycles, that is, a Repeat Zone. The number of repetitions must be equal to the number of ball instances. I create a geometry domain size node Domain Size, it allows y
ou to count the number of elements in the geometry, I set the mode to Instances. The Instance Count value gives the number of instances, I connect it to the Iterations socket in Repeat Input. This socket is responsible for the number of repetitions in the Repeat Zone. Inside the zone, I create a Separate Geometry node in Instance mode to separate each ball by its index. I create a new socket in the Repeat Input node. To do this, you need to open the Node tab in the sidebar of the geonode editor
and select one of the outermost nodes of the repeat zone. Socket type Integer, name Loop. The initial value is 0. Using the Math node in Add mode, I add 1 and connect the result to the Loop socket in the Repeat Output node so that the value increases by one on each circle. This Loop value is required to use the loop number in the calculation. To separate the ball on each circle by index, I use the Separate Geometry node. I connect geometry to it, but not from the Repeat Input node socket, but di
rectly from the Rotate Instances node. The Geometry socket of the Repeat Input node is not needed because it does not contain anything, since I did not connect the original geometry of the balls. Next, I create an Index node, which reads all geometry indices. The index is the ordinal number of the element. We compare the values ​​of the Index node with the Loop value using the Compare node in Equal mode. Then I connect Realize Instances and Bounding Box. If you connect all this to the geometry s
ocket in Repeat Output, you will end up with one box. To collect the geometry of the boxes from each loop, I use the Join Geometry node, which I add before the output in the loop, and connect the geometry from the Bounding Box and from the Repeat Input to it. The result is dimensional boxes, the top points of which are at the same height as the topmost points of the balls. The entire cube is not needed, the coordinate of the top point is needed. Again, there are several ways to get this coordina
te. I'll just turn the center of the top face of each box into a point, it will be clearer. To do this, I use the Mesh to Points node in Faces mode, it turns each face into a point, but I don’t need a point from each face, only from the top one. And to separate the upper face, I connect the Compare node to the Selection socket in Vector, Direction and Equal modes. I add a Normal node to socket A. In socket B, the vector should be 0, 0, 1. I set the deviation angle Angle to zero. In this way, the
normal of each face is compared with a vector directed strictly upward. And such normals are only for the upper faces. Now there are points derived from the top faces of each box, one point per object, and each point at the same height as the topmost point of the ball. Next, you need to lower the balls by the difference in coordinates along the Z axis of their top point and the origin, that is, to the height to which each ball sticks out from the ceiling when turning. I connect the geometry of
the resulting points to the data sampling node using the Sample Index to obtain their position in the form of an attribute, so that this attribute can be used in calculations with the attribute of the position of ball instances. The node must be in Vector mode. I connect the Position node to the Value socket, and the Index node to the Index socket. This way I get the position value for each point. But I only need the coordinate along the Z axis, so I create a Separate XYZ node and connect the re
sult from the Sample Index to it. I create a Set Position node and connect the geometry of the balls to the Geometry socket. Now, using a mathematical node in Subtract mode, I subtract this height-shifted coordinate from the object’s own position, which, let me remind you, is tied to the origin, located at the highest point, and not at the geometric center of the ball. The coordinate of the instances’ own position along the Z axis is obtained by dividing the Position vector into components using
Separate XYZ. I assemble a vector to shift the position using the Combine XYZ node and connect it to the Set Position node to the Offset socket. Now the balls don't cross the ceiling. Additional control. I will add a dependence on the position of the ceiling. I drag the ceiling plane from the outliner into the geonode editor, it will turn into an Object Info node, pull a connection from the Location socket containing the global coordinates of the object’s position, and create a Separate XYZ nod
e to extract the Z coordinate from the object’s position. I connect this coordinate to the To Max socket the second Map Range node, which comes immediately after the Float Curve node. To control the speed, you can also move the maximum value of the original range from the first Map Range node to the Group Input. Now this value is in the modifier. I move on to setting up materials based on the Principled BSDF shader. First, I create a material, call it Balloon, and add it to the balls using the S
et Material node. I will configure the material in the viewport in rendering mode on the Cycles engine. I'll also add a couple of light sources. I have several material references. I will create a transparent and opaque material. In the shader editor I create Object Info and use the Random socket to set different colors for the balls, I connect the Random output to the Base Color socket in the shader. This option works without problems, since the balls are instances and are perceived by the syst
em as different objects. Now I add a Color Ramp node, change the mode to Constant, and set several colors. The randomization parameter of the Object Info node does not have a Seed value to allow control of the pseudo-random value. To control randomness, I create a White Noise Texture white noise node in 4D mode and connect Random to the socket vector, and with the parameter W I control the randomness. I connect the Value result to the Color Ramp. Now, to set transparency, I’ll create a Layer Wei
ght node with a Blend value of 0.2 and connect it to the Color Ramp node, setting the colors from light gray to white. The gray value is approximately 0.3. The ball material also has less transparency in areas and the tension is lower. For this effect, you can create an attribute in geonodes and use it in the material. Tension correlates with polygon density, and therefore with face area. Where the mesh is denser, the area of ​​the faces is smaller, and in these same places there is less tension
. Therefore, I take the Face Area node and connect it to the Map Range node. If I connect the geometry of the balls and this attribute to view in the Viewer node , then the desired result is not yet visible, since the area range is very small. And in Map Range I will set the initial range from 0 to 0.001. Now that's what we need. I create a named attribute using the Store Named Attribute node in Float mode, and set the name tension. Although the data was obtained from the area of ​​the faces, it
is necessary to save it into an attribute at the vertices in order to get the correct gradient, so the geometry domain will be Point. To use this attribute in the shader editor, I create an Attribute node and enter the name tension. Now, using the Color Ramp node and the Mix node in Color mode, you can mix it with the color from the Layer Weight node to get the desired transparency. Opaque material is much easier to make. The same Color Ramp node is used with the desired colors in Constant mode
, the transparency is simply adjusted with the Alpha parameter, I’ll set it to 0.75. If the Color Ramp is duplicated and connected to a Metallic socket, you can adjust the metallic sheen. The color used here is grayscale. White is a completely metallic surface, black is a non-metallic surface. To make the ball look more natural when exposed to light, I add subsurface scattering in the Christensen-Burley mode.

Comments

@3dddd3

Скачать файл проекта: https://docs.google.com/spreadsheets/d/1XpNJ7Al-t53uABys9pB5OU78IzTU9g9ymtC7dtw699k/edit#gid=0

@Vyach3D

Великолепный урок по нодам!!!

@julianarocky

Отлично 🎈🎈🎈