About Me and Woody3D

Published November 03, 2010
Advertisement
About Me
A couple of things you should know about me. Firstly I'm a solitary programmer. I work every day at my home office which makes me a little nerdy but actually quite personable. I have been married for nearly 10 years to Christa. Together we have raised Brandon for these last 16 years. We moved to Ann Arbor so Brandon could be challenged and make good friends. It was a success; he's a 4.0 in his sophomore year, likes advanced geometry, and just finished his first season of water polo.
In other words, I'm a solitary problem solver / family guy.
The next important fact is that I grew up in a house surrounded by a forest. My childhood consisted of staring at giant pines in the winter months and playing ninja, slashing branches, and generally wanting to be Mr Miyagi the rest of the year.
With that in mind, when I decided to create forests in 3D it immediately felt right. Here was a way for me to return to the forests of my youth and also share a part of my childhood with the world. Win Win!
Enough drama, here's how I did it.

A Fully Animated Tree
My goal was to make a tree where every part (leaf, stem, and branch) is animated in real-time for video games and simulation. Having some background in film, my first thought was to shoot video of tree branches, edit it to a loop, and play those videos on billboarded quads. The quads would then be attached to a geometric branch structure.
After some thinking I realized this method had merits but it was not at all practical to implement. Because I was aiming for platform independence the system could not reply on API specific video. Also the thought of all that video editing was too much. To maintain the desired effect I devised a way to embed the leaf and stem animation frames into a 2D texture. The animation would then be controlled via the texture coordinates. To do this I would need to create a tool to render leaf animations. This would later lead to 2 versions of the Leaf Painter application.

Resource Gathering
Christa, my business partner and part-time photographer, began collecting texture resources early on in development. Trunk and bark textures were photographed in the field, branches and leaves were a little more complicated to capture. For each branch on a tree we would cut small samples and quickly take them back to our small photo studio. The samples were placed inside a light tent and photographed with reasonable control over the lighting. Individual leaves were then cropped using Photoshop and stored as Targa bitmaps. This method is tedious and time consuming but works well enough.
e_2a.jpg
The Branch Geometry
Back on the programming side I began developing the mesh to be used for each branch in the tree. I developed a base mesh class and derived a branch mesh class. The base mesh provides an interface for allocating and modifying the mesh geometry. It uses a flexible vertex format allowing the user to define arrangement and size of vertex elements. The branch mesh class essentially creates a 3D tube object made of indexed primitives. The number of stacks and slices are defined at creation as well as texture tiling, normals, tangents, etc.
Now that I had the basic mesh to work with I created the branch object class. This class is responsible for shaping the tube mesh into a branch. Using a given number of knots (noise points) I could rotate the mesh vertices to follow the path of a spine interpolating along the knots. The radius of the branch at a given slice is controlled by a curve ranging from zero to radius max along the length of the branch. Early on many of my curve settings were linear resulting in a cone like branch shape. Later, after creating the curve editor, I could create more realistic branch shapes. Noise, distributed along the control points, is also controlled by a curve as are many other settings.
Next I needed to create a tree from the branches. Behold the tree class object; it allocates a list of branch objects during the tree creation phase. Branches are added in levels. The first level is attached to the trunks (level 0). Branches are placed along the length of the trunk given a set of placement parameters. Every branch level contains a randomization seed value for general settings and another for noise. Additional levels are then added. Weights are applied to each level causing them to grow towards a point or along a vector.
In the beginning all parameters were entered manually, this was before I developed the Tree Forge application. Currently all branches are created procedurally using parameter values and curves but my goal is to allow direct user control over branch placement and shape in the Tree Forge.
e_2b.jpg
Leaf Placement
The current leaf placement strategy is quite simple. Leaves are placed along the length of a branch given start and end points. A maximum offset value is entered and a curve controls the offset from 0 - maximum offset along the length of the distribution area. A leaf distance value controls how far apart each quad is placed. A randomization seed is chosen and the system fills the placement area with quads. I have many ideas on how to improve this method as well as additional methods for placement I'll experiment with later.
e_2c.jpg
The Animation Strategy
I realized early that a tree fits neatly inside of a sphere with its center at the base of the trunk. As the wind moves through a tree it's branches bend towards the ground. Using an arbitrary axis rotation matrix, created from a 2D vector on the XZ plane, I could bend the trunk geometry by multiplying a wind intensity value by a flexibility weight element for each vertex. By adding an oscillation value to the wind intensity the trunk movement was simulated with acceptable results.
Once the trunk was animating, I added branches. Each branch inherits it's starting flexibility weights from the parent branch. Now I could create multiple levels of branches that would rigidly bend together in the flowing breeze.
It was clear that a tree with rigid branches neither looked real or sexy. I decided an additional layer of oscillation should be applied to any given level of branches. Each vertex in the tree was given another element, the oscillation offset weight. Using this value I could determine if a vertex was below or above the oscillation branch level. Branches found to be at or above the weight level multiply the wind intensity by the sine of the (oscillation offset weight + an incremented oscillation constant) before calculating the rotation matrix. The result, with a little tweaking of the values, is quite convincing.
Leaf quads were then animated using a sine wave around the view (quad normal) vector. Each leaf has it's own vertex elements with unique phase offsets. This creates a nice randomized movement as the intensity of the wind increases and decreases. Finally the leaf texture coordinates are manipulated, based on the intensity of the wind, to play a smooth leaf animation.

