I just want to weigh in here with an alternate technique.  This technique is
optimized for fairly slow movement speeds.  Our current implementation can
handle up to 50 meters a second without a problem, but after that it can't
keep up.  Not a problem for us, but could be for other people.

The net effect of the following technique is the following:

Average FPS on Geforce II 700 MHz viewing 10,000 meters out is around 40-75
with sky and terrain.  The terrain in this test would be 6.6 million
triangles unoptimized.  Thats  12.8 km x 12.8 km.  The effective texture
density is 16,000 x 16,000 pixels over the same area.  The terrain is lit,
with normals and two light sources, one direct for the sun, and one ambient.
Generally at any point in time there are 24,000 to 35,000 triangles used to
generate the terrain.

We do our terrain completely differently than CLOD or Roam. All the meshes
and textures for all the LOD levels are built in an offline process
(although we can also make dynamic alterations at runtime) Since 99.999
percent of terrain does not change very often. The geometry for each terrain
patch is analyzed and an edge collapse map is created. The textures for the
various lod levels are built and stored with the corresponding patch. Lod
level zero is patches of 200m x 200m areas. Lod level 1 is 400x400
consisting of 4 level 0 patches. So at any point in time the renderer can
decide to show four level 0 pathes or one level 1 patch, etc all the way up
to level 6. We are vey happy with this approach. Lod changes are seemless
and fast. The only cost is the disk space. We store each 62 square mile zone
(12800m x 12800m) in a 40-50 MB file.

People always discount this approach when I describe it because it is not
sexy like roam or adaptive quad-trees. We don't do any view dependent
optimizations of the terrain at all (except culling backfaces and FoV
culling). But J3d is very good with FoV culling and so in any one view many
of our patches are culled. Many of our patches are reduced to as few as 180
triangles through the edge collapse algorithm. Most of the patch textures
are only 128x128 and other than level 0 no mipmapping is needed, as the
level itself is in a way a mipmap. But there are some really nice advantages
to this approach. When we put a road down, you can see that road from a
great distance because the net effect of this technique is that we have a
virtual 16000 x 16000 texture sitting on top of a 12800 x 12800 landspace.
Add multitexturing in there and the ground takes on a very nice look. We can
see out for about 10km with sky and trees and everything else at over 50 fps
on a geforce II gts.

More info...

We tried a LOT of different ways to go, including adaptive quad-trees, but
finally settled for static quad-trees for the terrain. We import a GIS
heightmap and generate geometry cells and procedural texture cells for 200m,
400m, 800m, 1600m, etc up to 6400 meter cells.

Each level is controlled by a LOD descriptor that defines the following:

1. The sparseness of the heightmap scan
2. the amount of polygon crunching to do in percentage of total polygons
3. The size of the texture
4. The density of the detail texture
5. The name of the detail texture
6. Whether or not to share the parent's texture
7. The number of children in one dimension (2 for right now for all levels)

We run a program that generates all the geometries and textures into files
(soon to a jar) and we are coming in at 50mb per 135 sq km, which is pretty
decent, although we have plans to reduce that further. We then define an
array of spherical bounds which define the minimum LOD level in relation to
the person. So everytime they move 40 meters or so we recusively drop down
through the tree starting at the top and check to see if the cell violates
the layered bounds. When it does, it builds n children and drops down inside
of them, whereupon it continues. So we can say we want the highest lod
detail within a 400 meter radius, and we never want the 3200 or up LOD
version within 800 meters. If we don't do this we can get too close to a low
res version approaching major colinear cell boundries (like in the very
center of a 12k cell). During this pass a list of nodes is built. This list
is then passed to the renderer which determines which cells have been
removed from the last pass and which need
to be added. It then modifies the scenegraph accordingly and then prunes the
tree to remove children that arn't needed anymore.

The textures *can* be built on the fly, but there is a noticible
sluggishness. This will only grow worse as we refine the shaders. So we
pre-generate all of them for every cell at every level, except where the
levels share textures. So you can tell the engine that 800 meter cells
should use their portion of the 1600 meter cells. But by and large the vast
majority of the textures are the 200x200 meter cells stored in 128x128
textures, then blended with a detail texture to hide stretching.

The meshes are also pre-built, although they can be more easily built on the
fly without performance hits. Each mesh file has a corresponding matching
texture file. Each mesh file is stored with a pre-calculated LOD reduction
map, so we can dynamically control the quality of the landscape based on
user's machine. Each mesh file is quite small. There is a dynamic (in
memory) node tree which represents the currently active nodes. Its
recursive, so say there is a 12800 m x 12800 m node, with 4 children
representing the four 6400 m x 6400 m children, representing 4 quandrants of
the parent. When I check to see if we need to update the landscape, I drop
down through the parent and apply certain policies to see if we need to
recurse into the children, or if it is safe to render this cell level. So
the quad-tree is self maintaining. It builds a render list of nodes which
*should* exist to fulfill the policies. This is passed to a controller that
compares it to the list of existing nodes. It then builds a transaction
representing a series of attaches and detaches of the scene graph, and
requests the nodes to return their Shape3D's, the old branchgroups are
detached and get garbage collected, and the unused children are then culled
from the tree. So for for over a 120,000 square meter area I usually only
have from 20 to 45 nodes active at one time.

Feedback from the team is that there is no sense of paging or slowdowns or
hiccups at all. The LOD changes are noticible, but not really bad at all.
There is some popping, but not generally in outline of the mountains. The
textures appear to be seemless. The farther cells are being built with fewer
and fewer polygons.

I am attaching a few pic shich should be under 60k combined.

David Yazel

<<attachment: cosm570.jpg>>

<<attachment: cosm566a.jpg>>

<<attachment: cosm569.jpg>>

Reply via email to