Boids Simulation using Geometry Nodes Tutorial | Blender 4.1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we will be making this void's animation using geometry nodes in blender 4.1 the system will work by having a large simulation Zone with a repeat Zone nested inside of it to calculate the new boy trajectories the boy's algorithm simulates bird flocks the word Bo actually refers to a birdlike object and yield surprisingly complex results based on three Simple Rules we will be implementing a configurable system to simulate all three of these rules in Geometry notes cohesion alignment and separation start off by creating a new blender project again I'm running version 4.1.0 next press shift a to enter the object Edition menu add a cube and then enter the geometry nodes editor by pressing the option on the top bar create a new geometry nodes project by clicking the new button in the middle of the screen disconnect the group input geometry from the group output geometry we are doing this because we're not actually going to use the cube we created earlier instead we are going to pass points through a simulation Zone this node works by repeatedly performing some operation on the input using its own output as the next frame's input press shift a and search for simulation Zone then connect the output of the zone to the group output node now add a points node and connect it to the simulation Zone input these points will act as the boids in our simulation every frame each point will pass through the simulation and get changed in some way then this new state will be outputed and passed back into the simulation continuing the process we want to spread these points out randomly though instead of all of them being in the same spot so add a random value node switch it to vector and connect it to the position socket on the points node set the minimum Vector to -10 -10 0 and the maximum to 10 10 0 now if you increase the number of points they will be spread out within that boundary as their position is being manipulated by that random value node this is up to preference but I prefer to disable with 3D cursor and Origins and to enable the cavity option in the modeling window just so that the points stand out a bit more and there's less clutter on the screen now that we have our points we want to change them to move with some kind of velocity every frame doing this with simulation nodes is quite simple add a set position node and drag it onto the geometry then click the simulation Zone node and press n to open the node editor window navigate to the node tip and click the small plus icon on the right to add a new property change it to a vector and name it velocity by double clicking on it connect that new property to the simulation output and also connect it to the offset of the set position node with this setup our velocity will remain constant and our points will all be offset by the same velocity every frame if every particle moved in the exact same way it wouldn't be particularly interesting to look at so to remedy that duplicate the random value node we created earlier and change its seed to a different number then connect it to the initial velocity input of the simulation zone now add a vector math node and set it to normalize place it between the two nodes normalizing a vector transforms it to have a length of one while maintaining the same angle with this node all the points will move in different directions but at the same speed this velocity Vector will be important later on in order to access it later we need to associate each point with its velocity by utilizing a named attribute this this way we can access the velocity later by calling on the attribute add a store named attribute node and place it on the geometry line set it to Vector connect the velocity at the value and set its name to Velocity now let's define what we're trying to do to each velocity suppose we have a point which is our void and it has a certain radius of vision around it let's say all the boids within that radius have a specific velocity and position value assigned to them that we can access so what do we want our new velocity to equal firstly we want to compute the average position of all the voids within that Vision radius and we will add that to our current velocity then we also want to add the average direction of all the voids in front of us so we want to take each angle and make a new Vector based on that all the vectors can combined thirdly we want to have a second radius a smaller one and if there are any voids within that radius we want to steer away from them this will be our separation component for the average position and average velocity we will need to know the number of neighbors within our defined vision of the each void and once we have all those things computed we can add them all together to get our new velocity now that we know what to do let's get to implementing this system simulation zones work by looping over every point that is inputed at the start and we will use that point as the reference position in order to access the attributes of points only within a specified radius of that reference point we need to iterate over every single other point in Geometry nodes this is done using a repeat Zone as per the name the repeat Zone will repeat whatever is inside of it by a certain number of iterations add a repeat Zone and place it somewhere in the middle of the setup for each of use place a group input node and using the side panel menu make a new value in integer and name it count plug this new input value which we can now change in the modifier stack into the point count and the iteration socket of the repeat Zone this way the number of iterations will be the same as the number of voids in the simulation in order to find the new velocity we need to define a sample or reference position that we can draw the radius from we can draw this position straight from the simulation Zone to extract an attribute from the points we can use a capture attribute node to specifically get the position at a position node and set the capture attribute node to accept vectors connect the position as the value the output of the capture attribute node now is the position of the Void we are evaluating now take the output position and connect it to an empty socket of the repeats on we can now reference this position while iterating using the side menu rename it to SLE position connect the sample position through the repeat zone so that it stays as a constant every iteration and does not change right now the repeat zone is iterating over nothing in order to access every boy's data we need to tell blender which one we want to look at in Geometry nodes each point is represented by some index you can see this value on the spreadsheet in the top left corner in the leftmost column and this value starts at zero if you've programmed something using lists before this is probably familiar since there are as many indexes as there are points each iteration of the repeat Zone should look at a specific index the sequentially Loop over every index say 0o 1 then two then three then four and so on we need another variable using the side menu in the node tab again with the repeat Zone selected make a new value of type integer connect it through the zone and this time instead of letting the value be constant at a math node set to add a value of one this way each time the cycle repeats there will be a new unique index that corresponds to some point using the index we will be able to compare the reference position defined earlier with the position of another point now that we're iterating over every point we can extract attributes from those points for comparison with the reference position to access the position of a point based on its index geometry nodes has the simple index node add one and connect the index and geometry to it by comparing some points position position to the sample position we can determine if it is within the radius and from there whether or not to include it in the velocity calculations so add a position node and connect it to the value of the sample index node to find the vector between the sample position and the new position at a vector math node set to subtract connect the sample position to the bottom slot and the sample index node's output to the top slot this subtracted Vector goes from the sample position to the position of the other point next add another Vector math node set to length since a subtract node output of the vector from the sample position the length is the distance between the two points finally add a compare node set to less than or equal to to check if the point is within the specified radius for ease of use add a group input node and add a new value set the distance named threshold and connected to the compare node now we have a Boolean that specifies whether or not a point is within the radius that is defined in the modifier the first value we will compute will be the number of neighbors create a new integer socket in the repeat Zone using the side menu named number of neighbors pass it through the Zone then add a switch node this node as the name suggests switches a value when a Boolean is true plug the number of neighbors input to the false side and plug the output of the switch node to the number of neighbors output then add a math node set to add a value of one plug the initial number of neighbors value into the a socket and connect the output of the math node to the true input of the switch node then connect the Boolean from the compare node to the switch node now whenever a particle is within the radius of the reference position the number of neighbors value will increase and be switched from the previous value to the value plus one the next thing to implement will be the average position to get an average you first need to add up all the values in this case these Val would be the positions of points within the radius just like the number of neighbors add a new tab in the repeat Zone named average position create another switch node but set it to Vector this time connect the Boolean result from the first compar node to the switch and then set it up in the same way with the false input of the switch being the previous value unchanged and the True Value connected to a vector math Edition node to add the new position use the output of the sample index node from earlier for the average direction or average velocity of the points the setup again is very similar add another input in the repeat Zone Add a switch node connect it to the Boolean and use the previous value as the false and a vector mouth addition for the true you may notice that we still have not extracted the velocity from the points this is what the named attribute was for earlier by creating that attribute and having the points capture it earlier we can now access it with using another sample index node add one set it up in the same way as the other one with a geometry and being connected set the type of value to vector and a named attribute node also set to Vector connect that attribute to the sample index node and then type in the name that you set earlier into the name tab now connect the output of that sample index node to the vector Edition node finally for the separation component add another tab in the repeat Zone and connect it through then add a switch node since the separation relies on a different radius or distance add a new compare node set to less than or equal connected to the length node we used previously and also to another group input node this time named separation distance set it to be a distance value connect the new compare node to the switch for the false input pass the unchange separation value through and for the true input add a vector math node set to subtraction the reason we are subtracting is because we want the boy to move away from other points that are too close so we need to add a negated version of the vector in instead if you recall we previously already made a vector that went from the reference position to the other points position subtracting this Vector will steer the void away from that point we have now calculated all three forces in the void's algorithm using iteration let's quickly summarize what we just did as I mentioned previously simulation zones work by individually looping through every point for every point we are looping over every other point using a repeat Zone to calculate the new velocity first we compare the reference position from the simulation Zone to the one we are iterating over in the repeat Zone if those two points are close enough we consider them a neighbor and increment the number of neighbors's variable additionally we add that Point's position and velocity to the respective variables if a neighbor is too close to the reference point then we use Vector subtraction to create a force away from the neighbor now that we have the raw numbers calculated we need a system to weigh each value differently for both ease of use and functionality however there's still one issue during a repeat Zone calculations at some point the index landed on the same point as the one that was being referenced this means that in order to have only the neighbors's values counted we need to subtract away the reference points attributes add a math node set to subtract a value of one connect that to the number of neighbors variable then add two Vector math nodes set to subtract for the first one connect the average position on the top and the sample position on the bottom for the second Vector math node connect the average velocity to the top to get the velocity of the current void add another captur attribute node and connect it to another named attribute node the same way we set it up in the sample position earlier then connect the captured attribute to the bottom slot of the vector math node currently we only have the sums of the positions and velocities of the other points to get the average we need to divide by the number of boids evaluated which is conveniently the number of neighbors value add two more Vector math nodes set to divide plug the outputs of the subtract nodes into the Divide nodes and then put the subtracted number of neighbors value into the bottom slot to make these new vectors easier to work with add two more Vector math nodes set to normalize for ease of use we will use Sliders in the modifier panel to control the cohesion alignment and separation forces at a group input node in the group tab in the side menu add three new inputs name them accordingly and set their subtype the factor set their minimum value to zero and the maximum to two to be able to modify all these aspects of the simulation intuitively we need to change these input values this will consist of several math nodes these numbers aren't specifically special but they are what I found works best first off add two subtract notes set the Top Value to two for both and then connect the cohesion and Alignment values from the group input next next add two more math nodes set to multiplication and multiply the two math outputs by 50 finally add two more math nodes set to add a value of 01 these two final nodes are for instances where the weights go to zero and they serve as a minimum to apply these to the vectors add two Vector math nodes set to divide plug the normalized vectors into the top slots and the outputs of the math nodes into the bottom slots finally for the separation add one more math node set to multiply a value of five connect the group input separation value to this then add a vector math multiplication node connect a separation component from the repeat Zone and the math node to obtain the final velocity we now need to add all of these values together to the previous velocity add three Vector bath nodes set to add add the previous velocity which is still be connected to the set position node from earlier in the process and the separation component to the first Adder then add the previous adder's output and the alignment using the second node finally add the second adders output in the cohesion value using the last ad node to finalize this new velocity add one more normalized node and one more Vector multiplication node to the setup set the multiplication node to 22 0 we can use this multiplier as a way to control the general speed of the simulation connect the multiplication node to the set position node that we created earlier we have now technically finished the boids algorithm having implemented all three of the rules however if you run the simulation you'll notice that the boids all scatter off in different directions and don't ever stop to keep the boids within an enclosed boundary we need to create another force a border that pushes voids away when they get too close to a boundary creating a border will consist of checking the X and Y components of the Void positions and then adding a force away from the border if the position is over the limit for example if a void goes too far on the x- axis a vector of - 1 0 0 would be added which would push the point to the opposite direction navigate back to the start of the simulation Zone where we extracted the sample position add a separate XYZ node and plug the position of the point in now add four compare nodes set two to greater than and then set two to less than than plug the X component into one greater than and one less than node do the same for the y- AIS to allow for customization add a group input node and add two new properties using the side menu name them X bound and Y bound these will control the size of the Border firstly connect the X bound directly to the greater than node that is connected to the X AIS then do the same for the Y bound and Y AIS since the two other compare nodes use less than add two math nodes set set to multiply by -1 connect the X and Y bounds to the math nodes then connect the math noes to the respective less than compare nodes now the boundar is user editable and we can tell when a boy crosses any of the boundary lines through the compare nodes in order to translate these Boolean results to a vector output we will again make use of switch nodes add four all set to Vector connect them horizontally from the compare nodes leave the false vectors unchanged and for the true vectors use the following for the greater than xaxis node use -10 0 0 for the less than xaxis node use 10 0 0 for the greater than y AIS node use 0 -10 0 for the less than y AIS node use 0 10 0 essentially all that's happening here is that when a void crosses the boundary we get a vector that opposes that boundary now create three Vector math addition nodes and connect all the switch node outputs for the first Adder add the first two switch nodes for the second Adder add the first one's output in the third switch node and so on finally to control the strength of the Border add a vector math multiplication node and connect it to the added up output then add one more group input node and create a new variable set to float and Factor named border strength set the minimum value to to zero and the maximum to Value to one then connect the Border strength to the multiplication node to add the new border Force to the other velocity calculator add a vector math node set to add add the Border vector and the other Vector the output is the final velocity of the Void to finish off the project we need to transform these points into actual geometry go into the model tab add a plane go into edit mode and select two points on one of the edges press M and then select at Center this will merge these points together then at the opposite Edge add a loop cut using controlr and then click move this new point inwards and then scale the entire plane however you like make sure the front end of the plane is facing the positive xais once you're done modeling press crol a and select all transforms you can then hide this plane using H go back into the geometry noes editor and go to the end of the network before the group out node add a instance on points node and connect an object info node select the plane in the object info node and adjust the scale using the instance on points node you will notice that while the plane is being instance on every point it's facing the same direction every time we can fix this using a vector math formula given a vector X Y its angle from the xaxis is the tangent inverse of Y / X to implement this in the geometry node setup add a separate XYZ node then connect the velocity output of the simulation Zone to the node add a math node and divide the Y value by the x value then add another math node set to arc tangent which is the same thing as the inverse tangent theoretically the output of this note is the angle of this Vector however it is important to remember that the arct tangent operation is limited to a range of Pi to Pi radians or 90 to 90° this means that the setup can only handle angles up to 90° from the xais in order to account for angles beyond that we need to add Pi radians or 180° to the angle if its X component is less than zero as per usual to implement this in blender we need a compare node and a switch node set the compare node to less than and plug in the x value then set the switch node to float and plug the raw arc tangent value into the false slot for the true add a math node and also plug in the arc tangent for the addition type Pi then connect the add node to the true socket of the switch node since we are rotating these points on the z-axis add a combined XYZ node and plug the switch node output into the Z Tab then connect the new Vector to the rotation tab of the instance on points node we are now completely done with the geometry node set hopefully everything was understandable and clear I tried to explain what exactly was going on where I could if you would like to have the same material that is on the screen now here's a quick explanation first add a capture attribute node on the main geometry line set it to integer and connect the number of neighbors value from earlier then connect the output of the capture attribute node to the output of the simulation Zone add a map range node outside of the simulation Zone and connect the outputed value set the from minimum to one and for the maximum add a group input node and connect the void count multiply this value by 11 connect this to the group output node and name it density in the modifier panel go into the output attributes Tab and type in density again now enter the shading window make a new material and add an emission node in a color ramp then add an attribute node and set it to density and type in density connect the factor to the factor of the color ramp set the color ramp to HSV and clockwise and then set one side to red and the other to Blue Back in the geometry notes editor add a realized instances node and the set material node to finalize the effect thank you for watching and listening if you would like an extra challenge try and expand the setup to three dimensions simply adjust the spawning criteria and add another border the rotation aspect is a bit more tricky here's a setup I found that also uses Vector math
Info
Channel: CaptainSmollett
Views: 381
Rating: undefined out of 5
Keywords:
Id: S9JBSvtmD_k
Channel Id: undefined
Length: 23min 46sec (1426 seconds)
Published: Fri Jun 28 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.