I thought the list might be interested in some notes on this subject.  We
will be attempting the implement the scheme described below in the near
future, and if there is interest I would be happy to share the results.

Dave Yazel
Cosm Development Team
http://www.cosm-game.com



TREES
----------

I have been toying with these ideas for a while and wanted to get them
jotted down so we don't lose them.  There are some wierd things that make 3d
worlds come alive.  Trees, shrubs, flowers, weeds, ferns, grass, sticks,
rocks, pebbles, worms,birds, etc.  Cosm is right now a very barren place,
despite the illusion.  There are many problems with displaying all that in a
way which looks good but does not crush your frame rate.

These things very much differ from POI ("points of interest").  Cosm's POI
manager is pretty efficient.  It will bring a tower into being and place it
in the right place when it needs to and not before.  It will even manage
duplicate objects, like boulders, and constantly  move them around to
conserve memory.  So as you walk through the world rocks are being removed
from behind you, then scaled and rotated and placed in front of you... and
you never see it happening.

We are currently managing trees in this manner.  A pool of trees is created
and they are moved around as you walk through the world.  On my geforce II I
can push the distance out pretty far and see a lot of trees.  The problem is
that it starts to really soak up the frame rate, and these trees arn't even
very good.  They are low poly and ugly.  When we put nice trees in the scene
then we might start to lose a lot of frame rate, or be forced to bring in
the clip.

So I would like to experiment with something called imposters.  An imposter
is a picture of something that is placed in the scene to fool you into
thinking that it is really there.  Its like if someone painted a big picture
on a billboard and went and placed it in a field and when you looked at it
you thought there really was a tree there.  An imposter is usually a flat
plane oriented to face the camera.  So as you move, the billboard rotates to
be parallel to your viewport.  This gives the illusion that the imposter is
really 3-dimensional.  If the billboard did not rotate then it would become
thinner and thinner as you approached it from an oblique angle, until your
were looking at it edge-on, whereupon it would be invisible.  Imposters can
usually be pretty small, depending on how close you want the imposter to get
before you replace it with the real thing.

Now I should pause here and discuss some technical constraints:

1. There are two ways of doing transparency, blended or boolean.  With
boolean transparency each pixel in the image is either off or on.  If it is
off then whatever is behind that pixel shows through.  With blended
transparency you can have a pixel which is translucent.  This is very good
for edges of things, and especially good for vegetation and trees.  The
issue is that for something to be blended with stuff behind it, then that
stuff has to already be drawn.  Translucent items therefore have to be drawn
after all opaque objects, and the translucent obejcts themselves need to be
sorted to make sure they are drawn back to front.

2. The basic thing that is drawn in Java3d is a "shape3d".  A Shape3d
consists of a bunch of triangles and directions on how to draw them.  The
directions are called the Appearance.  The appearance controls the texture,
the materials, transparency options, coloring, zbuffering, etc.  Basically
the appearance controls everything about the shape except its geometry.
There is a fixed overhead in drawing Shaped3D's.  A long time ago I created
tree imposters in Cosm, each one in a shape3d.  1000 trees reduced my frame
rates to a crawl.  The reason was the overhead of all those shapes.  The
other reason is that each of those shapes had to be transformed to be moved
into the scene, and that each of those shapes needed a behavior which
handled the rotations per frame.  So basically 1000 transforms, 1000
behaviors, 1000 shapes with 1000 appearances and 1000 geometries.  All to
draw 1000 identical trees.  Now I did use link nodes for the Shape3d, so it
was using the memory of 1 shaped3d, but it was rendering 1000 shapes.

3. There is something called a GeometryUpdater.  This is basically a method
to change the geometry dynamically.  We use this for skin and bone
animations, particles, sky system and lots of other things.  With geometry
updaters I can adjust the each vertex's color, texture coordinates, normal
and position.  We can also add and remove new vertices.  The disadvantage is
that all this information has to be sent over every frame and therefore
cannot use display lists stored on the 3d card.  The other disadvantage is
that all that geometry in a single updater has to share the same Appearance,
which namely means it is sharing the same texture.

