Not logged in, Join Here! or Log In Below:  
News Articles Search    

Submitted by Loïc Baumann, posted on December 22, 2004

Image Description, by Loïc Baumann

Yep, another Terrain Engine... I know, I know, at least one hundred IOTDs were about that. So what is special about this one? Well you’re the judges...

Hardware rendering of the terrain's heightmap:

That allows real-time deformations of the terrain by modifying directly the height map.

You can also use this engine for animated water (sea/lake) rendering.

Very scalable:

The terrain is made of A*B elements, each element is made of C*D tiles, each Tile is made of E*E vertices (E power of 2).

- Elements can be loaded on the fly from disc, allowing worlds as big as you want.

- Only visible Elements have rendering buffers committed and just before being used for render (you can setup how many elements are to be kept in memory).

- Tweaking the A,B,C,D,E factors enables different policies (speed vs memory).

Adaptive rendering:

- You can choose the LOD count of the heightmap.

- A quadtree routine determines which LOD level to use for the rendering of each part of the terrain.

- The LOD is then hardware interpolated per vertex.

- The tiles’ LOD always match their neighbours at the edges to avoid cracks (no need to fill holes later, and it’s still progressive LOD).

- You can of course set the Maximum Screen Error for the surface rendering.


- Quad-Tree parsing for clipping and rendering.

- Fragment rendering of tiles for Frustum clipping, to avoid rendering a whole tile when only a small subset is visible.


- 4bytes per height of the map.

- Additional vertex buffers of 4*C*D*E*E bytes (for each LOD, with E, then E/2, E/4, and so on).

About speed, on a GeForce 6800, this is 2.2 times faster than rendering using the highest level with the same clipping.

About the pictures:

The top one is from the camera used for the terrain rendering, the bottom one is an external view of the terrain being rendered from the top camera’s point of view.

- Each box represents a tile (the bigger the tile is, the lower the LOD).

- For the bottom picture, the shade from black to white represents the LOD fraction between two levels.

- You can see that fragments of tiles are rendered (instead of the whole one) on the borders of the frustum to save some rendering.

- The little picture at the bottom left demonstrates what happens when there’re two tiles of a different LOD stick together. The LOD fraction is clipped to 0 (for a higher level) or 1 (for a lower level) at the edge to make the junction perfect.

I Hope you enjoy, you can email me if you have questions.

I may write an article about the technique and release the demo in the future.

Image of the Day Gallery


Message Center / Reader Comments: ( To Participate in the Discussion, Join the Community )
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

December 22, 2004, 01:34 PM

Holy shizat! First post!


December 22, 2004, 02:32 PM

lets not have "first post" bullshit start here again.

What kind of texturing are you aiming at with this approach? Does it lend itself well to multiple passes for detail texturing or are you thinking about splatting? I've been through a number of data representations and rendering algorithms for terrain and it has always come down to how well the system can accept texturing.

Dr. Necessiter

December 22, 2004, 02:47 PM

Very nice and extremely similar to what I do. BTW: since my particular application is phototexture-based, I don't do any splatting... just tiled phototextures.

I noticed that you don't seem to have "transition strips" between LODs. Do you just assure the "t-junction" vertex is perfectly coliniar with the lower LOD's edge? I chose the transition strip system so I didn't need to touch the vertex buffer. I'm curious as to why you chose this transition scheme?


December 22, 2004, 02:51 PM

How do you deal with discontinuities between lod levels? On your screenshots it seems you are not doing anything to prevent cracks or lighting discontinuities.


December 22, 2004, 03:36 PM

meh, I have never been the first one to post on an image of the day so I couldn't pass up this one time chance.

As for the image, it looks nice, but there have been so many of these terrain rendering pics. Maybe I should post mine too so I can be like everyone else ;)


December 22, 2004, 05:56 PM

