3D Trees with Blender Geometry Nodes | 3D Tudor | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

3D Trees with Blender Geometry Nodes

teacher avatar 3D Tudor, The 3D Tutor

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      3D Trees with Geometry Nodes Course Introduction

      3:11

    • 2.

      Tree Generator Overview

      6:07

    • 3.

      Branch Generator Intro

      3:58

    • 4.

      Split Ends

      13:45

    • 5.

      Branch System Basics

      12:24

    • 6.

      Advanced Branch System

      17:14

    • 7.

      Internal Data

      13:59

    • 8.

      Roots

      8:42

    • 9.

      Displacement

      11:21

    • 10.

      Mesh Generation

      9:08

    • 11.

      UV Mapping and Refinement

      12:37

    • 12.

      Leaf Distribution Basics

      9:59

    • 13.

      Advanced Leaf Placement

      11:28

    • 14.

      Basic Particle System

      12:10

    • 15.

      Advanced Particle Simulations

      14:17

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

210

Students

4

Projects

About This Class

Dive into the fascinating world of procedural tree generation with Blender’s Geometry Nodes!
[Click Here for Resource Pack]

In '3D Trees with Blender Geometry Nodes', you’ll learn how to build natural-looking, fully customizable 3D trees—from trunk and root structures to realistic leaf distribution. You’ll also explore advanced techniques like noise displacement, Split End Nodes for branching, and even a simple simulation setup for falling leaves. This hands-on approach ensures you gain practical skills you can apply to everything from game environments to stylized forest scenes.

By the end of our lessons, you’ll know exactly how to transform curves into optimized 3D meshes, map textures efficiently, and develop a node-based workflow that’s both flexible and efficient. Whether you’re a Blender beginner looking to expand your skill set or an experienced 3D artist aiming to streamline your process, this class will show you how to grow professional-quality trees with a few smart node setups.

Why Choose 3D Trees with Blender Geometry Nodes?

  • Professional 3D Trees – Ideal for game developers, environment artists, and hobbyists looking to create high-quality trees for games, animations, and 3D worlds.

  • Hands-On Procedural Mastery – Master key techniques like the SplitEnd Node, Branch Randomization, and Root Systems to develop organic, natural-looking trees from scratch.

  • Advanced Node Techniques – Discover how to distribute leaves dynamically, add procedural noise displacement, and generate complex branching structures using repeat zones.

  • Simulated Falling Leaves – Implement a particle system (Blender’s Simulation Zone) to create leaves that detach, fall, and bring movement to your scenes.

  • Realistic UV Mapping & Mesh Generation – Convert procedural curves into fully functional 3D meshes with proper UV maps and seamless material application.

  • Grow Your 3D Skill Set – Apply these techniques to a wide range of projects, from realistic environments to stylized fantasy landscapes.

What You’ll Learn

  • Procedural Foundations: Create trunk and root structures using custom node groups.

  • Branching & Randomization: Master SplitEnd Nodes and repeat zones for natural branching patterns.
  • Leaf Placement & Simulation: Control leaf distribution along branches and set up falling leaves for dynamic realism.

  • Mesh Conversion & UV Mapping: Convert curves to mesh efficiently and apply textures without fuss.
  • Practical Node Workflows: Build a modular system you can reuse for trees, bushes, and beyond.

Who This Class Is For

  • Game Developers & 3D Artists seeking optimized tree assets for real-time engines or cinematic scenes.

  • Stylized Creators wanting to add foliage to fantasy realms, alien landscapes, or concept art projects.

  • Blender Enthusiasts ready to explore procedural modeling and broaden their environment design capabilities.

Why This Class Is for You
Learning these procedural techniques opens up endless creative possibilities. You’ll gain a deeper understanding of Blender’s Geometry Nodes, speed up your workflow, and produce rich, dynamic 3D environments—perfect for animations, games, or imaginative personal projects.

Time & Resources

Class Duration: 9 in-depth lessons spanning over 2 hours of procedural modeling techniques.

Resource Pack Included

This class comes with a high-quality resource pack featuring 8 stylized PBR materials designed for procedural tree creation. Cherry and oak bark textures, cherry branch variations (blossomed and non-blossomed), and oak leaf variations for summer, autumn, and spring are all included. A cherry petals pack is also provided for realistic falling blossom effects. The finished project file is part of the package, so you can compare and refine your tree setups easily.

Ready to Start Growing?

Take control of procedural tree creation like never before. From fantasy trees to realistic forest foliage, this Skillshare class will open you up to new projects.

Push your Blender Geometry Nodes skills further and start crafting awesome 3D trees.

Until next time, may all your polygons take root—and may your leaves never fall too soon!

Luke

Meet Your Teacher

Teacher Profile Image

3D Tudor

The 3D Tutor

Top Teacher

Hello, I'm Neil, the creator behind 3D Tudor. As a one-man tutoring enterprise, I pride myself on delivering courses with clear, step-by-step instructions that will take your 3D modeling and animation skills to the next level.

At 3D Tudor, our mission is to provide accessible, hands-on learning experiences for both professionals and hobbyists in 3D modeling and game development. Our courses focus on practical, industry-standard techniques, empowering creators to enhance their skills and build impressive portfolios. From crafting detailed environments to mastering essential tools, we aim to help you streamline your workflow and achieve professional-quality results.

