In an effort to revitalize this blog, I thought I would attempt to document my search for the perfect tree. The current iteration of this process has been going on for about 2 years, and I think I recently had a break through, and am finally getting the results I want. At the moment at least.
Let's start out with defining some goals. These trees will be specifically for Shuvit 2.0, but also should work for my in progress racing game and other Godot projects. Target poly count per tree is super low, about 500 polys. Around 1200 is the max at the high end, but 500 should be the main target for most meshs. The meshs will be made in Tree It (would like to replace this non-free software, but it's what we are going with for now). Leaf colors will be set using a material that interprets rgbcmy values from an image texture, using Godot's instance shader parameters. Trees should have a 'dense core' that provide predictable blocking of what's behind it, in other words the standard tree silhouette should be fairly opaque, unless specifically designed otherwise.
So as far as the mesh goes, I've used Tree It for years, and know pretty much exactly how to get what I want out of it. That process is pretty much set. Make a trunk. Make a few mesh based branches. Then, add 2 sets of leaves. 1 set attached to the truck. 1 set to the branches. Tweak until happy. The layer of leaves on the trunk is essential for the 'dense core' and is my noteworthy tip here.
Ok, now on to the fun stuff.
I knew hand painting these was dumb. But if I remember right this first version was made about 2 years ago, after some really bad attempts at other style trees. I did them by hand as kind of a temporary alpha version. I didn't know then how long I would spend trying to improve on them. Trying my hand at some true freehand drawing:
Advancing to a proper leaf shape:
And my first attempt at some rgbcmy colors, to be set later in godot shader:
And it's overlay:
This version I had for a while, It is used in the current version of my motocross game. Obviously there is a lot of room for improvement here. The amount of alpha versus color in the image is way too high. I think this was having a pretty big impact on performance and they definitely failed the 'dense core' test without a lot of polys for the trunk leaves. Placing the leaves manually sucks, especially when each leaf has multiple 'layer' requirements.
And the version that ended up in Shuvit:
The thing about trees, at least for me, is they are always there, they always need work, with all of the good that brings, the bad is, sometimes you need to put them aside and work on other things. I wasn't really happy with these, but I needed to move on. I think these trees existed and hung around in my projects for 9 months to a year and half.
So phase 2. Enter Material Maker (https://www.materialmaker.org/) Great software. I use it for all kinds of stuff. It's made with Godot. I really wanted to use it here. And I really tried. The node it had to do what I needed doesn't do it in the specific way I need. To get the vein texture, I couldn't figure out a way to have it exclude the leaf underneath. Overall it was not fun to work with. Completely my fault, there probably is a way to do what I want, or it's open, so I could contribute the solution myself. I reached out on their discord, got some great help, but in the end couldn't get what I needed. Material Maker is great. You should use it.
Here is the ugly node setup I was using for this iteration of the branch/leaf textures:
Made a branch like this:
But I couldn't figure out a way to get the line splatter node to support coloring the leaves, and also layering the veins correctly.
So I decided to marinate on it a little bit. Put it aside and work on other things. The thing with this project is there are a bunch of different ways to do this. Like an infinite amount. I've mostly been using Gimp and Inkscape, but also tried a version in Blender and the Material Maker one. I spent a bit of time prototyping a script that just built an svg file from scratch.
Some time during this I built out the material in godot. Nailed down the correct blend between the trunk mesh and the branch texture. Decided on a wind type to standardize on and got it looking the way i wanted. Started adding some color sets and season support. Right now the coloring works like this: every tree instance get's it's own set of 6 (rgbcmy) colors. 1 for the trunk/branches, 5 for the leaves. Each month builds a different list of leaf set options. It picks 2 sets and blends between them at a random value. Setting a leaf transparent reveals the branch underneath.
For some reason I tried to make the leaves cartoonishly large for most of the trees in this iteration. That did not look good. At all.
Phase 3. Time to write my own leaf generator. Warning: we are about to get slightly technical with the Godot details here.
Each leaf species takes 3 input images. A basic outline:
A version with the vein:
And a heightmap version that will be used to create the normal:
Branch creation is a manual process right now. I know there are some algorithms for this, coming up with my own would be a fun project some day. This is fine for now.
To create a branch I add Path2Ds to a specific node. The program reads from this node and draws out the paths. The first path gets drawn thicker than the others:
For each branch, leafs are added at the specified spacing. The first branch allows for a starting offset for the first leaf. Each 'leaf' adds a node containing a TextureRect for each of the 3 inputs (the vein overlay, the color, and the height).
I added buttons to show the different outputs. Only the height is visible, not the normal that gets generated from it. That is kind of a design flaw on my part, if I am going to fix it, and I should because it is driving me mad, I probably need to restructure the whole project, at least completely overhaul the interface. Anyway, here is some turning the layers on and off:
There's a few options, there could be many more. 4 leaf types at the moment. I have some randomization in the spacing happening but it's not in the interface, and could use more work. The overlay color, greyscale, and the leaf scale all factor in the distance from the image origin. Rotation has some randomizing but I need to expose that in the interface. Here is some playing with the settings:
You get the idea.
This is what my ui for setting a tree in godot's editor looks like at the moment. It is still changing a lot. All options work, I just haven't really decided on some bigger picture infrastructure stuff. Trees have the ability to configure themselves on load, using the game's calendar system to detect the month and set appropriate leaf colorings. That is mostly disabled and I am just manually randomizing them at the moment.
A single 400 poly tree:
Here's some in game shots of a quick example area:
In this shot you can see the same tree mesh with different leafs set to transparent:
I don't think I am doing anything ground breaking or original here. This isn't a how to, but I haven't seen many people separate out leaf colors like this. From the moment 'instance shader parameters' were announced in godot I have wanted to use this setup. I'm really happy with the poly count I'm able to achieve and the style really came out as intended. As with anything though, it's a process. These aren't fully fleshed out and I'm already on to other tasks. I'm sure further iterations will happen.
Thanks for joining me on this journey. As always, it would be great to hear from you on my discord, mastodon or anywhere else. Long live blogging.