Lighting is easy to get uniform across lod levels, the key is to do perpixel lighting, this avoids visible 'pops' when lod level switches (because for starters it doesn't :). Here's a video from 2002 which demos the technique, the textures are not very interesting in this one:

This technique is using seamless lod technique I developed, it uses GPU to compute the fractions, lod, detail texture blending factor, et cetera in the vertex program. Largest dataset I have ran using this was 4000x4000 and it ran the same framerate the smaller ones (60 fps, locked to LCD refresh rate). The problem at this stage is memory, really, not performance. The video is 2K by 2K if I remember correctly. Try to spot cracks or lod popping (I want to emphasize that this is NOT brute force :)

The normal maps are computed with the GPU. The higher frequency noice is also computed with the GPU using Perlin noise and the amplitude is controlled by 8 bit map stored in one of the surface map texture channels, so can have rought and smooth parts in the landscape (airstrip, whatever) and rought areas just painted into the textures (though in this video the data is 100% random generated).

So in fact the largest challenge after the initial idea was actually texture caching: 4Kx4K would take some serious amount of memory for the textures. Oh, forgot that technique called 'unique' texturing is used, so each texel in the landscape is *unique*. That also takes a little hit in the RAM but is worth it in the special effects. The parameters how the unique textures are computed are also stored in their own textures, the using render-to-texture it is possible to compute the unique texture from the layer/composition information from preset collection of materials. The idea behind this is that each texture is in reality built from 4 which are layered (the blending weights are stored in lower resolution texture, the layer composition texture). The benefit of unique texturing is that can CACHE the multipass results, which is a lot faster! Also, effects like scorch marks, trackmarks, skidmarks whatever, you name it, are possible to generate on top of the unique texture when the cache does a read request to the generator. :)

There is one crucial area that needs updating and that is the lighting. The test light just runs circle over the area in the video, lame. Yet, there can be multiple lights. Yes, I want shadows (meaning self-shadowing from the landscape itself, objects in the same scene would cast shadows), that is something I would add if ever get back to the code. Let's be realistic: lack of self-shadowing just looks plain shit.


December 23, 2004, 02:04 AM

"I noticed that you don't seem to have "transition strips" between LODs. Do you just assure the "t-junction" vertex is perfectly coliniar with the lower LOD's edge?"


"How do you deal with discontinuities between lod levels? On your screenshots it seems you are not doing anything to prevent cracks or lighting discontinuities."

Every edges match perfectly, there's no cracks, holes or whatever.
I don't have to lock any VB to do that, I don't have to render "transition strips" too, the problem is solved in real-time, in the Vertex Shader.

The detection of LOD difference between two edges is made on the CPU, then with a series of flags loaded to the VS constant the VS Shader does the border detection and clamp the LOD to 0 or 1 for the edge vertices when there's a difference with the neighbour's one.

This VS code which performs that is really quick.

The LOD is computed for each vertex, and the height is computed by the VS Shader using the two surrounding LOD Levels to ensure a smooth transition between them.

Texturing and Lighting wasn't my concern for this IOTD, I'll maybe demonstrate the solutions I took in a next IOTD! :)

The key points of this IOTD is that it renders a terrain directly from a height map (which can be dynamic), with real-time detection and fix of the discontinuities between the LODs of two tiles.

Julien Houllier

December 23, 2004, 06:12 AM

DICE/EA's outdoor engine for BattleField uses a 16bit heightmap instead of a 32bit one.
It is enought for many many many projects. Why are you using 4 bytes for the altitude of a cell ?


December 23, 2004, 08:53 AM

Julien Houllier wrote: DICE/EA's outdoor engine for BattleField uses a 16bit heightmap instead of a 32bit one. It is enought for many many many projects. Why are you using 4 bytes for the altitude of a cell ?

It's 16bit too. But I have two values stored per altitude.

The vertex shader uses these two values to compute the height (from the vertex' LOD), then the position in space of the resulting vertex.

Of course, one value would be enough if I didn't want a seamless transition between the LODs.

This thread contains 9 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.