Experiment - Large Terrain Rendering
I took a few days off of the bug fixing process to investigate on adding a terrain system to GameStart.
I considered a few different methods:
- The simpler one with no lod and a fixed resolution (usually pretty low due to the lack of lod). These systems are very quick to program but are far from optimal on all fronts. They usually consume a lot of unnecessary memory for the static mesh and will most always still have the heightmap in memory to feed the collision engine. While you can put a high-level manager around patches of static terrain to increase the area and resolution you cover there's really no point in trying. You're going to have an insane amount of paging to keep the memory from exploding and much more than with a smarter approach, so let's move on.
- Old-school state of the art such as ROAM are very good on the polygon count front but require too much CPU work while the GPU got very good at dumbly pushing millions of triangles on screen. I did not entirely discard this solution but went for another first.
- Chunked-lod this is a very easy to implement solution which can be made to use the GPU in a very efficient manner. That's where I choose to start my implementation.
I started with a KD-tree implementation which while it seemed like a good idea was really overly complex due to the unconstrained patch aspect ratio (a square terrain split in two starts by giving two rectangles). Worst, it required to either fully store the display lists on the GPU (same caveat as the simpler method) or use immediate mode.

KD-Tree on the left, Chunked LOD on the right.
Switching to a quad-tree solved most of these problems. The quad-tree keeps a constant level of tessellation within a patch as each finer level increase the resolution by 2 while reducing the patch size by 2.
By exploiting this fact a single VBO can be used and reused to draw any patch in the quad-tree at any level of detail. The VBO only needs to be scaled and positioned appropriately and programmed to fetch the correct height map samples.

Buggy on a rocky planet, how new!

To note, this approach can be fully done on the GPU by fetching the height map from the vertex shader. That is not what I am doing at the moment but this is a minor extension to program and it will reduce the CPU load even more.

A rather large island (4km²) with a good definition (50cm) in 250mo.
The current implementation integrates perfectly with the system. Multiple terrain can be declared, any size and arbitrary maximal precision, the only limit is the available memory since there is no paging support. However, 250mo can buy you the following: 4km² at 50cm precision with fully dynamic shadows (covering 1.5km in front of the camera) on a 8600M running at 15 to 60fps depending on the viewpoint. Oh yes, there is DOF, SSAO and noise filtering everything on a two monitor setup on a laptop from the editor so yeah... Performances ought to be even better in real life conditions.
It's looking good already and there's definitively quite a few things left to be done to enhance all this. The terrain uses the same material definition as any other object so its shader tree can be reprogrammed if necessary.
- Emmanuel Julien's blog
- Log in or register to post comments
Comments
Thomas Simonnet
Mon, 07/19/2010 - 10:11
Permalink
Good morning,
)
This is a good news and will had a pretty neat environment, looking forward to drive the buggie on this big island !!
(maybe splashing some zombie walking
Scorpheus
Emmanuel Julien
Mon, 07/19/2010 - 12:24
Permalink
Hi Thomas,
Yes, I think it will be a great addition to the engine, especially for driving simulations
.
Demonith
Thu, 08/18/2011 - 15:31
Permalink
WOW just Wow!!!!
blc
Sun, 12/18/2011 - 23:37
Permalink
Thats amazing ... really. Is here way to explain more about making this in my gamecore ?
I make tank sim and large terrain im verry need. I have L3DT program for heightmaps.