├── resources ├── Leaves2.png ├── ItalianCypress.png └── tree-leaf-texture-plant-green-transparent-png-1407608.png ├── documentation ├── Branches.jpg ├── MainGif.gif ├── SecondaryGif.gif ├── ApplyingGravity.jpg ├── BranchAlingment.jpg ├── DistortingCurve.jpg ├── LeavesAlignment.jpg ├── RandomizeTree2.jpg ├── RandomizeTree3.jpg ├── RandomizedTree4.jpg ├── RandomizedTrees.jpg ├── ItalianCypressTre.jpg ├── DetermingBranchLength.jpg ├── DeterminingThickness.jpg ├── GettingForwardFromEuler.jpg └── CalculatingDensityAndCappingAtWhichPointBranchesStart.jpg ├── LowpolyGeometrynodeTree.blend ├── LowpolyGeometrynodeTree.blend1 ├── LICENSE.md └── README.md /resources/Leaves2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/resources/Leaves2.png -------------------------------------------------------------------------------- /documentation/Branches.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/Branches.jpg -------------------------------------------------------------------------------- /documentation/MainGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/MainGif.gif -------------------------------------------------------------------------------- /LowpolyGeometrynodeTree.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/LowpolyGeometrynodeTree.blend -------------------------------------------------------------------------------- /resources/ItalianCypress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/resources/ItalianCypress.png -------------------------------------------------------------------------------- /LowpolyGeometrynodeTree.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/LowpolyGeometrynodeTree.blend1 -------------------------------------------------------------------------------- /documentation/SecondaryGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/SecondaryGif.gif -------------------------------------------------------------------------------- /documentation/ApplyingGravity.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/ApplyingGravity.jpg -------------------------------------------------------------------------------- /documentation/BranchAlingment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/BranchAlingment.jpg -------------------------------------------------------------------------------- /documentation/DistortingCurve.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/DistortingCurve.jpg -------------------------------------------------------------------------------- /documentation/LeavesAlignment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/LeavesAlignment.jpg -------------------------------------------------------------------------------- /documentation/RandomizeTree2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/RandomizeTree2.jpg -------------------------------------------------------------------------------- /documentation/RandomizeTree3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/RandomizeTree3.jpg -------------------------------------------------------------------------------- /documentation/RandomizedTree4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/RandomizedTree4.jpg -------------------------------------------------------------------------------- /documentation/RandomizedTrees.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/RandomizedTrees.jpg -------------------------------------------------------------------------------- /documentation/ItalianCypressTre.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/ItalianCypressTre.jpg -------------------------------------------------------------------------------- /documentation/DetermingBranchLength.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/DetermingBranchLength.jpg -------------------------------------------------------------------------------- /documentation/DeterminingThickness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/DeterminingThickness.jpg -------------------------------------------------------------------------------- /documentation/GettingForwardFromEuler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/GettingForwardFromEuler.jpg -------------------------------------------------------------------------------- /resources/tree-leaf-texture-plant-green-transparent-png-1407608.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/resources/tree-leaf-texture-plant-green-transparent-png-1407608.png -------------------------------------------------------------------------------- /documentation/CalculatingDensityAndCappingAtWhichPointBranchesStart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRCSS/Trees-With-Geometry-Nodes-Blender/HEAD/documentation/CalculatingDensityAndCappingAtWhichPointBranchesStart.jpg -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Shahriar Shahrabi 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 4 | to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, 5 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 9 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Trees in Geometry Nodes 2 | ================= 3 | 4 | The repo contains some nodes for generating trees based on splines and curves. It was made using Blender 3.2.0 Alpha. It will probably work with newer versions, but since Geometry Nodes have switched to Fields, you need to be at least on a version that supports fields. 5 | 6 | The example below is a single tree spawned on a surface: 7 | 8 | ![](documentation/MainGif.gif) 9 | 10 | You can also draw the trees yourself using the curve tool! 11 | 12 | ![](documentation/SecondaryGif.gif) 13 | 14 | You can also see the node in used for this model here: https://skfb.ly/osLOY 15 | 16 | Newly added, I also adde a generator for an autom forest, with procedural material for the woods, and randomized colors for the trees: 17 | ![](documentation/RandomizedTree4.jpg) 18 | ![](documentation/RandomizeTree3.jpg) 19 | ![](documentation/RandomizedTrees.jpg) 20 | ![](documentation/RandomizeTree2.jpg) 21 | 22 | Update: newly added, italian cypress trees 23 | ![](documentation/ItalianCypressTre.jpg) 24 | --------- 25 | KNOWN ISSUES 26 | -- 27 | 28 | In order to apply the geometry node and convert it to a real mesh, you cant use instances for the leaves. In my nodes I am using instances since they are faster to render, but you need to Realize the mesh before applying. This behaviour my change in the future. 29 | 30 | After applying the geometry nodes, the UVMaps get lost! The uv map is still there as an attribute, it is just not marked as UV Map any more. You can convert this on export to UV map with a [script](https://github.com/nothke/b3d-attribute-converter), use the [built in](https://twitter.com/Nothke/status/1497968184238002181?s=20&t=6z9rORmladSZnvb2EoiQpw) function to convert attributes to certain data, or just use the Attribute node in the shader editor to access the uv. This is a bug and will be fixed in the future. 31 | 32 | ---------------------- 33 | Code Structure 34 | -- 35 | 36 | The nodes are fairly cleaned up, so it should be easy to follow. The Low Poly Tree group has in it the generation of the main trunk based on a provided curve, branches and leaves. 37 | 38 | For the main trunk I figure out the thickness based on how long it has gone along the spline: 39 | 40 | ![](documentation/DeterminingThickness.jpg) 41 | 42 | Then I distort the spline based on a noise to give it a more organic look. There are two type of noise I use here, one which keeps the two ends of the spline fixed, the other only the begining fixed. Here is the one that keeps both fixed, the other is a simple variation of this: 43 | ![](documentation/DistortingCurve.jpg) 44 | 45 | Next is the creation of branches. The whole branch creation is fully procedural based on spline, and the function has a few nodes in it: 46 | ![](documentation/Branches.jpg) 47 | 48 | The main idea of the group is to use instances on Points on the trunk spline (or any spline, you can use the Branches node to spawn branches on branches on branches), to spawn a bunch of new splines, which get oriented, scaled and distorted in a way to resemble branches. I wont get in to the detail of distortion and determining branch thickness since we already covered those (only difference with thickness is that you take the thickness of the point the spline was spawned on as begining thickness). 49 | 50 | The first part is capturing all the different curve attributes at the begining to use for calculation. Also branches usually dont pop up everywhere on the trunk, but at a certain height. Here I am using the height of the mother spline to determine at which point branches should start poping up. 51 | ![](documentation/CalculatingDensityAndCappingAtWhichPointBranchesStart.jpg) 52 | 53 | Next is determining the branch alignment. If you have ever noticed, branches only grow in the direction of the light. This mean when we place our spline, we should make sure it is at the very least pointing upward-ish. To achieve this, after randomizing the normal of the curve at the spawn point, I project it on the xy plane. Then doing some cross product I tilt these up by a random value. 54 | 55 | ![](documentation/BranchAlingment.jpg) 56 | 57 | I have written a utility function to convert an eulor to a forward vector. You can create a rotation matrix out of an euler rotation, which if you multiply with the vector X (1, 0, 0), you would get the "*forward*" of that rotation. 58 | ![](documentation/GettingForwardFromEuler.jpg) 59 | 60 | The scale of the curve determines the length of the branch. Here I am randomizing that and also reducing the length of the branches the closer you get to the end of the base curve, since those branches would be the youngest. 61 | 62 | ![](documentation/DetermingBranchLength.jpg) 63 | 64 | Last on that front, I bring down the branches a bit down the further they go from the contact point, to emulate the effect of gravity as the branch grows and time goes by. 65 | 66 | ![](documentation/ApplyingGravity.jpg) 67 | 68 | 69 | 70 | Generating the Leaves is much of the same but instead of curves it is an actual mesh I spawn. This can be cut outs or modelled leaves. The only slight difference is how I determine the alignment there. 71 | ![](documentation/LeavesAlignment.jpg) 72 | --------------------------------------------------------------------------------