Blender Geometry Nodes 3.0 - Plant Growth with Fields

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi this is manuel with entegma today with a new geometry notes tutorial now that blender 3.0 is in beta geometry notes gets more and more mature and it's time for a little more complicated setup today i want to use geometry nodes to make some alien flowers grow on a grid let's directly dive in and get started first let's delete the camera and the cube and the light we don't need them for now instead let's lay down a plane this will be our first geometry nodes object so let's create a new collection and call this collection geometry nodes and call the plane 0 1 base geo and move it into this new collection just to keep things tidy and now let's get ourselves a geometry notes editor here geometry nodes and let's create a new geometry nodes tree and call it base geo let's create some base geo i don't want to use the geo that is here i want to create it procedurally so let's lay down a mesh primitive and a grid and this grid should have some decent size so let's say five by five meters and let's subdivide it a hundred by a hundred times for now let's connect this here if we go to wireframe mode we see that we have quite some subdivisions with this mesh in place let's make sure that it shades smooth by creating a shade set shade smooth node now let's make a terrain by using a noise texture so lay down the noise texture noise texture like so and this noise texture by default outputs values in the range between 0 and 1 and i want to transform these values so i will need some math nodes so let's first subtract 0.5 from the value that the noise node spits out and then this range will be multiplied by two this way i transform the range to minus one to one like so and next it might be a good idea to just add another multiplier for the strength i could use this one but that is more tidy i think and now let's combine x y z this value into a vector and use it as the z coordinate now we want to use this noise to displace our grid so let's lay down a set position node set position here and connect it here with the geometry let's put this vector here into the offset but at the moment of course the frequency is too high so let's start it down to 0.2 say something like this and the detail can go down to 1.2 or something so some nice shallow hills maybe a little more frequency 0.3 now this will be the terrain where the plants should grow now i'm done with the base geo and i don't intend to put everything just in one note tree instead i will create different objects with stages of the setup that way it's easier to debug it later and to work on individual parts now that we have that let's tidy this up a little bit like so set smooth like this we don't need the geometry input here let's go to the viewport and create just another grid another plane and this will be zero to seeds so now i intend to scatter some seeds onto our base geo with the seeds selected create a new notary and call it seeds like so instead of using the geometry let's cut this connection i want to bring in my base gear by just dragging and dropping it in and here's my base geo if i connect it i can make the original base geo invisible and i still have the gear here now let's scatter some seeds for this i will need the distributed points node distributes points and faces connected here and this will give us some seeds done well not exactly because we intend to make the flowers grow and instead of figuring out all the logic to grow the flowers later on with flower setup i just want to put a value and attribute on each of these seeds that indicates the growth factors so each of these seeds gets a value between 0 and 1 and this value tells the animation how far the plant that goes to the seed has grown for debugging let's create an instance on points and the procedural cube mesh primitives cube connected here to the instance such that we see something but the cube is too large so go down to 0.1 say i want to create an empty and use the scale of the empty to drive the effect so i want to be able to scale and empty in the viewport and make this control the growth so let's create an empty of type sphere and let's call it effector i use a german spelling here and let's go back to the seeds now drag the effector in the defector gives us the location and the scale of this empty and we can use both to figure out a value of growth for all of these instances for this we will need a distance node so lay down a vector math and switch it over to calculate the distance and we want to calculate the distance between the instances and the center of this empty so for this we will need the position of the instances or the points and we can just drag the location in here in the position in here and this distance node now outputs the distance between the center of this empty and the locations of the instances such that we can tell if one of the instances is inside of the radius of the sphere or not to calculate this we want to use the scale but the scale is a vector so let's first separate it separate x y z and let's separate out the scale and we only want to use x at the moment this thing is scaled uniformly so it doesn't matter so let's use x for our purposes and now we want to lay down a map range that will make the magic happen the distance goes into the value and the distance has a range that varies it might be up to four or so it depends on the geometry we want to make the distance aware of the radius so we want to give the instances inside of the empty a value of one to do this let's connect this x here to the from max so that means if the distance is zero the instance gets the value of zero and if the instance is the radius which is the scale at the moment then it gets a value of one but we want the opposite so we want to have a value of one whenever the distance is zero and whenever the distance is greater than or equal to the radius the value should be zero because we want to grab the flowers inside of this empty to see what we are doing here let's just connect this to the scale port here and you see it is working now we can select this empty and if we scale it you see it is working it is happily scaling the instances inside of our empty back to our note 3 but at the moment it starts here in the middle and then goes up to the radius that is not exactly what we need because we want to have an area where they are all grown to one fully and then a transition area so let's use the math node for this mass and let's use this scale but subtract the value let's say one that is the width of our falloff area and now connect this to the from min and now you see if i again scale this empty that all the instances inside have a value of one and only here in this transition area that is one unit wide we have instances of different sizes but at the moment they are all scaling at the same time and that looks a little boring so why don't we just vary the animation time by introducing a new range map node let's use this value that is calculated from the distance and then we set it 0 to 1 and zero to one and whenever the initial value reaches one we want to have one but some of them should just start later in growth so what if we give a random value to the from min let's create a random value node random value and connect it to the from min like so and now use this as a scale and i see if i scale this empty that they are not starting all at the same time some of them are animating faster and some of them are animating slower so for some of them to animate the value has to reach higher values so we created an animation weight so to speak and now it is time to put it on the points remember we don't want to keep the cubes and we don't want to keep the instance on points these two are only here for debugging so let's bypass them and instead let's take this value and write it to an attribute by dragging it to this hollow port now let's use the n panel and go to group and you can see it has created a value called result if we click it we can rename it let's call this effector weight because that is what it is so that is the name of the port and if we now go to the modifier itself we have a new output attribute effector weight goes to an attribute on the geometry and we want to name it the same so effector wait and now we have points with an attribute on them that tells the point how far they have grown with the animation now it's time to create our third object so another plane and this one will be called zero theory plant growth plant plant growth like so so that is where the actual plants go and this needs another geometry nodes tree and i call it plant growth just to stay organized no with a capital p like so let's drag in the seeds cut this connection it's not needed anymore and the seeds can be made invisible like so so now we want to use the seeds to put little plants on them and for modeling the plants i want to use curves lay down a quadratic a quadratic bezier this will create one curve if we connect it here you can see this curve is created let's make the effector invisible for now this curve is created and we want to alter the values so first let's set everything to zero let's reset this node zero zero and zero now the middle point goes in z to 0.5 and the end point in z goes to 1. we have just a line now or it looks as if it is line but it is a bezier segment and now we want to instance this quadratic bezier segment to the points that we created in seats so let's use a new instances on points node and let's feed it the seeds and as instance input we want to use the quadratic bezier and you see now we have a lot of bezier curves instanced to our seeds now let's vary this a little by varying the scale let's use a random value and say the random value goes between 0.5 and 2 and let's use another combine because scale is a vector and the random value is just a float and we just want to alter the z scale with its random value let's connect this to the scale and you see now we have a little variation of our bezier segments but these segments are a little straight if you ask me it would be nice to deform them and i want to deform them using noise but to be able to do that i first have to realize the instances because at the moment it's just instances of curves cannot be deformed so we need a realize instances node to convert these to actual geometry and now we can deform them with noise now this noise deformation goes pretty much like the base geo that we created let's lay down a noise texture and noise texture and we want to use this noise texture to deform the points that we created here but first again we have to convert this into the range between -1 and 1 this time we want to use a vector mass now to do this because we need the 3d output of the noise texture the color output so connect the color output here switch the node to subtract and subtract 0.5 from it now duplicate the mass node and set it to multiply by 2 like so and that converts the range again we can duplicate this multiply node for sorry that was not intended and again we can duplicate the multiply node to have a strength input set it to 1 for now now that we have this in place let's use a set position as before set position to alter the positions of the points of these curves and connect this to the offset and you see this gives some crazy chaos because the noise is very strong at the moment and moves all these points around the third thing that we want to do is to limit this noise deformation to the points that are up in the air there is an attribute on splines on curves and this vector goes between 0 to 1 along the length of the curve and we can perfectly use this to limit this so let's lay down a curve parameter node the curve parameter and that spits out the parameter along the curve for all the curves and if we connect this now to this strength input that we created you see that the defamation is limited to the points that are up on the spline and now let's again dial this down to 0.2 say and you see if i now move this slider only the upper parts of these curves are affected due to this curve parameter time to make them grow i'd say to make them grow we have to import the attribute that we created on the seeds remember affect the weight we have to bring it in the problem is that the seeds are different geometry than the blinds that we are currently working with so we will need a transfer attribute node transfer attribute to transfer the attribute by some logic from the point geometry to the spline geometry so the target is the geometry where the attribute is on and that is the seeds so let's connect it to this seed output here and now we have to specify the data type and that is a float and the method and we want to use index index means that we just use the index number in memory of the element to refer to the element and as we have as many splines as points this will work because say we have 20 splines then they have indices between 0 and 19 and the points have indices between 0 and 19 so by using the index we can create a one-to-one mapping between the curves and the points that is the preferred method for now but we have to connect an index input and we can do that by using the index attribute so if we just connect index here this index is the index of the curves and it maps to the index of the incoming points the only thing that is now missing is the attribute and to bring in the attribute we need the attribute name we have to specify this name on the modifier itself so let's connect this attribute port to the hollow port here on the group input that gives an attribute input field called attribute at the moment we again can go to group and rename it for clarity i want to call it effector weight because that is what it is effector weight is just set to zero but we want to use the incoming attribute so we have to click this little button to tell the field that it is supposed to be an attribute field and now write the name of the attribute here that is effector weight now effector weight is coming in but don't get this wrong effector rate is not actually coming in over this port because that is fields this is just a function so the transfer attribute has to just know the name of the attribute that it has to fetch from the geometry stream and what we are telling this node is just the name at first it might be a little distracting that this attribute is here on this group input although we are not using the geometry and it should work with this geometry although here is no attribute output but as soon as you understand that it is more or less just the name it makes more sense i'd say so this node is now reading the effector weight value and we can use it to make our curves shorter by using a trim curve node so lay down a trim curve node the trim curve node can be used to trim curves basically so if we connect it here after the set position we have a start and an end and you see if i dial down the end all the curves get shorter and the value range is again the curve parameter so this factor here between 0 and 1. but what happens if we now use the attribute that is coming in so if we put this to end you see that a lot of curves have vanished and that is because our effector now comes into play let me make it visible again and if we now scale this you can see that it is actually growing our splines the thing is just that we not only wanted to create these stems but later on we want to create little flowers and then we want to create leaves and merge all this geometry into one stream and output it here that means the geometry after this set position here will be quite different to the geometry of the spline and that means that the attribute values won't be consistent all the time to solve this problem there is another node that we want to use now and that is called the capture attribute because fields is always evaluating attributes at the point where they are applied but for us it is very important to have the attribute values of the seed points here at this point in the geometry this is a point where we have exactly as many splines as seeds and thus the mapping of the attributes is still intact we want to put the capture attribute here after the realized instances and we want to switch the domain to spline and now we want to connect this attribute to this value so what's happening here is now that although the realize instances already created a lot of points and now after this node we have a lot of points to run over the capture attributes make sure that every point gets the value from the spline domain so it converts from the spline domain to the point domain so having this capture attribute is very important from here on we have to use the attribute that comes out here so this is now our new effector weight and now we can use this to drive our end parameter here like so let's play with our empty it is still working so nice next step put some geometry on these curves let's create a curved mesh curve to mesh and put it after the trim curve but the curved mesh needs a profile curve for the profile i just want to use a circle so circle curve circle and connect it here which will give very very large curves the resolution is too high let's go down to eight and the radius is too large fortunately we can set the curve radius procedurally so look for a set curve radius node set curve radius and let's put it here after the trim curve like so and here we can dial down the radius until we have nicer stems okay but i don't want to stop here i want to make all these stems thicker at the bottom and thinner at the top i again want to use the curve parameter so let's create another one curve parameter and connect it here to the set curve radius now this parameter goes between 0 and 1. that is why the curves are again very large we can counteract this by going down with this radius of the curved circle to 0.02 say like so and now you see they are starting small and getting thicker that is to be expected because the parameter starts at zero and goes to one but we want the opposite so let's lay down a float curve like so and let's use this to remap this value first we want to invert it sort of like so and then i want to go up with this point a little bit to not reach zero entirely something like this next let's tackle the flowers themselves i want to put a flower in my case a sphere at the end of each of these curves for that i need a selection i want the last point of these curves and i want the last point after the trim curve because of course i want to put the flowers at the end of the trimmed curves so i want to use this geometry here that comes out here and i want to instant something on the geometry so let's lay down an instance on points again and let's drag this geometry in and for now let's go with the icosphere ico sphere let's make this smaller 0.2 save and two subdivisions and let's connect it to the instance and now it's time to introduce a join geometry because we want to have the stems and the flowers so this goes into join geometry and the output of this goes into joint geometry and all of this goes into the geometry output port and of course that is to be expected i get a sphere on every point of the curves that's not what i want fortunately the instance and point node has a selection port and we can feed a selection in here and with curve there's a special selection node called the endpoint selection so let's get us an endpoint selection and this works like this it is counting from the start of the curve or from the end of the curve then you put in the number how many points you want to select starting at the start or starting at the end we don't want any points at the start but we want one point at the end now connect this to the selection and you see we only get the last point now we have flowers on our stems and it's still working but of course as long as nothing has grown yet the flowers are too large so we want to scale them with the animation and that is where the unified animation value that we created with the seeds comes in handy because to drive the scale of these flowers we just can use the same value as before let's get ourselves a math node a mass node set this mass node to multiply and connect our beloved effector weight to the multiply node this one from the capture attribute the consistent effector weight this goes to the multiply node and now with the second value we can specify the end size and this goes into scale and now everything is scaling let's see if it is working if i go down as soon as the flowers are short the flower heads scale down because they just use the same unified value very nice so now we have flower heads let me clean up a little so this is the flower head all of this stuff is the flower heads and this is the join the output and everything here is the stems so let's write this down this is stems and this is a flowers just as a note to myself and that is a master weight like so okay so now we have flower heads we have stems but we don't have any leaves yet the next part is about creating the leaves for the leaves let's quickly model a leaf for that i will deactivate everything quickly such that i have a clean viewport and get myself a plane call this leaf so now we want to make sure that all the geometry is here to the right of the y-axis to make it easier to align it procedurally so let's select everything and then move it over gx1 like so let's just create some edge cuts like so one in the middle maybe another one there and there and let's quickly model this leaf geometry if i look at it from the top it's easy to select so let's go down with this one and down with that one and scale this one a little bit like so and that will be scaled even further and these two will be the scale and y only will be the stem of the leaf like so now let's select everything scale it down in y maybe make this a little smaller and now let's redistribute the loops gx and scale it a little bit and these two like so and all of that dx yes that will be our leaf now let's make it curved for that i will use proportional editing just select this one vertex here and if i now press rotate around the y-axis i can constrain my influence with this circle you can make the circle bigger or smaller with your mouse wheel and if i rotate up i get a nice curve to my leaf so this will be my leaf shaded smooth like so okay now that we have the leaf let's try to put the leaf on our flowers for that let's make everything visible again and let's go to geometry nodes so i want to use an instance on points again to instance the leaves and i want to have the leaves inside of the tree so drag them in just connect our trim curve geometry as before like so and then connect the leaves to the instance port and all of that goes into our join geometry which creates a lot of leaves a they are too large easy fix is a transform node so transform and put it here between the geometry and the instance port scale this down to 0.2 say better but you can see we have too many leaves because it puts the leaf on every point so let's see what's happening if we are scaling this and it is working sort of but as you can see it is not the behavior that we are looking for what we want to have is leaves at certain locations and the leaves should just scale up when the plant is growing and at the moment it gets redistributed that is not the right approach so we have to do something else and the solution is to not use the trim geometry here instead let's use the original geometry the geometry that comes out of this set position node we want to use this but we want to resample it because we want to have less leaves and we want to have control over how many leaves to create so let's create a re-sample curve node and feed it the geometry that comes out of that position and let's resample it to 9 same like so and now we want to use this for the geometry to gather the leaves on and you can see now we have less leaves and we have control over how many we want to create but at the same time the leaves do not respect the growth anymore of course not because we are not using the trim curve to make this work at least visually we just want to use our animation value to scale everything down to zero that has not yet grown this way we have consistent leaf positions and still have the impression that the leaves are growing on the stems so all the magic happens with a scaling to make this work we want to create ourselves another map range node map range and this map range will drive the scale you guessed it the value that we want to use is our master weight that drives all of our animation that goes into the value and now we can just connect this to scale and it will scale down everything at the same time let's again try to animate and everything is scaling down working like with the flower heads but now we want to use a curved parameter again to distribute this scaling along the length of the curve so let's create another curve parameter curve parameter node and let's use this by connecting it to the from min what happens now is that the stuff is scaling up with animation but that is not enough we don't want to have them scale over the entire animation instead we want to set the duration of the animation that's easy by just using a math node and adding to this vector i want to add a value of 0.2 say let's connect this to from max so what happens now is as you can see that the leaves are animating over the same amount of time one after the next and why is that because in comes the value of growth between zero and one the growth value will be zero until the factor is met and the factor is the position of the instance along the curve leaves higher up get a factor closer to one and leaves further down get the vector closer to zero the further down leaves will start animating earlier and then when the animation parameter varies between 0 and 0.2 say the leaf will scale from 0 to 1. and then the next leaf and then the next leaf always dependent on where they sit on the parent curve and that is determined through this factor this way we can make these leaves scale in and still have consistent leaf positions as you can see here because the leaves are always there it's just that all the leaves that are higher up than the growth the current growth of the stem are scaled down to zero so the last thing is that we want to align the leaves first we want to align the leaves with the growth direction for that we can use the tangent of the curves so let's create a tangent curve tangent and then to create a rotation out of this vector we want to use an align euler to vector node or this tangent will be used as the vector we want to use the z direction for rotation and then connect this to the rotation and you can see now the leaves are following the direction of the curves but they are all pointing in the same direction it makes a master leaf invisible now we want to rotate them around the stem and with a lot of plants the angle that the leaves are rotated around the stems while growing is often the golden angle and the golden angle is 137.5 degrees so now that the initial orientation of the leaves is correct we want to rotate them in their local coordinate space and that is why i'm not bothering with this rotation anymore instead i'm introducing a new rotate instances node after the fact because that one allows me to rotate in local space that means if i'm now rotating around z you can see i am rotating around the stems but i want to rotate each successive leaf by 137.5 degrees so let's create a vector for this rotation and remember this vector of course is in radians let's put in a value and convert it to radians for that i can use a math node switch it to 2 radians and put in 137.5 so that is phi in radians and now i want to read the id number of our leave and multiply it with this value here that gives successive rotations so let's create an id attribute and then duplicate this mass node and switch it to multiply and just multiply the id with the golden angle that is the angle that we wanted to use to rotate around the stems so finally let's use a combine x y z and just connect this to the z because we are only intending to rotate around the z and if i connect this now look what happens we get pretty plants looks quite natural although the geometry is so simple and now we are basically done we created all the three geometric effects that we wanted to make little alien flowers grow we have stems we have leaves and we have flower heads so now let's animate our effector at frame 0 i will scale this down quite a bit and keyframe the scale by pressing i over this scale field here and now let's go to 250 frames and scale this up quite a bit like so and another keyframe and now we have a nice flower growth animation let's quickly alter the interpolation by switching to the graph editor and then just selecting these two keyframes and then going to key interpolation mode linear because we don't want to have a curve here so to see this better let's apply some materials select this and let's use the set material node to apply some materials first let's create a material let's switch over to the shader editor quickly and let's call this material stems then let's copy the material let's call the next one flowers and let's copy the material and the last one is called leaves like so and the leaf material for now will be sort of bluish and flowers material will be orangey and the stems material will be pinkish like this now back to geometry nodes and let's see here are our three geometry streams the first is the stems then there comes the flowers down here we have the leaves i have to write it here leaves like so and now let's find a set material node one here duplicate it here and duplicate it here and first comes the stems yes the stems get the stems material and then the flowers get the flowers material and the leaves get the least material let's switch to eevee to see how it looks well the materials are working so time to reintroduce our light point light like so and make this a little brighter or quite a bit brighter like so and here you have it our little animation okay some fixes our flower heads are still tessellated we can change this by introducing a shade smooth note set shade smooth like so and of course the stuff should move with the wind so to make everything move with the wind while growing we want to animate the noise that we are using to deform the stems to animate the noise we want to alter the space that the noise is evaluated in and we can do this with this vector port here so we want to change this vector port at the moment the noise is evaluated at the position of the geometry we are applying the noise here that means these realized instances the points from the realized instances are the positions that get used to sample the noise texture but we can add to this position by introducing a vector math and we want to get the position of the geometry like so and now we want to add to this position and then we connect this here now we have a vector to add to the position nothing changed so far but as soon as i'm dragging here you see the stuff is animating like crazy because we are moving the sample space around and that is very wind-like we want to animate this all the time the best thing would be to just drive it with the current time we can do so by bringing in the frame and we want to bring it in as an input attribute so let's create another math node mass we will need it in a second multiply and let's connect this hollow port to the first port here so we get another port and with the group panel we can rename this to frame like so but at the moment nothing comes in then we want to take the frame number and then multiply it by 0.5 or another value and use it to drive our noise so for that we will need another combine x y v combine x y z because we only want to alter the x value like so okay something happened and what happened is if you go to the modifier and we now have this value here and you can drag on the value and we can now alter the vector space from outside of the setup now that we have this we can click here and just type numerous frame which will create a driver that puts the current frame into this field and that means that now the stuff is animating but of course it is a lot too fast that is why i created this multiply node in the first place so let's multiply this down by 0.05 to make it a lot slower and now it is animating but spatially it's still quite fast so maybe we have to multiply the entire noise down a little the amplitude by introducing another multiply node before we create this weighting with a curve parameter and go down to 0.5 or so to make the overall effect less apparent and i think that looks quite nice and that concludes our note graph that we created to make these flowers grow let's see what we have now rewind time let me switch back to the timeline rewind the time and play and you see now we have a nice flower growing animation completely procedural with individual flowers that are driven by wind and all the leaves are growing and all of this is just controlled by one empty so we have one empty you can move it around and it will control the animation this really shows the potential of a procedural system like geometry nodes i hope you learned something in the tutorial from today and see you next time if you like what we are doing please consider becoming a patreon for supporting us and for access to more in-depth courses on topics like volume techniques or pdg or vellum and more to everybody who is already supporting us thank you so much without your continuous support and time would not be possible
Info
Channel: Entagma
Views: 35,609
Rating: undefined out of 5
Keywords:
Id: XSkaM-8Vgz8
Channel Id: undefined
Length: 40min 17sec (2417 seconds)
Published: Mon Nov 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.