Ok onto the imposters.  If we use a geometry updater, with every 4 vertices
being a single vertex, we could draw 1000 trees with 4000 vertices, one
shape and one texture.  This would be very fast.  For every frame we would
re-sort the trees by distance to viewer, then loop through them and build up
the buffer.  For each tree we would check to see if it was within view.  If
it was not then we would exlcude it.  I am confident this would work very
well and run very fast.  Well, it would work very good if all we were
showing was pine trees.  But what about a mixture of  trees?  I mean a
forest has more than one type of tree generally.  If we had two of these
updaters, one for each tree then each tree would be rendered in a different
shape3d, which means their order would be all one types of tree, then all
the other type of tree, etc.  But these trees need translucent
(anti-aliased) edges to look good, so they need to be rendered in order.  So
we would be forced back into having a single shape3D for each tree, back
into our basic problem.  But how big does a tree texture need to be,
especially if it is a far away tree?  Well a far away tree could be 20
pixels high or less, but a tree half the distance away could be 200 pixels
high.  So we can probably assume that a picture of a tree could be 100 x 100
pixels and still scale reasonably to 20x20 or 200x200.  We would have to
play with the numbers.  Let us say then that we made a composite texture,
sized 256x256.  On this texture we could place four 128x128 images on it. I
am not being precise here, since we will need a bleed border between the
images, but we are doing estimates here.  This would mean that we could show
4 different types of trees all with the same shaped3d!

Ah but there are a few problems.  The first is that four different tree
types in the scene is not very many, and what do we do about transitionary
borders when we change from one area to another, each of which might have
different tree types.  Well one solution might be to move to a 256x512
texture, which would double the tree count to 8, or to a 512x512 texture
which would move us to 16.  I dare say that 16 different types of trees in
view at one time would be sufficient.  Remenber that each tree can be scaled
slightly differently or orientated slightly differently.

The next problem is that a single picture of each tree is not sufficient.
To do it correctly you would need to take snapshots of the trees from
different angles and then pick the right picture based on the orientation of
the tree and your relationship to the tree while viewing it.  So while there
might be 100 pine trees which are all really the same, they are each placed
into the world with a slightly different scale and roatation.  The less we
respect that in our imposters, the more obvious it will be when we swap out
the imposter and swap in the model.  So we could take the 128x128 space and
divide that into 4 peices, each one representing the tree from a different
angle.  This would work really well for far away trees, but those 64x64
trees might start to scale badly when they are taking up 200 pixels of
screen space.  We won't know until we try it.

Now as you get closer to a tree there comes a time when we will replace the
imposter with the model itself.  This is usually pretty obvious if you are
looking for it, especially if the "real rendered trees" radius is pretty
small.  I don't think this is a particularly high proce to pay however.  I
know Asheron's Call does this and it has never bothered me at all.

Another nice technique would be to make far away trees more and more
transparent until they just fade away.

PLANTS
------------

The next category is all the other stuff which you would expect to see in
the world around you.  This could be flowers, weeds, grass, small
pebbles,etc.  basically anything which falls into the category of "mentally
dimensionless".  I use this phrase to describe those things that exist on
the periphery of our conciousness.  We don't really look closely enough at
them to notice they are 2 dimensional.  If you see a field of grass and
dandylions you never look at each dandylion individually, instead you see
the "effect" of lots of little yellow flowers.  So the dandylion could be
drawn as a very small texture of a yellow flower with no stalk.  If this was
mixed into ground cover then this would appear to be legitimate dandylions.
So the idea is that we assign a bunch of "ground cover" objects to an area,
build a composite texture which includes all the little images and render
them using the same technique as we are using for trees.  Except this time
the radius extends from the view outward.  We should not go out further than
the the break between real and imposter trees, since they are being rendered
in two different shapes we don't want them to collide, but in practice we
will render the ground cover after we render the imposter trees.

Thats the basic idea.  I will publish more detailed information after we do
some of the implemtation so we can get a feel for how this will work in
practice.

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to