Leaf Painter
The first tool I created was the Leaf Painter. The original version was simple and allowed the user to load leaf brushes and paint them to a 2D canvas. Each leaf was rotated in 2D and the results were rendered to a 2D texture. It was enough to prove that my animation scheme worked but not enough to achieve the realism I was working for. I would need to create the leaves in 3D.
The second version of Leaf Painter works by painting leaf meshes onto a plane in a 3D window. The meshes are textured with the leaf images. Leaves are rotated using an arc ball gizmo. Each mesh can be rotated, warped, scaled, colored, and rotated in 3D. Because each mesh contains world space normals the Leaf Painter can generate tangent space normal maps from the canvas in real-time. The resulting animations produced by the new Leaf Painter exceed the results of the original.
e_2d.jpg
Tree Forge
The second tool I created was the Tree Forge application. This is the tree creation tool. Trees are generated from a set of parameters and can be modified and randomized. Level of detail is generated automatically and can be visualized. Animation parameters can be set and viewed in real-time. It essentially creates trees and saves the parameters to an XML file. The XML is then compiled to a platform specific Seed or Mesh binary file which the API loads at runtime.
There is so much to the Tree Forge application that I'll need to devote an entire entry to it later.
e_2e.jpg
My Exit
That's it for now. I hope you've enjoyed reading about my experiences and that you come back to read more. I've been working on this in private for a little over 3 years and have been dying to tell my story and share my work. In the next entry I'll talk about what I'm doing right now and plans for launching Woody3D.
Happy development,
Neil
0 likes 7 comments

Comments

Hypnotron
Looks really great. I was blown away (:p) by the video linked to in your last post. When you see videos like this of a properly simulated windy forest with the wonderful sound of blowing leaves, it reminds us how far interactive entertainment has come in terms of reproducing the look and feel of reality and how far it needs to go still. The potential and possibilities still seem boundless.

Of course the big questions are, will there be some form of interactive demo (like the ones you can find for SpeedTree in their Pangaea demo) so people can evaluate it properly. What kind of frame rate and on what hardware are you getting?
November 03, 2010 05:41 PM
RSI
Quote:Original post by Hypnotron
Looks really great. I was blown away (:p) by the video linked to in your last post.


Hi and thanks for your nice comments. Your joke made me leaf-out-loud. [grin]

Quote:Original post by Hypnotron
Of course the big questions are, will there be some form of interactive demo so people can evaluate it properly. What kind of frame rate and on what hardware are you getting?


Yes the demo will be freely available so you can run your own benchmarks.

The demo renders around 8000 trees in the scene.

Here are some frame rates I'm getting on three systems - each with different level of detail and multisample settings.

--------------------

Key: MS = Multisamples, TGD = Trees and Grass Distance, AFPS = Average Frames per Second over 60 seconds.

ATI Radeon HD 3200 1GB - 2.2 GHz AMD 64bit - 4GB RAM - HP Laptop
@ 1024x764
MS:2, TGD: Max, AFPS: 20.31
MS:1, TGD: Mid, AFPS: 32.967
MS:0, TGD: Min, AFPS: 66.367

ATI Radeon HD 3600 1GB - 2.8 GHz P4 32bit - 2GB RAM - Dell Dimension
@ 1024x764
MS:2, TGD: Max, AFPS: 25.45
MS:1, TGD: Mid, AFPS: 55.5
MS:0, TGD: Min, AFPS: 124.183
@ 1440x900
MS:1, TGD: Mid, AFPS: 44.45

nVidia GeForce 9600 GT 1GB - 2.3 GHz AMD 64bit - 4GB RAM - Custom Box
@ 1680x1050
MS:2, TGD: Max, AFPS: 61.1
MS:1, TGD: Mid, AFPS: 137.72
MS:0, TGD: Min, AFPS: 284.0

--------------------

If you've got any other questions then please ask.
November 03, 2010 10:48 PM
LachlanL
Hey,

First of all, very nice work! Looks really natural.

Okay, I'm going to go the obvious question: how much of your scene is geometry and how much is imposters? Also, if you are using imposters, how do you animate them?

P.S. Welcome to journal-land! [grin]
November 04, 2010 12:06 AM
Giallanon
Very good job, the video is amazing
November 04, 2010 04:35 AM
RSI
Quote:Original post by LachlanL
Okay, I'm going to go the obvious question: how much of your scene is geometry and how much is imposters? Also, if you are using imposters, how do you animate them?

The number of tree billboards (imposters) or rather the number of Woody3D trees is determined (in the tech demo) by a dynamic bounding radius determined by a configuration dialog. I don't have exact numbers.

Tree billboards are not a part of the Woody3D API yet. In version 1 it will be up to the developer to implement distance billboarding as they see fit. Currently the demo auto creates billboards at start. First it analyzes the billboard texture coordinates to determine a ratio. Then it scales the corresponding billboard geometry to the height of each tree.

Tech demo billboards are not yet animated. I will add this at some point and will do so by adding matching flexibility weights (I can analyze each Woody tree trunk to determine the maximum flexibility value while building bounding data, etc.) this will cause billboards to bend in relation to the wind vector and intensity.

You should also keep in mind that dynamic level of detail is in play here. A tree might have ~2000 triangles up close but only ~400 at a distance.
Quote:P.S. Welcome to journal-land! [grin]

Thanks! Good to be back.
November 04, 2010 12:27 PM
dgreen02
Amazing work!! Great job.
November 04, 2010 04:12 PM
Christa
Woody3D is phenomenal, and YOU created it! I'm so proud of you, Neil!
November 05, 2010 06:30 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement