VRMLSite

Subscribe for FREE

Discussion Area

VRML 2.0 URLs
VRML by the Pound

Tell a Friend
We'll Link to You!!

Aereal, Inc.
   Instant VRML
   Proteinman's Top 10

BackContentsNext
view me!



Building the Perfect Tree
A Lesson in Optimization and PROTO

by Robert W. Saint John

Recently I had to do a project in VRML that would require the construction of an entire forest. But the forest was only going to be atmospheric... I didn't want it to be so high in polygons that it slowed down the browser, let alone made the file huge. At the same time, I wanted to give the trees some individuality. I knew that the answer lie in PROTO, so that I could make myself a Tree node.

The first issue was to build the basic tree itself. Because there would ultimately be so many trees (about 20 or so), I decided to rely on a GIF texture with transparency for the leaves and branches. I would map a GIF (see left) made in PhotoShop onto an elliptical IndexedFaceSet, and let transparent edges simulate the leaves. Keep in mind that when you only want the texture to show (versus decalling on the geometry), the Shape node should have a material field of NULL. I DEF'd the shape as "LEAVES" so I could USE it two more times, flipped around, to give the top some dimension. This whole unit I grouped under a single Transform as "TOP".

Next, I would do the trunk. At first, I used a tall thin Cone primitive wrapped with a wood texture, but decided that I could accomplish more with less by using an Extrusion node. For those who haven't used it yet, the Extrusion node is a powerful way to accomplish simple modeling without having to use large IndexedFaceSets. An Extrusion basically defines a cross section along the X and Z axes, and a spine running up the Y axis. I used V-Realm Builder's Extrusion Editor (below) to build a five sided Extrusion, and rescaled the top set of points to make the trunk narrower at the top. I smoothed out the sides by assigning a creaseAngle of 1.92. Keeping in mind that I wanted a very optimized tree, I set beginCap and endCap as FALSE (since they would never be seen), and made sure it was a solid since the inside didn't need to be rendered. Here's the code:

geometry        Extrusion {
    beginCap    FALSE   # don't render
    endCap      FALSE   # don't render
    ccw         FALSE
    convex      TRUE
    creaseAngle 1.92    # smooths the faces out
    solid       TRUE
    crossSection        [ 0.149976 0.277726,    # 6 points for 5 faces
                        -0.0938272 0.187624,    # along the X and Z axes
                        -0.178628 -0.0667793,
                        0.123476 -0.246982,
                        0.319579 -0.0349789,
                        0.149976 0.277726 ]
    orientation [ 0 0 1  0,
                  0 0 1  0 ]
    scale       [ 1 1,          
                0.35 0.35 ]     # this scales the top down
    spine       [ 0 0 0,
                0 3.5 0 ]       # 2 points, bottom and top
} 

I specified my material and added a wood texture, and my TRUNK was complete. Once positioned with the TOP, I had my tree.

As I began to think about it more, I thought I should go further with my optimization for the sake of the forest. Trees in the distance don't need to be fully rendered, so I decided to utilize Level of Detail (LOD) and create one additional tree, very low resolution. Using what I created before, I simplified the tree. This time, I used only one set of LEAVES, and made it solid (you'll see why in a moment). Then I created an Extrusion that was only one face for the trunk, and removed the texture. I grouped the whole thing under a Billboard group so that it was always facing the viewer (hence the solid setting I mentioned above... the other side will never be rendered). And this whole thing I put under a Collision group so I can't walk through the tree (well, at least, I won't be able to once the browsers truly support it!). So, I end up with a file that has a basic hierarchy like this...

TREE GROUP (Collision)
  LEVEL OF DETAIL (set to switch at 20 units)
    TREE - HI REZ VERSION
      TRUNK EXTRUSION (5 faces)
      TOP
        LEAVES (3 sets)
    TREE - LO REZ VERSION (Billboarded)
      TRUNK EXTRUSION (1 face)
      TOP
        LEAVES (1 set)

...and I have my very optimized tree.

Finally, I want to PROTO this whole construction so I can have a "Tree node". It's true that I could just DEF what I have and USE it as much as wish, but then all the trees would look identical. With one simple PROTO, I can customize the size of each tree with very little code. Here's the definition of the PROTO:

PROTO TREE [
        field  SFVec3f  size    1 1 1 ]
{
    DEF TREE Collision {
        children DEF TREELOD LOD {
            level [ 
                        DEF TREEHIXFORM Transform {
                                scale IS size   # defining the PROTO field
                                children [ 
                                    DEF TRUNK Shape { ...

Note that the PROTO has only one field: size. You can see where I specified "scale IS size" within the overall Transform for my hi-rez tree. I again specified "scale IS size" for the low-rez version later in the file. This is crucial if you want trees in the distance to behave like trees up close.

Now that I have PROTO'd my tree, I have to instantiate one to make it work. Because PROTO'ing is like creating a new VRML node, I use it just like it was a primitive:

DEF INSTANTIATION Group {
        children Transform {
                children 
                TREE {
                        size    1 1 1
                }
        }
}

One cool benefit of having done it with the Extrusion from the very beginning is that when I go to rescale the tree along Y (i.e., make it taller), I won't have to translate it back up to keep the base at 0, 0, 0. And although this may be a lot of code for one simple tree, it only comes out to a little over 5 kb, 1.6 kb g-zipped! Adding additional trees to build a forest will require only a few lines of code apiece. Now I can create an entire forest in less than 10 kb, and use the space for what counts!

Feel free to take the tree and modify it as you wish. Using additional PROTOs you could, for instance, define different Appearances to create different types of trees like oak or maple (The VRML 2.0 Sourcebook by Ames, Nadeau and Moreland has some great examples of this). The key thing to remember is that whenever you are going to create a scene that involves a number of repeated objects, optimize them as much as possible, and PROTO them! Not only will your worlds download and run faster, but it extends your creativity as well.


About the author

Robert W. Saint John is Administrator of VRML Development for Integrated Data Systems in San Francisco. He spends his days cranking out VRML worlds with V-Realm Builder 2.0, writing articles like this one, and struggling to find new and interesting things to say in his bio. He denies having a Birdcage fetish.

Back Contents Next
Have you tried out our new Discussion Area yet?

LinkExchange
LinkExchange Member

Need sponsorship or advertiser information? E-mail adrian@aereal.com.

Have an idea for an article? Thought of a way we can improve VRMLSite? E-mail suggest@vrmlsite.com.

Please Tell a Friend about VRMLSite!

© 1997 Aereal, Inc. All rights reserved. VRMLSite is a trademark of Aereal Inc.