
Trees
A key element of a composition I'm building in Houdini is a tree. Much like mountainous terrain, trees are a classic target for procedural generation, so I'm not going to be presenting anything particularly ground-breaking here, but I've learned a great deal. If you're a Houdini beginner like me, I hope this article helps you towards your own 'aha' moments.
L-Systems
Houdini ships with a Node supporting L-system syntax to generate connected line segments. On the surface, this appears to be an ideal way to start building trees.
You can get tree-like results very quickly with this method. But producing a particular tree shapes requires progressively more complex syntax. Because L-system syntax is basically just a long string, it takes more and more time to unpack what's going on each edit.

Syntax-aside, you are limited by the bounds of what L-syntax can do. I had ideas about growing self-avoiding branches based on light access that was never going to be achievable here.
Python
For some reason, I got it into my head that of course a VEX wrangle node wouldn't be able to create geometry. Modifying an object while you're iterating over it is a classic conundrum in programming. The general solution is to copy your entire input.
Because of the potential size of Houdini's inputs, an assumption crept in about how I though wrangle nodes worked. There's no way they'd be copying the inputs, I thought, so there must be no creation/deletion in VEX.
Anyone with Houdini experience, particularly with Compiled blocks, will know just how much I was misunderstanding how Houdini works.
At this point, I'd like to make a special mention of this (often cited) blogpost by Toadstorm. This is one of the most informative Houdini blog posts I have read up to this point, and helped clarify a number of questions that had been building in the back of my head about how Houdini worked under the hood. His other blog posts are also inspiring (I mean just look at this), so a huge thank-you to Toadstorm for helping me get back on track.
TLDR: I went away and wrote a huge amount of Python, and got some good results, but oh lawd was it slow, being entirely single-threaded and all. In my search for alternatives I discovered that of course you can create geometry with VEX.
Oh well, I guess I was getting a little rusty with Python.
VEX Implementation
Another quick shout-out to another 3D Artist, Richard C Thomas. His article on optimising node-graphs for Houdini is required reading if you're processing large quantities of geometry (which is pretty much always when working in Houdini).
His insights helped me map Houdini's node graphs onto my existing knowledge of how best to multi-thread code. The general gist is that having an 'uber' node with all the VEX code in it is likely to execute slower, especially when tweaking parameters further downstream.
Here's the subnet that generates the line segments. It's been passed through the Polywire node to generate the mesh you see on the left.

Most of the work is done in the 'grow' node. The general idea is that we seed the graph with a single 'trunk' branch primitive. The repeat block loops over 'alive'' primitives X number of times (the life of the tree). Each iteration we:
- Spawn another branch if we've grown enough.
- Alter the branch's orientation to introduce noise or another desired goal (E.g light seeking).
- Calculate the position of the new 'head' of the branch and create new geometry for it.
- Consider killing the branch early by removing it from the 'alive' group
The remaining blocks exclusively iterate over points, calculating various properties that we could have, in principle, calculated during the 'grow' node. But as mentioned earlier, this actually ends up being slower, especially when fiddling with parameters.
Quaternions
The hardest part was keeping the orientations of the branches sensible. I only had a vague grasp that quaternions were probably the right choice, but lacked experience. So I bit the bullet and finally got around to learning them. I was pleasantly surprised to find how straightforward they are in practice - so if you're in the same boat as me, consider this a strong recommendation!
A hands-on approach worked for me. In a sandbox file, I used a CopyToPoints node to copy axis widget geometry to points with an 'orient' attribute, and used a wrangle node to modify. You can get a lot done with a remarkably small function of VEX functions. They key ones I used are:
Life/Generation Ramps
As a branch grows, it stores its current 'age' in each point it lays down. Additionally, it also tracks how many parent branches it has. Both of these values are then normalised to provide detailed control to a range of parameters. The obvious example is the radius of the branch, but you can also do things like tweak the frequency of the noise, or the spread of the branches at different stages of the tree.

Arriving at this approach took many iterations. Most of my early attempts resulted in wildly inconsistent parameter design, where each feature had a different way presentation to the artist. Unifying this while retaining the fine level of control is probably what I'm most proud of with this piece of work.
Leaves
Leaves were straightforward. I simply add points to a group based on a life-ramp, and construct an 'orient' attribute. Copy to points takes care of the rest.

Dynamics
My tree needs to move into response to a mild breeze - and I had this in the back of my mind from the start. I knew the wire solver would get in the ballpark, avoiding any kind of soft body dynamics, or bone deformation.
I spent a lot of time fine tuning the density and kangular parameters on each point of tree. I was happy to find that deriving these from the radius produced correct looking motion at different thicknesses of the tree.
Most of the time was spent tweaking the POP Force turbulence settings. Anything near the defaults tended to look synthetic. Trees create their own turbulence as wind passes through their leaves, which tends to contain much higher frequencies than the wind itself. I got much better results once I began putting some distance between the octaves of noise.
Gallery
While my composition only requires a single species of Himalayan pine, I had fun designing a system that could reproduce a variety of tree structures and shapes. Here's a few of the best ones. The source file contains these plus a few more.
Thanks to Pawel Olas at treesdesigner.com for making a freely available library of 3D scanned leaf textures.