thinBASIC TBGL Website

by Petr Schreiber 

Growing trees

TreeI know being a gardener was one of your greatest secret wishes, but you always been shy to leave computer alone and get lost from within pleasant warm breeze of you graphic card fan.

Don't worry, your time has come. Growing trees! Right on your PC! And with less than 200 lines of code...






Problems with trees

Creating trees as models for PC game was always very tricky. In early games you could see use of bilboarding exclusively, if anything at all.

As time passed, first real 3D trees started to appear. They were usually hand modeled, and sometimes looked quite strange.

Modeling a plant manualy is tough task even for advanced modelers, thats sure. Some programs provide tools for generating vegetations, but target is usually high poly model for movies and high quality stills.

But you want tree usable in real time application, right?


Growing a plant from code

One of approaches which could occur to you is to take random numbers generator and let the branches grow as they ( or better random number generators ) want.

Don't do it, it will be usable in very few cases.

Instead of torturing your friend with modeling a tree, try to get some algoritm. Get it from its author - nature :) At least this is one of authors which does not scare you with patents on technology.

To see how tree branches grow, it is good to watch trees in winter - leafs will not cover the topology.

Dead tree
click to enlarge


As there is spring out there while I am writing this article, I will help you with photo of dead tree.

You can see there is something periodic on the growing... the angles between branches and subbranches are really almost the same. For simplicifation, we will presume they are exactly the same.

To get it even simplier, we will take as a fact branches are rotating around 2 axes when growing - Z and Y.

I know this is not exactly true, but as this won't be super perfect simulation but just approximation to reality, I think we can live with it for now.


Let's code

With knowledge from previous paragraphs we can start to build the source.

As target is real time application, we will use some limiter to define depth of branch generation, lets call it levels for a while.

Lower the number of levels will be, lower hardware requierements but also worse look. My recomendation is to keep between 5 for larger scenes and about 9 for solitary trees.

To not drown in infinite recursion, we will lower this number for each new generation getting closer to end.

Tree generated without twist angle looks weird
without twist


While approaching to last branch, also the length of branch fragment and radius should be reduced, else result would look like output from mad "mikado" game.

Next parameter we will simply call openAngle. This will be angle in degrees by which the main branch line will be rotated. As child branches should be clearly differed from their parent branch, they will be rotated by angle*2. This angle will be manifested on Z axis.

The second important angle I will call twist. It will turn branches around Y axis.

>>
' Recursive function to create branched branches :) 
SUB DrawBranch( startRadius AS SINGLE, startlength AS SINGLE, _
levels AS LONG, openangle AS SINGLE, twist AS SINGLE ) LOCAL i AS LONG LOCAL length AS SINGLE LOCAL radiusS AS SINGLE LOCAL radiusE AS SINGLE IF levels < 3 THEN TBGL_BINDTEXTURE 2 ' Hot Alpha handling stuff TBGL_USEALPHATEST 1 TBGL_ALPHAFUNC %TBGL_GREATER, 0.5 FOR i = 1 TO 3 TBGL_ROTATE 120,1,0,1 TBGL_CALLLIST 2' 0.2,0.4,0.1 NEXT TBGL_BINDTEXTURE 1 TBGL_USEALPHATEST 0 IF levels = 0 THEN EXIT SUB END IF radiusS = startRadius radiusE = radiusS - startRadius/levels length = startlength TBGL_PUSHMATRIX FOR i = 1 TO levels ' possible optional optimization
' tbgl_setPrimitiveQuality levels/1.5
TBGL_CYLINDER radiusS , radiusE, length TBGL_TRANSLATE 0, length, 0 TBGL_ROTATE openangle,0,0,1 TBGL_ROTATE twist,0,1,0 TBGL_PUSHMATRIX TBGL_ROTATE -openangle*2,0,0,1 IF i = 1 THEN DrawBranch(radiusE, length, levels-1, -openangle, twist) ELSE DrawBranch(radiusE, length, levels-i, openangle, twist) END IF TBGL_POPMATRIX radiusS = radiusE radiusE = radiusS - startRadius/levels length = length - startlength/levels NEXT TBGL_POPMATRIX END SUB
<<


As you can see in the procedure above, to draw branches we just picked TBGL_Cylinder function.

This allows to scale number of polygons of whole model ( determined by complexity of cylinder ) by using TBGL_SetPrimitiveQuality to arbitrary value.

You will see even 8 sided cylinder is more than enough for trees, and with optional lowering of detail with generations of branches, you can get pretty fast result.


Leafs

In code above, there is some part to render leafs.

Although somebody with GeForce 8800 would appreciate multivertex modeled leaf with caterpillar, we will use little trick to maintain shape diversity of leafs while keeping it just 4 vertex definition.

Trick consists in using TGA texture. TBGL can load 32bit TGA files with alpha channel, so we can prepare photo of tree in any graphic editor and mask it with alpha. Such a task is realizable in many editors, I used Picture Publisher 8, but even free GIMP can do this for you.

To enable alpha masking in TBGL, you need two lines of code:
>>


  TBGL_USEALPHATEST 1
  TBGL_ALPHAFUNC %TBGL_GREATER, 0.5
<<


We will append leafs to jointpoints 3 generations before end to make the tree look full of them.

It is also good idea to make them slightly rotated, although they will inherit angle after the mother branch.


Summary

Hope you liked this article, first on new version of TBGL website. If you didn't, or think something is wrong , than just leave a post on our forums and I will see what I can do.

You can download material related to this article below:


Download source