We're committed to fostering a supportive... See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. 3D Trees with Geometry Nodes Course Introduction: Welcome to three D trees with Blender geometry nodes. In this course, we will explore the powerful procedural workflow of blended geometry nodes to create fully customizable and realistic trees. From generating organic trunk structures to finally distributing leaves, you will learn how to craft natural looking trees with procedural flexibility. By the end of this course, you will have the skills to create trees ranging from ancient oaks to delicate bonsai, all controlled by easy to use perimeters. If you are interested in pushing your gemenude skills even further, don't miss our blender geometernode for beginners, procedural bridge generator, and foliage scatter courses. These will help you refine your procedural modeling techniques and create stunning freedy environments filled with foliage, architecture, and more. To help you bring your trees to life, this course includes a high quality resource pack, featuring eight stylized PBR materials crafted specifically for procedural recreation. You'll get cherry and oak bark, blossomed and non blossom cherry branches, and seasonal oak leaves for summer, autumn, and spring, plus cherry petals for stunning falling leaf effect. We will begin by building a procedural tree system from the ground up. You will start with the foundational split end node, a custom node group that generates branching structures by iterating multiple curve splits. Using perimeters like branch count, length, and angle, we will craft a realistic growth system that mimics natural tree formation. Additionally, we'll implement a noise displacement to introduce subtle movement and realism to the tree's overall form. Once the trunk and branches are in place, we will shift our focus to leaf placement. Using custom attributes such as lengths from start and lengths from end, we will determine how leaves are distributed along the branches, ensuring natural growth patterns. Next, we'll extend our procedural system to generate roots. By modifying the branch system to reverse its direction, we'll create an underground root structure that connects seamlessly with the trunk. Finally, we'll explore UV mapping techniques, ensuring that bark and foliage materials are applied seamlessly. In the final section, we will integrate a simple particle system to simulate falling leaves. Using blenders simulation zone, we will generate and animate leaves that detach from branches over time. This course is designed with modularity and efficiency in mind. By using reusable node groups, you will be able to quickly adjust perimeters like tree height, branch density, leaf coverage, and more. Whether you need a stylized tree for game or hyper realistic op for an animation, our setup will allow for rapid iteration and customization. By the end of this course, you will have a fully procedural tree system that's customizable, efficient, and visually stunning to bring your creative vision to life. Join now and start growing your own credi trees with Blenders omiton rods. 2. Tree Generator Overview: Hello, and welcome to the introduction to free D trees with blender geometry nodes. In this course, you will learn how to create a fully procedural tree using blenders geometry nodes. You will build a realistic trunk and branching system, control leaf placement, and add a simple particle system for falling leaves to bring natural movement to your tree. To help you along the way, you will also receive a free material pack with high quality oak and sakura textures and materials perfect for this course and future projects. Before we start building, let's go over the inputs and perimeters that will control your tree shape and structure. By tweaking these settings, you'll be able to create anything from small bone site to massive oak. So this ometer node is just a one modifier. So as you can see, I have here this tree modifier applied to this object, and you can see that right here, we have few parameters. One of them is seed which controls seed of all of the random values and random generators. Then there is resolution which controls resolution of branches. You can set height of the trunk and overall radius. And then there's also material for roots and branches and also controls for the UEs. Then in branches panel, you can see that first input is called levels, and that controls how many levels of branches your tree will have. So if we set this to just two, for example, so first, there is a trunk, which is a separate branch or one main branch. From this branch, there are three more branches like this. And from these branches is the second level of branches, so it looks something like this. The second two inputs are min and max split count, which means you can control to how many branches each end of the branch will split. So here we have 3-5. If we set it 2-5, you can see that now it just splits to two branches. And if we play around with seed, we should get some different results. Now you can see we have four of them and so on. Then you can also control lengths of branches. You can control first and last separately. So if we set first branches to something long and last to something short, you'll have different results. And there's also a length randomness, which controls how randomized the lengths of the branches are. The next thing is angle, which controls the angle of branches. So you can see if we set it to zero, they are all pointing upwards, and as we increase it, the tree gets much wider and the branches are growing more to the side. You can also control the randomness of this angle, and the last input is radius fff, which basically controls the thickness of the branches. So now you can see it's set to two, and you can see that the branches at the ends are thin. And if we decrease it, you can see that they get much thicker and you can control the gradient of the radius going from the trunk to ends of the branches. The next panel we have are the roots, and this panel has basically all of the controls as branches, and you can control same parameters. So I will skip this one. The next one is displacement with which you control the displacement of the branches. So you can control how straight or how quigly your tree is. The next one are trees. So here, we can control the trees. You can select collection of the leaves. So we can easily swap between those. We can also control density, and we can pick from three options where we want the leaves to grow. So there are three options. One is branches. That means that leaves are all over the branches. The second one is from end, which basically distributes the leaves only at the ends of the branches, and we can also control the length of the segments on which they are distributed. And the last option is minimal Z position, which basically distributes leaves everywhere where the position is higher than some value. So if we said this to three, you can see that here we have level three and where the position is greater, the leaves are distributed. The last two things are scale and scale randomness, so you can also control how scaled the original objects are. And the last panel which we have here are particles, and you can see it here. Those are the small leaves which you can see, and you can control their density, also physics, so we can control the gravity and some noise which is applied to their movement, and also how long they live. And same as for the leaves, we have collection for input objects and their scale. You can see that if we play the simulation, you can see that the leaves start falling from the leaves, and it creates a really nice effect. 3. Branch Generator Intro: Welcome back to three D trees with blender geometry nodes. In this lesson, I'll explain the techniques which we'll be using for generating the branch system and how we'll be able to control it with different perimeters. First, I'll just set density of leaves to zero so we can better see the branch system. And as you can see, we can simplify the structure to just lines. So for example, one main line is the trunk, then there are for branches to which it splits, and then it basically does the same thing at the ends of these branches. So the setup which we will be making will have one input for the geometry. So in this case, when we have trunk, we will give this trunk to this node group, and we will also give it a selection from which we want the branches to grow. So I'll selected with this cross. And what the setup will do is it will just generate branches like this depending on the inputs. So we'll be able to control to how many branches it splits and also how long and angled these branches are. And the output of this node group will be those branches. And also with selections, which will select those endpoints. And then we will use recursive approach or something very similar to recursion, and that we will again use this setup after this first iteration, and this set up will again create some more branches like this. And if we iterate this, for example, three or four times, we should get a nice branch system, which we will use as a basic structure for our geometry nodes modifier. Later in this course, we will also need some attributes for information about the branches. The two main attributes which you'll need is length, and the length will tell us how far each point of the branch is from the roots. So here at the bottom, zero. Here in this section, it's, let's say, for example, two, here it's free everywhere, and here at the ends, it can be like 3.5. With this attribute, we'll be able to control the radius of the branches and also get nice UV maps for them. And the second perimeter will be length from end. And this perimeter will be almost the same as the length, but it will go in different direction or in the opposite direction. So at the ends of the branches, it will be all zeros. And then as we go towards the roots, it will increase. So 0.5 will be here, 1.5 here, 2.5 here, and 3.5 in the roots. With this second attribute, we'll be able to, for example, distribute leaves from ends as I showed in previous lesson, and we will just separate those branches where the length from end is less than some value, and then we can distribute easily leaves on these branches. 4. Split Ends: Welcome back to three D trees with Blender Geometri nodes. In this lesson, we will start working on the foundation of our geometro nodes modifier, and we'll be working on branch system node group, which will help us create the basic branch structure. So here I have a fresh blender scene, and I'll start by deleting everything in the scene. And I'll add, for example, simple plane because we won't be using the original geometry, so you can add whatever you want. Then I'll go to modifiers and add a new modifier, which will be geometry nodes. I'll hit new and call this geometry node setup, for example, three. And now we can start working on the setup. So let's go to Geomet nodes workspace, and we can start by deleting the group input because we won't need this object. The plan for the branches is that first, we will create a basic tree structure from curve lines, so it will look something like this. And then we will convert these curves to mesh using curve to mesh node. So the basic line or the basic curve line will be the trunk. So let's add a curve line and this curve line has two inputs. It has start and end. We can leave start as it is because we want it to start at 00, and the end will control basically the height of the trunk. So if we take a look at the trunk now, you can see that its length is controlled by this Z value of the end vector. So we can separate those values by using Combine XYZ, and now we can control this Z value individually. For the tranghd, we can add a new group input. So let's hit N to bring up this site menu. And I'll click this plus icon to add a new input, which I'll call Trangight we can set the default value to, for example, three and minimum to zero. Now to connect this, we can bring up group input, and we will connect this trunk height to the Z value. You can see that it's zero, so I'll go back to group input to modifier, and now you can see that we can control the height of the curve line with this input. There's also this little warning, and that's because the input geometry must be at the top, so I'll just move it at the top, and now we should be fine. So now we are basically done with the trunk for now and we can just select all of these nodes, hit Control J to bring up the frame, and I'll call this frame a trunk. Now let's start with the node group, which will split a point into more branches. So let's create a new node group. I'll do it by creating a re route to this connection, so I'll hold shift right click and drag over this selection. By the way, if you are not using a node wrangular add on, I really recommend it because it will speed up your workflow in geometry nodes and also the shading nodes. So again, we can do Shift right mouse button and drag, and we can get this readout. And now, if you have this reroute selected, you can press Control G to create a node group. Now if we hit tab, we are outside of this node group, and you can see that it just has one input and one curve output. I will rename this to split ends because it will split end points of the curves. And to go back to this node group, we can again hit tab and we are inside Node group. This node group will have few inputs. First of them is the geometry, which we already have here, but I'll rename it to geometry. The second one will be selection, which will select the points on which we want new branches to grow. So I'll get a new input and call it selection. Type of it will be bullying. And the last for now will be count, which will be a number of branches which you want to generate. So let's add a new input, which will be count, type can be integer, and we can set default to, for example, three and minimum to zero. Now if we go out of this node group by using tab, we will input some basic data to this node group. So first, we will, for example, want to create three branches. So let's add count to three. And for the selection, we only want to grow these branches from this endpoint. So usually the curve line has only two points where the start has index of zero and the end has index of one. So we can just use the index value and where it's equal, so we'll add equal to one. This should select only this endpoint. We can check it with a viewer, so control shift and leftmost button click. This will bring up the viewer, and now we can drag this bullying value to it. And here you can see that this bottom is black and the top one is white. The second method is to check it with attribute text. So here at the top, you can select attribute text, and you can see that here is one and here is zero. So now we have selection done, and let's go back to the node group. We will start by generating a basic branches. So let's add a curve line which will create a branches. And this curve line can be, for example, just 1 meter long. We want to duplicate this curve line depending on this count input, and we can do it, for example, by creating points. So let's add points, and we will create as many points as we want branches. So I'll plug this count into this count. And now you can see that we have three points here. Now to replace the points with the curves, we can use instance on points. And the input points will be the free points in our case, and the instance which we want to replace points with is the curve line. Now, if we view this instances output, you can see that we have three instances. But here in the viewport, you can see that there is still only one line, and that's because they are overlapping each other. So to differentiate between them a little bit, I will first move them on the x axis so they are angled a little bit. And I will also play around with this rotation. So we will rotate it around Z axis depending on their index. So they will be nicely distributed around the Z axis. To do this, I'll add combine XYZ because we only want to control the Z value of this rotation. I'll plug this vector to rotation. Now if we play around with the Z value, you can see that it's rotating around the Z axis. We want different value for each curve, and to differentiate between the curves, we can use index input. So let's add index. And if we plug this index right into the Z axis, you can see that it does something, and that's because for the first line, the input is zero, for the second line, the input, sorry, the index is one, and for the third line, the index is two. We want to distribute those lines evenly in circle, for example, like this. So when we have three curves, we want them to be like this. So between them, it's angle 120 degrees. And to calculate this angle, we can just take a full rotation, which is 360 and divide it by number of branches. So let's do that. I'll duplicate this group input and add a meth node. And because we are using radians here, we will need to use two Pi instead of 360 degrees. So we will be dividing two times Pi, which is 6.28 by the number of branches. And this will give us the angle between each branch. And to distribute them nicely, we can multiply the index by this offset angle. So let's add a multiply and plug it into the Z coordinate. Now you can see that the branches are nicely rotated along the Z axis, and they are nicely distributed around the circle. If we go out of this node group and increase discount, you can see that it works nicely. Let's replace the old approach to rotation with something a little bit better. So I'll set this curve line 0.2 001. Now they are again overlapping. But now if we play around with the rotation on the Y axis, you can see that they are rotating nicely and we can control the angle between branches and the Z axis. So we are basically controlling this angle with this value. We want to control this value from outside. So to add a new input, we can take this empty socket and plug it into Y axis, and I'll bring up the site menu and rename it to angle. We can also set sub type to angle, so the unit in the modifier is in degrees, and the default value can be something like 0.5 or something close to it. Now, if we go back from the node group, you can see that we can control the angle in degrees and also the count. So the next thing you would probably want to control is the length of these branches. But we'll actually do this later because now we should actually distribute those branches on the source points to see how it actually looks like. So let's use this source geometry. And we will use those instances again and instance them on the selected points. So we can actually duplicate this instance on points, and we want to instance on source geometry only where the selection is selected. So let's also plug the selection into it. And as a instances, we want to use this structure which we built from the curve lines. So I'll also plug the instances into this one. And now if I zoom out a little bit, you can see that we have some branches here. And if I go to main geometry node group, you can see that we have the trunk and the sorry, and the first level of branches. And now what we also need is to output the endpoints of these branches because we will want to use the split ends again like this and just reuse this geometry as a new source points. So to get the selection, we can first just realize all of those instances, and then those are again, the curve lines, so we can just take the points where index is one and use this as a selection. To get the index of each point inside the curve, we will want to use a spline perimeter, which will give us index in them. If we use the viewer, you can see that all of the ends of the points have one and the source points have zero. If we would use a index, we would get different values because this index is across all of those splines or curves, and that's not what we want. So we'll just use this pline perimeter index. To make a selection, we can just use a equal and where it's equal to one, this will be our selection. We can plug this result into the group output and rename it to selection. 5. Branch System Basics: Hi, and welcome back to three D trees with Blender geometon rods. Now, if we go out of this split ends, we can duplicate this node group and connect these output curves and selection. And now you can see that this created a second level of the branches. If we use joint geometry and join all of these parts together, you will see that we have a very basic tree structure, which looks pretty cool, but there are still many things which we need to add to the split ends. So first of it, you can see that those branches should be aligned to this curve, so it should look something like this, and they shouldn't be straight towards the Z axis, but they should be aligned to the source curve. So to do this, we can go to split ends, and we'll be controlling the rotation of those curve line chunks. And to get the right rotation, we basically want to align those to the tangent of the source curves. If we look at this from the side. So for example, this step, this is the source curve, and its tangent is vector pointing in this direction. And we want to align the Z axis of this group of curves to this curve tangent, so it will look something like this. For this alignment, we can use align rotation to vector, which does exactly what I drew here. And we want to align Z axis, so that's here selected to this vector. This vector will be the curve tangent, so let's bring up the curve tangent. And this should give us the right rotation. So let's plug this rotation into this rotation. And now you can see that the branches are correctly rotated along the tangents of the source curves. Now when we have this done, we can actually add a length input, which will control the lengths of those branches. So let's bring up the site menu and add a new input, which we will call length. And the default value can be, for example, one. First location where you can control the length of the curves is this one because here we control the basic curve line, and we can just basically control the length of these. The problem with this one is that all of the curves would have same length, and we want to have some variations and randomness in our tree, and this wouldn't look really natural, so we will avoid this one. The second place where we can control this is basically the scale. So if I play around with those values, we can also control length of the curves here. And we can even input different values for different lines, as you can see here is rectangular input, which means there are fields, and we can input a different value for each of them. But if I now at a random value here, and something 1-2. I'm not sure if it will be really visible, but if we maybe decrease the count to three. Yeah, in this one, you can see it nicely. You can see that it almost looks like it works, but those parts here at the second level are all the same, and they are just differently rotated. Want to have as many random things as we can. So to make this even more random, we will use a different approach. You can see that those parts here, here and here, those are the shortest parts, and they are all the same. So to make this even more random, we will do it after realizing the instances and we will move the endpoints of the curves randomly. You can stick to this solution here, but I'll show you even better solution which will give us more randomness. So let's delete this one at scale back to one. And now the thing we will do is we will take the endpoints of these curves and move them randomly along their tangent. To do this, let's add a set position note. And we will be only moving the endpoints so we can actually use this selection. So let's plug this into selection. And now if I move it, for example, on Xxs, you can see that it's moving all of the branches, which means that we can control those endpoints separately. The way we will randomize this is that we will get a tangent of each branch and then just randomize it in some range to make it nicer. So first, now we know that those points are 1 meter from their source. So this is one because this end point is on Z axis one. So first, let's reset those points back to those source points and then pick random value in the direction of curve tangent to displace them back. So let's add a curve tangent. And first, we can normalize this, even though this is probably normalized, we'll normalize it. And then if we scale this and plug it into offset, you'll see that we can control length of these curves. If we set it to zero, they have same length as before. If we set it to negative one, you can see that they all collapse into one point. Now, if we add value to this vector, we can control the length of it using the same technique. So let's duplicate the scale value and add it to this original. And we'll plug this result into the offset. Now if we set it to zero, you can see that all of the branches have length zero. And as I increase it, for example, to one, they are back to the original position, but now the controls make actually sense. So when it's one, their length is one, and when I set it to two, their length is two. The nice thing is that there is rectangular control. So there are fields and we can control each branch separately. So if I now plug a random value into this one like this, you will see that those branches have different values or different lengths. You can see that there's this short one and you can't find this short one in the different parts, so you can see that it's truly random. So now to control this input, we can just use the length input which we created and connect it to scale. By default, you can see that it's zero, but now we can control those lengths. And from here, we are also able to plug a random value into it and you can see that it works for all curves separately. The last thing which you would like to add to this node group is to randomize a little bit this distribution in circle because in some cases, this doesn't look real good. For example, if there are only two, you can see that it's straight like this, it's straight, and we want to randomize this a little bit. So let's go to split and node group, and we control this rotation on Z axis here, this combine XYZ in this Z socit. To randomize it a little bit, we will add a value to this. So let's add a add node, and we will be adding to the original value. Now if I plug it into Z axis, you can see that we can basically control the rotation here. We want the rotation to be different for each curve. So we'll use a random value. And if I plug it here, we want this to be, for example, between negative one and positive one. And we also want different seat for each of them. So as a seat, we can, for example, use index of these, and now you can see that they are different. In some cases, what could happen is that all of the branches would be at the same position. So let's say we have three branches like this, and they can rotate like in this direction and direction. So this could end up something like this. So the way to remove this one is that we will limit this randomness in some parts. So basically, we will limit this branch in this part, this branch in this part, and this brand is this third part. So the values we want to input to the random value are basically the offset angle divided by two. So this will give us this angle, and we will just multiply it by negative and positive one, and this will give us the range. So this division here gives us this whole angle, and we will first divide it by two to get half of it, and then we can multiply it by positive and negative 0.5, which should give us those limiting values. Now, if we plug those values into minimum and maximum of this randomness, you'll see that it works nicely. And we can also increase the count. And if we look from the top, you can see they are nicely randomized. To make this a little bit more narrow, for example, we can even divide it by three to get more narrow limits, and I think I'll leave it on freeze so they can be touching each other. All right, the last part is that we'll be adding a seed to this node group because we want to be able to control set of all of these random values. So let's add a new input and connect it to this ID. And I'll just add read out here, and we will rename this ID to seat. Let's also not hide this value, so uncheck this height value because that's by default for the ID. And now we can control it from outside, so you can see that we can control the randomness of the rotation on first level and also the second level. To test this, let's also at the third level. I'll again, use the previous curves and selection, and I'll join it into the spin and we can make this a little shorter. You can see that we have now a pretty interesting structure, which looks a little bit like tree. But in the next lessons, we'll add more details, which will make this even better. 6. Advanced Branch System: Welcome back to free D trees with blender geometry nodes. In this lesson, we will continue working on our branch system, and specifically, we will create a new node group which will combine those split ends and create a complete branch system. So first, let's delete those nodes because we won't need them anymore, and we will create a new node group. So I'll just connect this curve to output geometry at a rearut and with selected rear out, I'll hit Control G to create a new node group. I'll call this node group a branch system. So how this branch system node group will work is that it will have a few inputs. One of them will be selection, which will be the point from which we want to grow the branches. So let's say this is the trunk and this is the selection, and then we will plug it into Branch system. Input which will be in branch system is number of levels. So that is number of levels of branches. So for example, this is how two levels of branches look like, and if we add one more, this is three levels. So we'll be able to control how many levels there are. And later we will also add some kind of randomization. So there will be length of first branches and last branches, and it will interpate between those values and also how much the branches will split. So there will be minimal and maximal number of branches which will be generated on each so let's go into branch system node group and add some of the inputs. First one will be selection. So I'll add a new bullying input and call it selection. And the next important one is number of levels. So let's add a new input. This one will be integer, and we can call it levels. I think this is fine for now and we can start working on overall setup. So let's add our split ends node group, which will be the base of this node group. And basically how this will work is that we will use a repeat zone, which will have split ends inside of it, and the repeat zone will iterate depending on number of levels which we input to this node group. And after all of those iterations, it will create a final branch system. So let's add a repeat zone. And number of iterations will be levels, so we can plug levels into iterations, and output geometry will come from the stripe zone so we can plug this into output. The starting geometry will be the trunk which we input to this node group, so we can also plug the geometry into this geometry. And on each iteration, we will use this geometry, so we can plug this into split ends. We've given selection and join it with the previous geometry. So let's add chin geometry, and we will join it into the source geometry, basically. And we also need to store the selection. So let's plug this selection into this empty socket, which will create a new socket here with selection, and we will use this one as a selection for next iteration. So for the first iteration, this will be selection from group input. But later in next iterations, we want to use selection from those new branches. So we'll plug this into the output. Now if we go outside of this node group and increase number of levels, you can see that it starts growing. I'll also play around with the count, and you can see that we can control how many levels of branches there are. If we now check how many curves there actually are, you can see there are 16 splines, but that doesn't correspond with what we see because if we count this, we have one trunk, three branches, and each of them has three second level branches, which should add up to 13, but we have 16. The problem here is that this selection doesn't delete the previous selection. So to actually fix this selection, we will create a new named attribute, and that will tell us which points we want to expand in next iteration. And for old geometry, we will set it to falls, and for new geometry, we will set it to the selection. So let's add a store named attribute. And we can call it as for selection, the type will be Bolin, and for all of those branches from previous levels, this will be false. So we'll leave this on falls. And if we duplicate this and plug it into those split ends, we'll plug selection to the value. And now for the selection in next iteration, we can use this named attribute called S and plug it into the selection. Now if we increase the levels to two, you can see that we only have 13 splines down instead of 16. So that's working nicely. And now we can start working on connecting those inputs from split ends to this group input. So the next input of the split ends is count, and we actually want to randomize this input because we don't want it to be constant, but we want some variations here. So, for example, the first level would split into three branches, then four and then only two or something like that. So to do that, we will add a random value The type of this random value will be integers because count is also integer, and we'll plug those minimum and maximum values into group inputs. So we can use this empty gray circuit to connect it, and this output value will be plugged into count. You can see that now this connection is red, but we can fix this we can add a new variable into this repeat zone, which will tell us in which iteration we will be. And if we plug this iteration into ID or C, this will converge to constant and not a field value, and this shouldn't be read anymore. So we've selected repeat zone, hit N, and go to node, and we will add a new input, which I'll call I as iteration and set type two integer. And at the start, we want it to be, for example, zero, and then in each iteration, we want to increase this by one. So let's add at math we will add one to it and store it for the next iteration. Now this will be incrementing every iteration. So that means it will be different for each iteration, and we can use it, for example, for ID, and now you can see that the value isn't filled anymore. And that created something strange, but that's because the minimum is zero and maximum is 100. If we change this to let's say, two to five, you can see that on first iteration, this split it to five branches and on the next one only 23. We also want to be able to control the seed. So let's also connect the seed to the group input. And I'll just rename those Min and max to Min split count and max split count. And also move set to the top of the group input as always. So now the number of levels is randomized and the next input is length. Further length, we will also create some randomization, so we can duplicate this random value and set it to float. And if we now plug this random value into this length, you will see that each of the branches have different length, and that's what we exactly want. For the sad, we can plug the seat from group input to this seed and we can leave ID as it is because by default, it picks index, which is fine for this purpose. For the min and max values, there are few options how we can control this. And one thing I would like to do is I want to make this dependent on the current level of iteration on which we are. So we'll be able to create, for example, long branches in first level and then shorter branches on the last level. And we will also want to randomize these a little bit, so we will add some kind of randomness. So let's add a first input, which will be first branch length, which will set a length of branches on first level, and we can set default to one and minimum to zero. And I'll duplicate this and rename this to last branch length, which will control the length of last branches or basically branches in last level and set it, for example, to 0.5. The last input for the branches will be branch length randomness, so let's add that as well. And we can leave those default values as they are. So now to calculate length of branch on each level, we will use a map wrench and also this I value which we used for ID for the randomization. So let's add a map wrench. And we will be remapping this I because it's going from zero to number of levels minus one. Or in this case, we can actually increase it to the starting value to one, and now this will go from one to number of levels. And now we can just remap this I value with map wrench from one to number of levels. And the range to which we want to remap this will be from first branch length to last branch length. This means that when the I is one, which means we are on the first level, the output of this map branch will be first branch length. And if we are on the last level, which is where the I is levels, the length of branches will be last branch length. We will use this value for the randomization, and the way we will randomize this is that we will add a random value to this base length in range of minus randomness and plus randomness. Basically, if I visualize this, let's say here is this map range value and we will randomize it in a range where this is L minus randomness, and this is L plus randomness. So if the R is something small, it will be in a small range between the L, and if it's larger, it will have more variations. So that means that the minimum of this random value will be this map ranch minus branch line randomness. So let's subtract this from the map ranch. And the maximum will be map wrench plus randomness, so I can duplicate this with Control Shi D and just change type to addition. Now, if we plug those to minimum and maximum and go outside, you can see that we can control the levels depending on their level. And if I increase the levels, you will see that if I change first branch length, it's only changing the first level and also the other ones, but the biggest change is on the first level, and we can also control the last branch length as well as branch randomness. Right, so now I think the branch system is ready for the next usage. We can also play around with the inputs, and you can see that it's generating pretty nice three structures. And the last thing which we can do is we can connect those inputs to the main group input and also create a panel which will control the branches. So let's add a new panel. I'll collate branches. And now I will bring up a group input, and as always, use this empty socket to create those new inputs. And because if we connect this to the socket, it will use the current value as a default. So I'll just set some nice default values here. So something like this. And now I will create all of those inputs in the group input by just dragging this empty circuit into all of them. When all of the inputs are created, I'll just move them into dright panel, which is the branches panel. And I'll also move seed to the top of the inputs and hide those on sockets with Control H, for example, now it's looking pretty good. One more thing which we might do is clean up this tree a little bit. So I'll just use different group input. So this isn't that messy. And just reconnect those inputs to their own group inputs. Now, when everything is finished, we can go to modifier step, and you can play around with this basic tree structure with all of those inputs. One last thing which I forgot to add is controlling the angle because we forget to this one. And with this angle, we want to control, actually, how spread the overall branch system is. So let's also quickly add a new inputs for these for this, we will just pick a base angle and then the randomness, and it will work the same way as the branch length, but just with one basic angle. So let's add first input to angle and second one to angle randomness. I'll duplicate this group input, and we'll use the same technique as here. So I'll just use this random value, use this one, this sat, and we'll just add and subtract the randomness from basic value like this and plug it into minimum and maximum values. This will generate the random angle, and we can plug it into the angle. You can see that now it's all flat, but that's because those inputs are set to zero, so I'll just increase it a little bit. And we can also set the sub type of these two angle so they are in degrees. The last thing which we should do is connect this seed to our global seed. So I'll just connect seed from group input to split ends. And to finish it, we will connect those two inputs to the global group input, again, with this gray, sock it and move them into branches panel. 7. Internal Data: Hello, and welcome back to free D trees with blender geometon nodes. In this lesson, we will implement internal data which we will be using for distributing our leaves and also fingering out radius of each branch for each point. I have already explained those data in introduction to branches, but I'll shortly go through them. Both of those will be attributes which will be stored for each point, and first of them is length. Which at the start of the root is zero, and then it increases depending on how far from the root we are. So, for example, it can look something like this. And then we will also implement the inversion of this or opposite version, which will be called length from end. And this one will be the same, but in the opposite direction. So at the ends of the branches, this will be zero. And as we get closer to the root, the value will be increasing. The length from end will be used for distributing the leaves at the ends of the branches. So for example, we can set the value to zero point or 1.5, which can be somewhere here, and the leaves will be only distributed at these branches. And the basic length will be used for calculating the radius of the branch mesh. Alright, so let's get into geometry nodes, and we'll be implementing both of those inside branch system. So let's go to branch system. And the first one which we want to use is the length because that one will be a little bit simpler. So we'll be storing those attributes. So first one, we can actually store some basic length for the trunk. So I'll add Sterne attribute. It will be float for each point, so the default values are fine, and the name will be length. For this one, we will use a spline perimeter, which will give us length of each point. And if we visualize this, you can see that it's zero at the bottom and two at the top. Now if we go to branch system, the way this will work is that, for example, in this first level, I'll just decrease this. In this first level, this source point has length of two. For all of those points, we will add a length to this basic value, and this will give us, for example, if this curve has length of one, it will create three at this point. So the length will be implemented inside the split ends because we can do it here. So I'll go to split ends and we will be storing here at the end after displacing the end points depending on the length. So I'll add a store named attribute, set name to length. And the length will be the current length of the curve plus the length of the source point. So we'll add a value to this one, and the value which we will use is the length of the source point. So we will capture it before instancing the curve on it. So let's add capture attribute. And we will be capturing the length. So let's also add named attribute, length. We will capture it like this, and then we will plug this value into this addition, which means that, for example, if this point has two, this curve has length 0-1, those values will add together, and we will get two here at the bottom and three here at the top. So if we store this into named attribute, we can now visualize this at the end of this repeat zone, so I'll bring up named attribute. And now you can see that those points have a little different values. Maybe I'll visualize this at the end of this branch system that will be the best. And we can also increase number of levels and make the branches more visible. Now if we visualize this, you can see that this source point has attribute length zero, then this value is somewhere around three. And there's 3.7, 4.7. All right, I think I made a little mistake inside the split ends. Here in the addition, there must be this spline perimeter and the spine length, which I used before because this spine length will give us only the length of the curve, but we want length on each point. So we need to use this spin perimeter. And now if we visualize those values, with the greater then, for example, so I'll at greater then and disable this attribute text. You can see that as I increase this value, all of the branches get black, and to make this even more visible, we can resample those curves to more points, and now you will see this nice border between black and white, which is going along the branches. So that's for the length. Now we want the opposite attribute which is length from end. This one will be a little bit trickier, and that's because the way we build the branch system is that we start from the trunk and then continue to ends. But the best scenario would be that we would start from the ends and then go to start, but that's a little that will be very complicated. So we need to figure out a way to calculate the length from the ends. The way we will calculate this is that for the trunk, we will store the length in opposite direction, so length from end. So at the top, it will be zero, and at the bottom, it's two because this one will be the end. And here at the bottom, the length from end is two. And then on each iteration, we will take the length of the next branch. So let's say this one is one and add it to all of those points. So this one will be zero plus one and two plus one. And for this curve, we will again store the inverted length from end. So here will be zero, and here will be one, which corresponds to this one. Now, if we do this for each level, again, this one has one and we will edit at this length to all of the previous points. So this one will be two. This one will be one, and this is two plus one plus one, which is four. And you can see that this in each level, it builds up the distance from end. And let's say this is 0.5, it'll be zero, 0.5, one plus five, 2.5 and 4.5 and you can see that at the end, we should have this value which corresponds to length from end. We will also implement this inside branch system, but we won't go into split ends, but we also stay here in the repeat zone. And as before, we will first start by storing this attribute for the main trunk. So let's use another named attribute, but we'll call this one length from end. And this one will be inverted length. So to get the inverted length, we can take the overall length of this curve and then subtract this perimeter from it. So let's also at sorry, spine length, which will give us the length of the curve. You will subtract this length perimeter, which is going from zero to length for each point and start for the length from end. If we visualize this value, you can see that it's zero here at the top and two here at the bottom. Now in branch system, we'll do exactly what I explained here. So for those new curves, we will just store the inverted length. So I'll again, use this surnamed attribute, set it to length from end. The type will be flowed, and we will use the same value as we used here. So we will take a spline length and subtract the spline perimeter Like this. This will again give us the inverted length factor, and we'll store in length from end. And for all of the previous levels which is this socket, we will add a maximum length of these nu curves to their length from end. So I'll duplicate this one and we will take their previous length from end, which we'll take with named attribute and add a length of these curves to this length. The problem here is that those new curves might have different lengths, and there isn't really a way to get each different length to the previous levels. Let's say we have the strunk and then it generates two branches. One is shorter and one is longer. So this previous level has, let's say, here is one and here is zero, and we can't figure out the length in this point because from this point, it's I don't know, let's say, 0.2, but from this end, it can be like one. So we don't know which value we want here. And in my opinion, the best thing to do is we can add or we can add the maximum length of these curves. So because this is 0.2 and this one is one, we'll use this curve which means that this point will have distance one, and this will have one plus one, which is two. So to get this maximum length, we can just take this geometry and use attribute statistics. And we will want the maximum length of the curves. So the domain in which we'll select will be spine, and the attribute we want to use is this length from spine length. So I'll duplicate it and plug it into attribute and make some space here. And basically, we'll just take this maximum and add it to the previous length from end like this and store it into length from end. So to sum it up, for the new curves, we will store the inverted length factor, and for the old curves, we will just add a maximum length of these new curves to their previous length from end. Now, if we visualize this here, I'll again use named attribute length from end. It's here. And we can again use the greater then because with that, we can nicely visualize this. And as I increase this, you can see that this value nicely goes from the ends of the branches to the root. You can see that if it's zero, all of them are white, and as I increase it, the ends are black, and it's going towards the root. 8. Roots: Welcome back to free D trees with Blender geometry rods. In this lesson, we'll continue working on our tree structure. Specifically, we'll be working on the roots. If you try drawing roots to our tree, so something like this, notice that this shape down here is very similar to this up here. And that's exactly what we will use because we will reuse our branch system node group to create the roots with same technique. So let's go to Geometri nodes, and here we can see that in this part, we are creating our branch system, and we will add the same thing, but for the roots. So for that, we can duplicate this branch system node group. And if we take a look at our trunk, we will be using this one as well, but we don't want to grow branches from the top part but from the bottom part. So let's plug our geometry to geometry here. And if we now output this branch system, we can see anything. But if we put our original selection here, we have a very basic tree, same as before. First thing we need to fix is that we want the branches to grow from the bottom. So instead of point with index one, which is up here, we want to grow them from point with index of zero. So we can duplicate this equal with Control h D and just change one to zero. And where this is equal to zero, it will create the branches. Now you can see that it creates the branches, but there is a problem because they are growing in the wrong direction. We want them to grow in this direction instead of this direction. To fix that, the easiest way to do this is to just take the trunk curve and reverse it, which will reverse the direction of this curve. So let's add reverse curve and plug our trunk to it. And if we now plug this curve into geometry and this selection to the selection of branch system, you can see that the branch system created exactly what we are looking for, and those are the branches which are growing from the bottom of our trunk. Now what we can do, we can combine those generated curves with the branch curves. So I'll just join these geometries together. You can first just add a joint geometry and connect them separately and connect them manually or you can hold Control shift right click and drag over those two nodes like this, and this will generate the joint geometry and join both of these branches together. Now if we output this, you can see that we have a nice tree structure. The only problem now which we have in the setup is that this branch system contains the trunk curve, as well as the root system also contains this trunk curve. So that means that now here in this section, there are two same curves which are overlapping. We don't want something like this, so we need to get rid of one of those trunks. To get rid of one of these trunks, we can, for example, store attribute before all of those node groups for the trunk and then check where this attribute is assigned and we will remove this geometry. So for example, here, we will add a rear route, and we will add a store named attribute. For example, we can add a Bolin, we can call it, for example, trunk and set it to true. This means that now the trunk curve has this trunk attribute assigned. And in the branch system, we will add this attribute as well, but we will set it to falls. So let's go to branch system. And here where we are joining our new branches to the whole setup, we will add a store named attribute, and we will again store the trunk, but set it to falls. Now if we go outside of this branch system and check the named attribute trunk, you can see that this curve is true, but those curves are all false. So we can use that. And for example, I'll delete this trunk from the roots, but you can delete them from branches as well, but only from one of these. So let's add delete geometry, and where the trunk is true, you want to delete it. So I'll use it like this. Now if we view this, you can see that the roots don't contain the trunk, but those branches contain it. So together, it will give us the whole tree without any overlapping. Right. So now our curve system has roots as well, and we want to be able to control all of these parameters, which we can control for branches. We want to control them for roots as well. So for that, we will add a bunch of group inputs, and we'll be adding them with this empty sockit. So for the seat, we can use the one existing. So let's plug it into seat. But this will result that those both node groups will use the same sad, and we might get same results on them. So let's make it a little different. For that, we can, for example, use a MF node. I like to multiply at, and we will multiply this seed by, for example, 15 and at some random number, let's say 42. And now this will probably give us always the different sad than the original value. So now we have the seat, and now we will just connect all of these group inputs or sockets to the group input. So we will use this empty socket and I'll plug them like this. And now when all of those sockets are connected, we can hit to bring up the site menu, and I'll add a new panel which I'll call roots. To finish it, I'll move all of these attributes or inputs to this roots panel. All right, so now when all of the socits are connected, we can hide a new socuits with Control H and also clean this note tree a little bit. I will just group those nodes with Control J and call it remove duplicated trunk. And we can also rename this whole setup to branch system. Now we can go to Modifier and play around with our roots. So I'll set levels to something smaller and make them a little longer and also play around with the angles. We can also check if both of our attributes which are length and length from end are working correctly. So I'll just add a named attribute and length, and we will check where it's greater than some threshold value, and I'll hide those attribute texts. So as I increase it, you can see that it's going nicely from this point here to the branches, as well as to the roots. And to check the other parameter, which is length from end, you can see that it's also working really nicely. 9. Displacement: Welcome back to three D trees with blender geometry nodes. In this lesson, we'll be working on the displacement of our curve setup, and we will give this tree a little bit more natural look. So how this will work is that basically, we'll just take those curves and we will displace them with some noise textures. But before that, we need to be able to control how much geometry this tree actually have. We'll be controlling it with this resample curve, but we will give user option to control how much resolution we actually have. To do this, it's actually better to switch this type to length because that means that it will sample those curves to evenly distributed points, and it doesn't depend on the length of the curve. And we can add one perimeter to this node group, which will be the resolution. So let's add a new integer input, which will be called resolution. And we can set the default value to, for example, ten and minimum to one. If we bring up the group input, we can't really plug this resolution straight into this resample curve because those integer values are really high, and you can see that it doesn't really work. We want some smaller values here. But for the user, it's better to work with those integer values. So to calculate this length, we can use MF node and we can just divide some constant by this resolution, which means that if we increase this resolution, it will make this division smaller or the result will be smaller, and the geometry will have more points. So if we use 0.5, for example, you can see that now when the resolution is set to one, the steps between the points is 0.5. But if we set it to, for example, ten, the steps between the points will be 0.05. So for now, I will leave it like this, and we can work on the displacement with noise textures. To do this, we will be using a simple set position node. So let's add that. And we'll be using this offset input with which you can offset the tree in all directions. If we now add noise texture, for example, this color outputs three dimensional vector with values 0-1. If we plug this straight into the offset, you can already see that it does some kind of displacement. And if we play around with the scale, you can see that the tree is much nicer now. The problem is that the root of the tree isn't at 000, so that's the first problem, and the whole tree is kind of moved in this direction. That's all because of this color, which gives us only positive vectors, and we also want some negative vectors. To change that, we can use a map range and we can remap this vector because the color is vector from 000111 to negative ones to ones. This will result that this vector will also give us some negative values. And if we plug this into offset, now you can see that the tree is almost centered, and that fixes a little bit. But still, the center isn't exactly at zero, zero, zero. To change that, we can use one of the attributes which we are storing, and that's the length. If we view the length, you can see that the length is zero here at the center or at the root, and it's increasing towards the branches. We can use this value to multiply this vector, which will result into that this point will stay at zero, zero, zero, because if we multiply the vector here by zero, it will be zero. And as we go towards the branches, it will be multiplied by one. So if we take this length and multiply this vector by it, so we can use a scale for that. This will result in something like this. You can see that the branches at the ends are really distorted, but this vector or rose the starting point is still at zero, zero, zero. The branches here are very displaced because the length is much higher. And we want this multipler be one at the maximum. So for that, we can use a clamp which will clamp the value in some range. So if it's higher than the maximum, it will go back to the maximum. So if we clamp this 0-1, you can see that now this looks much better. We can also visualize this, and you can see that this clamp value multiplies those vectors by zero. But when it's somewhere here, they are already the original and they are multiplied by one. So now this looks relatively nice, and we want to be able to control how much those points are distorted. To do this, we can multiply this clamped value by some constant. So let's at multiply. And plug it into scale. Now if I play around with this value, you can see that I can change how much the noise impacts the displacement of the points. The second perimeter, which we can also control is very important is scale of the noise. So if you play around with the noise and make it smaller, you can see that the tree has much smoother distortion. And if we set it to something higher, you can see that it's very harsh and it's very detailed. To get the best results, it's really good to combine few of these noise textures together. So we will combine two of them, and we will want to use them in that way that the first one will have a very low scale, and it will create a displacement like this, so the branches will be very smooth, and then we will apply another noise texture which will have much higher scale and add those harsh details. So we can reuse the setup once more, and we'll just add those values together. The values which we want to control is this multiplication value and this scale. So let's add some group inputs. I'll hit N, and I'll add a new panel which I'll call displacement. And I'll add inputs for this first noise texture. So the first input will be noise scale one and noise power one. And I'll set default to something like 0.25 and power also 0.25, we can try it here how it looks. Maybe that's too small. I'll set power to one. And now for the second texture which you'll be using, we can just duplicate those and I rename them to twos. For this one, I'll use a scale of let's say one, and the noise power two will have a default value. But 0.25, for example. Now let's go to modifier and also reset these to their default values. And we can connect those inputs to this first setup. So I'll bring up group input and connect this noise scale one to scale and noise power one to this multiplication. I want to duplicate the setup, so I'll just select those nodes and hit Control G, and I'll just rename those inputs. This scale is great, and the second one will be Power. And we can call this node group branch displacement. And because we want to add one more displacement, I'll duplicate this and use different scale and different power. To combine these together, we can just add those vectors. So let's add addition and plug this resulting vector into offset. Now, if I go to Modifier, you can see that we can control the impacts of these both textures, and we can get some very interesting results. To ensure that those noise textures aren't the same, we can change this type in noise texture to four D and use this W perimeter, which is something like CT. So I'll plug this W into the group input and just move it up. And now outside of these node groups, I'll use the set. And again, we will get some different values from this seat with multiply Ed node. So let's add multiply ad. So first one, again, we can just use some random values. And I'll apply this first one to this W and the second one you can really just use some random values and they'll probably have different values for each seat. They'll plug this to the second W. We can hide those and also hide a new circuits with Control H. Now, as we change the seat, the seats of the noise textures will change as well. To finish this up, we can select all of these notes and call it displacement. Also this previous part, we can call it resolution. 10. Mesh Generation: Welcome back to three D trees with blender geometric nodes. In this lesson, we will start generating the actual mesh of our tree and also add some basic UV maps. So let's go to Geometri nodes. And the first thing is that to generate a mesh from curves, we will be using a curve to mesh node, so we can add that. And for the profile, we will use a curve circle for now because we want it to be circular. Now, if we plug this curve into profile curve and decrease the radius, you can see that we have not pretty nice, but we have some really basic mesh around our curve structure. For now, we can also check this fill caps so the ends are filled. And the first thing which we'll do is we will play around with the radius of the curve. If we add a set curve radius, you can see that with this note, we can control the radius of each point, and we can control them separately, which is very powerful. So for our tree, we want the radius here at the start to be somewhere around one, for example, and here at the end, we want it to be somewhere around zero, so it will be decreasing as it's going or as it's approaching the ends of the branches. To get this value, we can use our length attribute which we are capturing. So if we visualize our length, you can see that it's zero at here and it's increasing towards the ends of branches. The problem here is that the values are very high. Here at the end is something like 6.9, but the ideal value would be just one, and then we can just flip this attribute. So to remap this length from zero to this 6.9 or what the value is. We can just take the maximum length of these branches and divide the length by this. So for example, if the maximum length at these branches would be seven here at this point will be something like 0.95 or something like that, and that's what we are looking for. So to get the maximum length of these branches, we can use attribute statistics. So let's add attribute statistic note. And we want statistic of this length. So let's plug this length attribute to attribute, and we want to take this maximum. Now to convert this length to range zero to one, we can just divide it by this maximum. And if we now visualize this, you will see that here at the end is something like 0.99, and here at the start, it's somewhere around zero. So that's exactly what we are looking for. The only problem now is that if you take a look at the roots, the values at the ends aren't really one, but they are 0.27 and so on. And that's because the branches here at the top are much longer than the roots. But the roots are using the maximal length of the branches as well. So we need to separate these two parts and calculate this factor separately. For that, we will move this calculation into the branch system, and this will separate those two parts. So I'll just delete those nodes here, and I'll go to branch system, and we can calculate this factor at the end of the repeat zone. So here at the repeat zone, at the end of repeat zone, we will add attribute statistic node and we will take a length attribute. And just divide it by the maximum. So the same thing as we did before. And here we can just store this value in another attribute. So I'll add store named attribute, and I'll call it, for example, length factor, and plug this result into this attribute. Now, if we go back to the end of our setup and visualize this length factor, you can see that now the branches still have 0.99, but the roots also has something around 0.807, and they are very close to one. So that's nice. And for example, now, if we plug this attribute into the radios, you will see that the branches are thin here at the start and thicker towards the ends of branches. We want to flip this and we want the maximum thickness at the start and minimal at the ends. So to flip this, we can just take the math node and subtract this value from one. So something like this. Now you can see that the branches or the root is the thickest part here. And as we go to the end, they are thinner and thinner. Then you can also control the overall radius with the radius of the curve circle, and it's looking pretty nice. Currently, the fall off is linear. So if we draw a graph here, and here on the y axis will be the radius, and on the X axis will be the length factor. I'll just mark it like here. Currently, where the length factor is zero, the radius is one, and where the length factor is one, the radius is zero. So it looks something like this. In some cases, we might want the branches to be thinner earlier in the tree. So we want the curve look something like this. Or on the other hand, we want them to be thicker longer time as we go to the ends. So we want to we want it to look like this. To control this, we might use, for example, float curve where we can do exactly something like this. So if we add a float curve after this one, we can just play around with this value. Now you can see that if I put it under the linear function, you can see that the branches are thinner, and if I put it here, they are thicker. The problem here is that we can't actually control this float curve outside of this node group or outside of this modifier. So we need to get a different way to do this. So the way we will do this is we will use function X to the A where the X is factor or our length factor and the A is input variable which can be controlled by the user. Here it's visualized. So when the A or the exponent is set to one, the function is linear. But if I set it to something lower than one, you can see that the function goes more like this, which means that the branches will be more thicker. And if it's over one, you can see that it's going under the linear function, which means that they'll be thinner. So to implement this into blender, we can just take this value and use a Bower and the exponent will be value 0-2. So if we set it to one, you can see that we have the same results as we get with linear function. If I set it to something smaller than one, they are thicker, and if it's higher than one, you can see that they are thinner. 11. UV Mapping and Refinement: Hi, and welcome back to three D trees with blender geometry rods. You can go even more than two, and you get even nicer gradient. But that's up to, I will probably set maximum value to something like three and leave it like this. So to add some controls, I'll bring up the site menu, and the first thing which I'll add is the overall radius. Which will be controlling radius of this curve circle. I'll set default value to 0.15, and the second one will be radius fall off, which will be this exponent. So I'll add a new input and call it radius fall off. The subtype, I'll set it to actor because it will be in small range, so you can use that. Set Default to one and set it 0-3. To use these group inputs, I'll just connect them from the group input. Also the radius to the curve circle. Now, if I go to modifier, you can see that now I can control the radius of these curves and their fall off. We could also set those values separately for branches and roots. Then the best way would be to put those controls into the branch system as well, but I'll just stick to this version. So to clean this up a little bit, I'll just move this radius here and now we can call this group of nodes radius because we are controlling radius here. Now the next thing which we are not controlling yet is this resolution. One way would be to just edit to the group input, but we can do it a little bit smarter. We can just use this resolution input, which we already have and just calculate how many points the curve circle should have. So for the resolution, we are calculating here. And with this division, we get offset between two points. So I'll just duplicate this with Shift D and parent with TP, so it's not inside the frame and just move it here to the front. And basically, the curve circle looks like this, and we know what radius it has. So we know this R value, and we need to calculate how many points it will have. The information we also know is the spacing between the points this division. So we know, I'll just draw a bunch of points here, something like this. And we know how long this gap should be. Let's call it G as gap. And to calculate the number of points which fit in here, we can just use that the length of the circle is two by times radius. This will give us the whole length. And if we divide it by this gap, we should get the number of points which we need to create. So let's calculate this. I will just multiply this radius by two Pi like this and then just divide it by this gap value, which is here. And if you plug this into resolution, you will see that the value we get is 17.6, it automatically rounds, so we don't need to round this value. And now if we take a look at the geometry and for example, decrease the resolution, you can also see that it decreases number of points automatically, and we don't need to worry about it. All right, so the last part will be generating the UVs. To generate the UV map, we will need two variables. One of them will be increasing towards the ends of branches, and the second one of them will need to go around the branches, and this will generate our texture coordinates. So first, for this one, we can just use our length attribute because we have this already calculated, and it should be correctly calculated. So we can just use this one. And for the second axis, we can use a factor of this curve which you are using for the profile. So if you look at this circle and use a plain perimeter, which includes the factor, you can see that this factor is going 0-1 around the circle, and we can use this value for the UV. So we need to capture this attribute using before generating the mesh. So let's add capture attribute, and we will want to capture this factor for each point. And now after the mesh, we need to create the UVs. So let's add store named attribute. The UVs are type of vector and they are stored for each phase corner, so we'll set it like this. The name will be UV map. And the value will be a vector. So let's combine XYZ. And for the X value, we can use this factor, and for the Y value, we'll use this length. If we now visualize this, you can see that we have nice UVs for the tree. And the only issue is that if you look at this part here, you can see that here's zero and here it's one and it's going around. But then there is a quick transition back to zero. To avoid this, we need to make this a little differently. The problem which we are facing is that if we visualize factor of circle, so we can just use this and I'll erase that. You can see that the value is zero at the start point. And on the last point, it's something like 0.9 free free, and then it's quickly going towards the zero. The thing we would need is we would need to have one here as well from this direction and zero here from this direction. To get this, instead of curve circle, we can use spiral, which isn't a closed curve, but it has two points in this position. So let's add curve spiral. Let's use our calculated values. So for the resolution, we will use the same value. Rotations, we only want one rotation, so let's set it to one. Start and end radius will be the same. So let's plug the radius into both of these like this and we don't want I'll just visualize this. We don't want the curve to have height, so let's set the height to zero. Now you can see that this curve actually has one and zero at this point. There are actually two points and they are overlapping. And if we use this spiral instead of curve circle, we should get much better results. Now you can see that here at this seam, there is a harsh transition, which means that the UV maps are correct. So I'll just delete this curve circle. But now we have another problem and that that here at this position, there are overlapping points. We can check this that if we hover over this output, there are 35,000 vertices. And if we use merged by distance now there are only 32,000 vertices. So there are many overlapping vertices which we need to merge. If we now look at the UV map with the viewer, this one, you can see that again, we have this harsh transition which we don't want here or this quick transition 1-0. And to fix it, we will replace this surnamed attribute with just capturing this vector. So I'll remove this and add a capture attribute. We want to capture this vector which stores our UV map, and the important thing is to use a face corner. Now, if we visualize this UV map after the merge by distance, you can see that now it's working correctly, and because it's after the merge by distance, the overlapping points are gone. So to finish this, let's store this attribute for the face corner and call it UV map, and we will just connect this captured attribute to it. Now our UV maps are finished and we can select all of these notes and just call it mesh plus UVs, for example. Now to check if it works with some materials, we can use our materials, which you will get for free discourse. So to append those materials to the blend file, we can go to append, find the file with the materials, and there should be in material, there are two materials for bark. There's oak bark and secura bark, so we can append both of these. And now when we add set material, and if we set one of these materials, you can see that we have nice materials on our tree. To finish this off, we will add material input to our group input. So let's hit to bring up site menu, and I'll add a new input, which I'll call material and type two material. And we'll just use this material for group input for our branches. One more thing which you might want to control is the scale of these UV maps. And we can just do this by scaling this vector here before storing it. So if we add a scale, and play around with it, you can see that if I increase it, the textures have more resolution or they are smaller, and you can control that as well. So I'll just add one more input, which will be UV scale, set default value to one and minimum to zero, and I'll just plug this UV scale into the scale. Now, if we set it to one, you can see that we can nicely control scale of our material and change it very easily. 12. Leaf Distribution Basics: Welcome back to three D trees with blender geometry nodes. In this lesson, we will start adding leaves to our tree and add three different options to distribute them. So the three types of distribution of the leaps which we'll be implementing were already explained in one of the first lessons, but I'll go through them quickly again. So the first one will be distributing leaves all over our branches, so they will be everywhere here on the branches. The second type will be from end, which means that we will just take those branches and use some threshold value to control how far from the ends the leaves will still be. This option gives, in my opinion, the best results, and the last option will be controlled by the minimum Z axis or Z position. So we will set a threshold value and distribute leaves only on the branches or on the points which are higher than this threshold value. Start off, we will need some leaves on which you'll be testing our setup, and you can find those in the file which you will get for free with discours. I'll go to file, append, in the file with the objects, we'll go to collection, and there are few collections, and I'll include all of them except this collection. We don't need this one. And if we click Append you can see that this adds a bunch of objects to our scene, and they are nicely organized in those collections. There are two main collections for oak tree and sacara tree. For each of them, there are some different leaves. So for oak, there are three types of leaves and also the material which we applied in previous lesson. And for the sacara, there are two types of leaves. There are blossomed one and no blossomed one. And the last one, there are flower petals which we can later use, for example, for the particle system. So for now, I'll just hide both of these collections and let's start distributing some leaves. Let's go to geometry nodes. And the way we will pick between those three types which are explained will be through menu. So let's open a site panel, and first, I'll add a new panel, which I'll call leaves. And to pick between those three different types, I'll at input, which will have type of menu. I'll call it where because it will be controlling where the leaves are spawning. And if we now go to Modifier, you can see that this dropdown doesn't have any options. To add options, we need to connect this group input to some kind of menu node. To do this, we can add a menu switch, which is basically a node where you can add a bunch of options and then control it with this menu socuit. So I will just connect this ware input to this menu switch. And to edit those options, we will click on this menu switch and go to Node tap. And here we can edit all of the options. So the first option will be branches. The second one will be from end, and the third one will be Min Z for the minimum Z position. Now this menu switch can switch between those three geometry inputs. And the way we will do this is we will for each type, create a curves on which we want to distribute the leaves, and then we will just use this output, which will be picked with this ware and distribute leaves on that curve. We can also check that in the modifier, now we have those three options. We can pick any of them, and it should be picking one of those inputs. So to create the base curves, we will be using the curves of our tree, and I will be using those after the radius because we will need this radius information later when distributing the leaves. So let's take those curves, and the first option which we have here are the branches. That means that we only want curves which are branches, and we need to delete all of the others. So let's add the delete geometry. And now to figure out which curves are branches and which not, we can, for example, use length attribute, which we have here, and when the length is greater than length of the trunk because length of the trunk is only on the trunk, and then the lengths are higher. So when the length is higher than the trunk length, we should only get the branches. Need the opposite. So if we delete all of the points where length is less than the trunk height, we should get the branches. So let's get named attribute length. And if it's less than trunk height, we can also visualize this, and you can see that all of those branches below the trunk are white. But the problem is that some of the roots here aren't picked. That's because their length is longer than the trunk height, and we don't want any leaves on the roots. So to fix this, we can also here at this branches stem, we can store information if those curves are roots or not. So for this, I'll add store named attribute set type two Bolin and call it roots. And for those top one, those are my branches. So I'll set it to falls. And for those bottom one which are actually roots, I'll set it to true. Now if we go to this end, we will basically pick where the length is less than trunk height or if they are root. So we will at named attribute roots. And if this is true, we also want to delete them, and this should give us a better selection. Now, you can see that all of those roots, including the trunk are white, which means that it will delete all of those parts. So if we now visualize this, you can see that we only have those branches. So that means we have the first option done and we can plug it into branches. And now if we output this, now we have branches selected, so we have branches. But if we select something else, they are empty. So let's do those as well. For the from end option, we will again use DD geometry. And we want to delete all of the points where length from end is greater than some threshold. So for this, we need to add this threshold input. So I'll add new input to this group and call it length from end. And I'll set default value to, for example, one, and also reset it here. And now if we take named attribute length from end, we will want to delete all of the points where the length from end is greater than this length from end from group input, or if there are roots. Again, we will add this or value or it with roots. And now if we view this, you can see that we only have ends of the branches, and we can control it with this group input perimeter. So this part is done as well. And now the last part is the minimum Z axis. So for this one, we will also need a perimeter. So let's add a new input and call it Min Z. And again, we will be using delete geometry and we will delete all of the points which have position on Z axis below this threshold. So we'll take position. We will get only the Z position by separating XYZ, and if those are less than the main Z input, we will delete them. So it will look like this. And we can plug this third option to this menu switch. Now if we play around with those options, we should get those three types of curves on which we will distribute the leaves. Also, a quick tip if you have some rear routes below each other like this and you want to align them, you can just select them and hit to scale X on X axis, and zero, and this will align them on the x axis to one line. We can also group these nodes with Control J, and I'll call it leaf curves. 13. Advanced Leaf Placement: Hello, and welcome back to free D trees with blender geometry nodes. And now let's start generating some leaves on these curves. So to create the leaves, we'll be using instance on points. But first, we need to distribute points along these curves. The best way to distribute points randomly on curves is just to create a bunch of points and then you sample curve with random factor, and this will distribute them nicely. So first, let's add some points. I'll add, for example, 200 of them for now. And as deposition, we'll use a sample curve. So we'll be sampling those curves. We want to sample all of them so we can check all curves, and now we can just control this factor. For each point, we want this factor to be randomized. So let's add random value 0-1, plug it into factor. And now if you plug this position into those points, you will see that the points should be only distributed on the branches. You can see that they are changed depending on how we set those curves. But the problem now is that we don't actually know how many points we want because sometimes the parts will be very small and we don't want many leaves at one place. And sometimes there will be long curves, and we don't want large gaps between them, and we want nice number of points here. To calculate a great number of points, we can just take the overall length of all of these curves with curve length. So this node gives us the overall length of all of these curves. And now if we add a new input which we can call, for example, density, we can just take this length and multiply it by the density. This will result that no matter how long the curves are, there will always be similar density of the leaves. So if the length is something smaller, there will be just a few points, and when this is something high, the length, there will be many points. If we plug this multiply to count now and set density to ten, you can see that there are many points. But if we decrease or I'll set it to from end and you can see that the points are always relatively nicely distributed. All right. So now our points are nicely distributed. We can also group this and call it distribute point leaves, sorry, leaf points. And now we can finally instance some leaves on those points. So through this, we will add instance on points. For the points, we will use those points which we distributed. And for the instances, we will want to use some of the collections which we appended from the file. For this, we will add a new input where we will add the collection. So let's add collection and set Type two collection. I'll also move it up to the panel. And set some values here. So I'll, for example, pick the sakura leaves. And now to distribute those leaves from collection, we can just take the collection info out. For the input, we will use collection of our group input. We want to separate and reset children. And we can plug those instances into the points. You can see that now all of the leaves are facing the same direction, and also all of the leaves are on each point. So we only want to pick one. So through that we can check this pi instance. And we also want to rotate those leaves a little bit. So the simplest way would be to just create random value or random vector 0-2 Pi. And if we plug it into rotation, we have some relatively nice leaves. If we now combine this with our branch geometry, you can see that there might be several problems. I will set densities to something smaller, so it's a little bit more visible and also set radius full of something below one. This isn't probably the tree which you want to create, but I want to show you a little problem which we have, right? So for example, in this curve here there is a curve, and we are instancing the points straight on these curves. The problem is that the mesh is not on these curves, but it's around it because we are using a spiral or curve to create a profile around it, and we want the leaves to grow on this mesh and not on the curves. So to fix this, we need to offset this, offset this point by the radius of this curve. So the leaves actually grow on the surface and not on the inside of the mesh. So to do this, we will before points instancing leaves on the points, we will also set position of these points, and we need to take radius of this curve in the distributed point. So that will be the value which we'll be also sampling. So I'll add radius. And now this value is the radius at a given point. And if we take a look at this drawing, each curve have some vectors. One of them is curve tangent, which is in the direction of the curve, and the second one is curve normal, which is direction perpendicular to the curve tangent. So if we take this curve normal and scale it by the radius, we should get a right offset for the points. So if you plug this point into the offset, and the important thing is also multiplied by the overall radius of the branch. So let's multiply it by the radius from the group input. And now the leaf is you can see that it's on the surface of the mesh. It's not pointing the right direction. It should be something like this. We are almost there. To randomize this even more, we will take the normal vector and rotate it by random value. So if we visualize this, we have the branch, and it has a curve tangent and also the curve normal. In this direction, we are offsetting the leaves, but now it would affect that all of the points would be offset in same direction, but we want to randomize this, so some of them will be in this, some of them in this, and this direction. So to randomize this, we can take this normal vector which we scaled by the radius and use a vector rotation or vector rotate. Center will be 00, zero, and axis will be the tangent because that is the axis around which we are rotating. And for the angle, we can just pick a random value. So I'll add a random value and put it to 022 Pi. And if you plug this resulting vector into offset, the points should be distributed even more randomly. Now, I'll just clean up this math a little bit. So something like this. And we should also always connect the seed to our random values. So I'll connect seed from the group input to this random value and also seed to this random value. Now, if we put radius flow back to something more reasonable and set the density to something like ten, you can see that we have a very nice distribution of the leaves. We can also swap between different leaves very easily because there's this collection, and it's all working nicely. One last option or one last perimeter which we want to add is we want to be able to control scale of these leaves. So let's add two more inputs. One of them will be scale, default to one, and the second one will be scale randomness. The scale will be controlled simply here where we are instancing leaves on the points. And the way we will generate this is we will just create a random value, and we'll take group input, and the minimum of this random value will be scale minus randomness, and the maximum will be scale plus randomness. So you can just plug both of those value to the random value and also the seed. And now if you plug this random value into the scale and set it to default values, you can see that we have some variations here as well. If we also check all three types of the leaves, so branches, the leaves are all over the branches. From end, we can control how far from the ends of branches the leaves are and we can also control the minimum Xs, which might get handy in some types of trees. Everything is procedural, so we can play around with the seed, and always we get a very different tree. 14. Basic Particle System: Welcome back to free D trees with Blender geometry nodes. We will add one more detail to our tree, and it will be a very simple particle system which will simulate falling leaves from our branches. In this case, we will again be using objects from the free asset back which you will get for free with this course, and in this case, I'll use those small secura leaves, which will be perfect for this usage. So how this will actually work, first, we'll be using simulation zones inside the geometr nodes, which will allow us to simulate those falling leaves and some kind of physics. So first thing which we need to do is we need to add some points to our geometry. So we'll be using similar technique as we used for distributing leaves. We will use the same curves, but we'll just instance some simple points on them like this. And then in simulation zone on each frame, we will move them a little bit down, so it will look like they are falling and also add some noise to it, so it won't be just straight falling leaves, but they will have some movement or something like that. So let's go to geometry nodes, and I will be adding the points down here under the leaf structure. The important thing is that small particles will be falling from leaves for which we already have those curves on which they are generated. So we'll re use these curves and distribute some points on them. So we will use output of this menu switch, which is picked by this are attribute, and we will be using similar techniques as for the leaves. So we will add simple curve and we'll be sampling random curves from these and just assigning those positions to new points. For now, I'll add points node, and let's say we want to add four points each frame, so I'll set count to four. And now we need to check all curves because we want to sample all of those, and the factor will be random value. So let's add a random value 0-1, and plug it into factor. Now if we plug position into the points node and visualize this, you will see that we have some points here, and we can change the seat with the seat attribute. To simulate the falling, we will need the simulation zone. So let's add simulation zone. And this is very similar to repeat zone. So it has some geometry input. Then it does some stuff between those two nodes. In this case, this is done for each frame, and then there's this output geometry. So on each frame, we want to add four new leaves to our falling points, and we will do this by joining those four points to this existing geometry. So let's add join geometry, and we will join those four points. Now if we output this simulation zone, play the animation, you can see that we still only have those four points. That's because on each frame, those same four points are added, and they are overlapping each other. If I **** over this output, we should see that now we have 404 points because we are on frame 101. To make them variable, we need to control the seat and make it different for each frame. This, we can use scene time, which gives us the current frame. And if we plug this frame into the seat and reset the animation, we should see that new points are appearing each frame. They are gradually creating the shape of original curves. Now, you might want to add a different number of points for each frame. So for that, we might use a random value and just plug it into the count. But you can see that it's not possible because output of this random value is field, but these points need a constant value. So to get around this, we need to figure out the way how to distribute or create random points on each frame. The way we can do this is instead of those points node which just create points on given position, we can, for example, use distribute points on faces where we give it some kind of mesh, and it will generate points depending on density and seat. And this will result into different number of points for each seat. So we also need input mesh. So for that, we can use whatever mesh you like. I'll just use grid. And now if we visualize this, you can see that we have this is the grid, and there are some generated points, and on each seat, it generates different number of points. If it's the density to one, for example, you can see that sometimes there are two points, sometimes only one, and sometimes zero points. So that's pretty good. One more problem which we might face is that this doesn't depend on the length of those source curves, which means that no matter how long those curves are, we will always generate same number of points. We can fix this by controlling the size of this grid by the curve length, which means that if we have longer curves, it will generate larger grid and distribute more points because there will be more space. So through that, we can just use a curve length and plug it into X or Y axis. Now you can see that it's generating points on this large grid. And we can also control the density with the second size on Y axis. But I'll just stick to one, and we'll be controlling density with this density value. Now when we have appropriate number of points generated, we just need to distribute them on the curves. So we'll just use set position. And as a position, we will use this randomized position from source curves. Now you can see that if I play the animation, it's distributing random points across all of the curves. Right? So now, if I go through the animation, you can see that there are always four points, and that's because the seat of distribute points is still the same. So I'll plug frame to the seat as well. And now we should get some different numbers of points. I'll maybe decrease the density to 2.02, and you can see that there are three points, one, one, three, zero, two, so it's nicely randomized. Right. So now let's put those points back to this simulation zone and output this one. And you can see that we are getting more and more points as we play the animation. So let's give it a little bit of movement. For the movement, we can just use a set position and just give it offset on ZXs to something like negative 0.1. Now if you play the animation, you will see that the points are falling. That's because it always creates those new points and all of them are moved on the Z axis by negative 0.1. One thing which we should fix is that if we now play the animation, you can see how fast they are falling. But if I change frame rate of this project to 60, for example, you will see that they are falling much faster. That's because this offset is on 24 FPS done 24 times per second. But if we set frames per second to 60, it's done 60 times a second, and it's much faster. To control this, we can use this Delta time, which gives us time between two frames. And if we scale a vector by this value, So something like this. And I'll say this to negative one on Z Xs because this Delta time is very small number. Now if you play the animation, you can see that it's pretty slow. But if we change the frame rate, the speed shouldn't change, and it should remain the same speed. Right, so we can call this, for example, a gravity and we need to be able to control this gravity, so we will want to control this value on the Z axis. Through this, I'll just add combine XYZ, and I'll add a new group input, which will control this Z value. For the points, I will add a new panel, which I will call particles, and I'll add a new input, which I'll call gravity and set default to one. Because we want to input positive gravity, but this value needs to be negative, we'll first multiply this gravity input by negative one and then plug it into the Z coordinate. Now if I go to modifier and reset the gravity to one, sorry, I need to set this to multiply. And now we should get falling leaves or falling particles. I can also increase this and you'll see that the points are falling faster or slower. All right. So now let's give it a little bit of randomness. So the thing we will do is we will add some random value to this offset. And this random value will come from noise texture because the noise texture gives us nice smooth noise, and we can use that for displacing those points. So let's add noisetexture. We've already used noise textures for displacing our tree, and we did one thing, and that was remapping this color because this is vector and we want to use this vector, and we were remapping it from zero, zero, zero, one, one, one to negative ones to ones. So we get vector, which can also be positive and negative and not only positive. So this gives us random vector. And now, if we just scale this vector by some constant and add it to this gravity, you will see that we have very crazy points here. I will multiply this by 0.1, for example, now you can see that the points are more jiggly, some of them also stay in the place. So one thing which we might fix in this map ranch is that we don't want to control those points on the Z axis, but we only want to control the movement on the X and Y plane. So I'll just set those Z codins to zero, and now this map ranch will only give us random vectors on the XY plane. 15. Advanced Particle Simulations: Hi, and welcome back to free D Trees with Blender emetinRds. You can see that the points are falling with the same speed, and they are squiggly. If we set scale to something global, you might see that some of the points are grouping together, and that's because if the two points are nearby or in the same position, the same noise is applied to them and they then have the same path or same way. So to create a different noise texture for each point, we can switch this to four D, and this W is something like CD. So for example, we can just use index of each point. This index isn't actually really the best choice because the index might change throughout the simulation. So to fix this, we will store some attributes before the start of simulation for each point and then use them for differentiating between them. So I'll add store named attribute here after set position where we are distributing the points. And the first thing which we'll store will be something like index, so I'll call it and it will be integer. And I will use combination of frame and the index to create a unique number for each point. So for this, we can, for example, just use multiply and add. I'll multiply the frame by some constant, let's say, 21, and add the index to this. This should give us a different number for each point, and we can start in this I attribute. And later, we can reuse this named attribute as a seed for this noise. Now you can see that the noise is much smoother, and we want to be able to control how much this noise texture affects our points and also the scale of this noise texture. So let's add two new inputs. First of them will be noise scale, which I'll set default to one and minimum to zero, and second will be noise power, which I'll set default to one. Ctly if you look at the setup, the weird thing here is that the gravity is scaled by the Delta time, but the noise texture isn't, and this should actually be fixed. So let's first add those two vectors together like this and after that, we will scale this whole vector by this Delta time. Now this should be truly independent on the frame rate, and let's plug the inputs from group input, so I'll bring up group input and plug the noise scale to this noise and noise power to this scale vector math node. I will also reason those values. And you can see that we have nice falling particles. The problem you might see is that the points are generating all of the time, but they are never deleted, and that might cause some issues with the frame rate because there might be too many leaves and it would get very laggy. So to fix it, we need to at a function which would delete the points after some time of their life. So let's say we set a lifetime of each 0.2 seconds. So if the point is older or is in the scene longer than 2 seconds, it will be deleted. For that, we will store some attributes before the simulation. One of them will be start, which will give us the time when this point was created. The type will be float. And to store this value, we'll just use the seconds, which will give us current seconds, and we'll store it in the start attribute. The second attribute which we will use will be lifetime, and that will store how long this point should live. And now I'll just set it for 2 seconds. Later, we can randomize this, for example. So after the movement of the points, we will check if each point should be still in the simulation, and if not, we will delete it. So let's add delete geometry, and now we need to pick which points we want to delete. You will take the named attribute start. And to figure out how long it lives, we will just use current time and subtract this start from this time. So this subtraction will give us how long this point was existing. Let's say, for example, the start is 2 seconds and currently the time is 6 seconds. That means that the point the point is 4 seconds alive. And when this is greater than the lifetime, so I'll duplicate this and set it to lifetime. We want to delete this point. So we'll plug this result into delete geometry. And now if we play the animation, you will see that those points at the bottom are being deleted. That's because their lifetime is longer than their threshold lifetime and they are deleted. We can also randomize this lifetime. So for that, I'll add two group inputs. One of them will be lifetime, I'll set default to two and minimum to zero, and second one will be lifetime randomness. Which I'll set default to zero. And now just classic randomization. We will add group input, and the minimum of the random value will be lifetime minus randomness, and the maximum will be lifetime plus randomness. So this will give us the range in which we want the lifetime generate. And we will plug those two values into random value like this, and also we can set the seed from group input. And the ID to make it different for each point, we can reuse this I value which we are storing here in I, and I'll just rode it here like this. And this should give us a different value for each point. And if we now store it in lifetime, Yeah, there are some problems that's because our lifetime isn't really set. So I'll set lifetime to two and randomness to zero. So now each point should live 2 seconds. But if I set randomness to one, the point can live from 1 second to 3 seconds. Right? So I think our very basic particle simulation is done, and now the last part to make actual leaves, we need to use these points and distribute some objects on them. So for this, I'll use instance on points. And as the instances, we will use some leaves. So those will be in collection. And we need to first create a group input for this. So I'll add a new group input and collection, set type also to collection and move it up here. And now I'll just plug this collection from group input to collection info. I want to separate and research children, plug these instances into instance input, and we want each instance to be randomized, so I'll check this big instance. Now we can see anything because we didn't pick the collection. And the collection which I will use will be those flower petals. So I can hide this again, and I'll pick flower petals here. And now you can see that we have very basic leaves like this. There are a few problems. They are all facing upwards. So we would like to, for example, randomize those leaves. And the second thing that they all have same scale, so we want to randomize this a little bit. First, let's fix the rotation. And first thing which we might do is we can just plug a random rotation to this rotation socket. But to make it a little better for rendering, for example, we can rotate them so they face the camera always, and you can always see the whole leaves, which might get very handy if they are very small, they might not be visible all the time. So this might fix that and to figure out the rotation, how it will face the camera, first, we need to camera object so we can get active camera object, which will give us the current active camera. To get location, we will use object info and use this location. And you can see that those leaves always are facing the Z axis. So we'll want to align the Z axis to the direction to camera. To get direction to camera, we'll just take our position and subtract it from a location of the camera. With vector math. So this gives us this direction vector. And now we can just use align rotation to vector because we want to align our Z axis to this vector, so I'll plug it into vector and rotation. And now, this looks a little weird. That's probably because I don't have any camera in this scene, so I'll add a new camera. And you can see that as I move the camera, the leaves are facing to it and I can check it with this this one. You can see that if I view from any angle, I can always see the leaves. And last thing, we can also rotate them randomly around the Z axis. So through this, we can just plug a random value to this rotation, and I'll just use random value 0-2 Pi. And now they also should have some randomized rotation. Alright, so that's looking pretty good. And now for the scale, we will use classic approach. We'll just add inputs for scale and scale randomness and just calculate it based on those inputs. So first input will be scale, default one, minimum to zero, and the second one will be scale randomness, which will have default to zero and minimum to zero. For value in this range, I'll subtract randomness from scale, and for the maximum, I'll add those two values and just plug those two values into minimum and maximum of random value. And this should give us the right scale. We can also use seed from group input for the seed, and for the ID, we can use the I named attribute. So I'll add named attribute, I and plug it into ID. So something like this should work. And now we can plug this value into scale, and you can see the leaves are randomized. I will set scale to oh, yeah, the scale is on one. I'll set scale to something like 0.2 and random as to 0.1. And now we have those nice small leaves. I will decrease the gravity, so it's a little slower. And the last input which we forget to add is density. So let's also fix this. The points are distributed here in this distribute on faces, and we want to be able to control this density. So I will add a new input, call it density. Sent devot to something like 0.5, and I'll plug it into this density input. If we now reset this, we have many points here, and I might increase the scale of the noise a little bit. And if I want just a few leaves, I'll set it to 0.05, but I still have many leaves. I'll decrease this even more and increase the lifetime. Now you can see that we have some pretty nice leaves. And to combine this with the original tree, I'll just add the joint geometry and just plug those two things together. And now what we have is this beautiful tree with falling leaves.