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

Submitted by Ben Woodhouse, posted on May 15, 2001

Image Description, by Ben Woodhouse

This shot was taken from the landscape renderer I'm working on. It demonstrates the use of LODs for landscape rendering.

The landscape is rendered as a 16x16 grid of tiles, with each tile drawing one of 5 pre-calculated LOD meshes (depending on distance from the viewer). The gaps between the tiles have not yet been filled in. The LOD reduction routine I'm using preserves detail with a bias towards higher points, so distant peaks are preserved.

With LOD turned off (each tile being just a grid of 16x16 quads), I get 14 fps in polygon mode, or 4 fps in wireframe mode, drawing 115200 triangles (on a GeForce2 Pro with FSAA 2x). With LOD turned on, the triangle count depends on the complexity of the landscape mesh. This one is nice and flat and so reduces to about 12000 triangles per frame, which displays at about 80fps in polygon mode or 20fps wireframe. Despite the fact that this landscape, including all the LODs, is made up of 90059 vertices and 145374 triangles, it manages to fit into about 1.45MB of memory (by the cunning use of BYTES instead of floats wherever possible).

The landscape renderer uses OpenGL. Eventually I hope to use it in a racing game I'm designing.

Ben Woodhouse

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.
Alex J. Champandard

May 15, 2001, 02:16 PM

Filling in the gaps between the tiles is the toughest part when you use this sort of scheme. You could just use plain strips, which you'd have to generate every LOD change (bit of a bummer :) Or just freeze the points on the edges (also not ideal).

Have you thought of hierarchically combining the tiles?

First post ;)



May 15, 2001, 02:19 PM

Please excuse my ignorance, but why exactly are there gaps between the tiles? Shouldn't it be possible to have them touching each other? They seem to line up ok.


May 15, 2001, 02:28 PM

Hehehe. I had the same question.

I think if the vertices don't line up you'll get funny little holes in your t-intersections... Like the ones you get with poor clipping.



May 15, 2001, 02:29 PM

A fast way to join not-so-similar-neighbouring-edges is what is also referred to as the "flanges" technique. You make each chunk or tile (whatever you call it) extend (add edge vertices to all sides of the chunk/tile) so that neighbouring tiles overlap eachother a bit. Then you make sure the edge vertices you've just added are below the vertices of the neighbouring chunk's/tile's vertices. Then you let the z-buffer do the union. Makes for a fast way to get rid of the cracks, without ever having to touch indexbuffers or vertexbuffers (which could then be made static).


May 15, 2001, 02:35 PM

Nice image, but whats this cunning use of BYTES instead of floats? could you explain more. Cheers.

Alex J. Champandard

May 15, 2001, 02:36 PM

Emphasizing the gaps will come in handy during testing, when he gets round to implementing his gap filling algorithm. As you said, you could just get the tiles to aline along the X/Z plane, but you'd get worse than T-junctions: actual holes. And then it looks like your just not taking that into account, whereas if there's a big gap there it's like saying "work in progress" ;)



May 15, 2001, 02:38 PM

Still if you do some vertex lighting it'll look like crap if you don't join the vertex. Looks nice what you've done but you could implement a distance based LOD also it would help reduce a lot of triangles.


May 15, 2001, 02:41 PM

Oops sorry :) I missed something actually implemented a distance based LOD...oh well looks like you could then use a LOD which when the "tile" is nearly flat uses the "tile" which has the least number of triangles...and keeps the highpoly tiles for moutains so they'll still appear "round"


May 15, 2001, 02:45 PM

For example you could use a "normal map" for the tiles...calculating an average normal for every tiles and then using it to find out which patch to use based on distance and global slope in regards with the user point of view...just an idea

sea cow

May 15, 2001, 02:54 PM

Could a normal map help define how a vehicle would move over this terrain? Nice image, btw.


May 15, 2001, 03:41 PM

well, if you store your data in bytes instead of floats, you'll save of course some memory, since a float is 4 bytes big, and a byte is, well, one byte big =)

John van der Burg

May 15, 2001, 03:41 PM

I was just wondering. If this little terrain (piece of a terrrain) already eats up 1.45MB of memory, wouldn't it be a bit of a problem when you need to store a HUUUGE terrain?
In other words, is the algorithm fast enough to stream through the terrain data. So while flying around, generating the terrain sector data on the fly (you should cache it ofcourse).
But I just have a feeling it will start choking a lot. The framerates when you visit new yet uncached terrain parts.
Just having some doubts that this algorithm is friendly enough to todays 3D hardware. I personally think not :) [another problem might be generating strips with this algo]

- John


May 15, 2001, 04:10 PM

and you could use various 1024-byte LUTs to convert bytes to different ranges of floats really fast. I know LUTs are not optimal nowadays, but they're certainly faster than a byte-to-float conversion + an add and a mul, or whatever...


May 15, 2001, 04:12 PM

Strips and fans aren't so good anymore. Indexed triangle lists can be a lot faster on modern cards.


May 15, 2001, 04:54 PM


I know, I know it 's probably a stupid question for most of you
but why you can render faster polygons than wireframes ??


zed zeek

May 15, 2001, 05:01 PM

im sortta in agreement with john van der berg it doesn't appear to hardware friendly for todays cards plus the popping. if youre landscape is only 115200 tris max i'd forget about LOD totally. about the gaps have u looked into the nv_evauluators extension (demo on my site ) it handles gaps between the meshes very nicely. well besta luck


May 15, 2001, 05:04 PM

Because lines arent used very much, so no one develops decent silicon for lines. It is quite stupid. Actually, lines are some of the only things that those expensive workstation 3d cards do faster.


May 15, 2001, 05:15 PM

While looking at that landscape, i had the thought of doing quantization on the tiles. If you where to have a gigantic landscape then you could use quantization to make some 2^n unique tiles then every tile would only need n bits. Less unique geometry, which would be good to the 3d-card and you could compress the entire landscape 100-200 times.

Would this work? Anyone?


May 15, 2001, 05:19 PM

I was being a little optimistic there, sorry, maybe 10-20 times would be more realistic.


May 15, 2001, 06:32 PM

By the way, AFAIK, FSAA on the GeForce 2 slows things down considerably (I don't own a GeForce 2 myself). The GeForce 3 allows FSAA with 4fold sampling! That's where I learned about the GeForce 2's caps ... GeForce 3 review ;)



May 15, 2001, 07:02 PM

John Van der bla: I think it's friendly enough for today's hardware...with his precomputed patches he can easily put those into some vertex arrays or display lists and this will speed up the whole thing. He's not recomputing each patch every frame


May 15, 2001, 07:40 PM

Well, just doing some quick mental arithmatic, that's only a 256x256 heightfield you've got there. Memory useage shouldn't be that extreme, even if you were using floats to store all of that. *cough* try a 4096x4096 field. *cough* ;)
Freezing your verts along the edges of a tile is probably going to yeild the easiest way of seaming the mesh together - just so long as you don't allow more than a 1 level change in LOD between adjacent tiles (you could be cheap and just set your LOD level as a function of the vector magnitude between a tile and the camera).
The reasoning behind not just flanging your tiles would be you wanted to vertex light them, but a bugger of a thing I've noticed about terrain engines that use arbitary meshes to represent the landscape (ROAM, QuadTrees or LOD tiles, as opposed to brute forcing it..) is that you will have a really hard time generating acceptable normals to vertex light the scene with. It will look okay while the scene isn't "moving", but as soon as an LOD switches the actual geomety sihloutte may not have changed all that much, but the shading changes will be very visually jarring. It's probably the biggest "for" for baking your lighting into your underlying textures.
Having your landscape divided into nice squares at 16x16 opens up a nice door into the world of procedural textures too- so that could be fun. At that size and on a Geforce, You could probably get away with an individual fairly hi-res texture on each Tile, and generating the texture/w lighting the first frame that tile comes into view.
(baking lighting into a texture like that is relativly easy -just create a render surface the same size as your texture, and then render a flat grid mesh with the proper vertex normals of the underlaying terrain. - Voilla )

Anyhow I've rambled enough - I think terrain engines are alot of fun to code simply because of the great visual feedback they give you when things go right, and all the fun junk you can do to spiff one up once the mesh is there. Kinda like the programming equivilant of reading a comicbook I guess :)


May 15, 2001, 07:48 PM

Methinks by 'clever use of BYTES' he's referring to storing the heightfield as bytes and then casting them as floats when need be?


May 15, 2001, 07:51 PM

Unless of course you disassemble the Quaddro2 Pro drivers and replace parts of the GF2Ultra drivers with them. Hey presto - a half price Quaddro2:-)


May 15, 2001, 07:55 PM

One of the nicest looking wireframe shots I've ever seen


May 15, 2001, 08:01 PM

to draw TRIANGLE using wireframes you need actually to draw THREE triangles - that's why.. You can't make your scanline render to draw wireframe TRIANGLES because you'll get gaps of empty pixels - if you ever drawn scanline render you'll see why?

So in modern cards having x3 less triangles to draw is like x3 faster - and here it goes 4fps x 3 = 12fps (even 14fps he gots).


May 15, 2001, 10:45 PM

malkia: then just draw some plain lines! don't scanline it. There's a mode in OpenGl which does just that GL_LINES or GL_LINE_LOOP..something like you don't have to draw 3 triangles


May 15, 2001, 10:47 PM

I aknowledge you'll still get a lot of lines being overdrawn but still if you manage to store the edges you can do a pretty fast wireframe renderer...if you care..and have time to waste :)


May 15, 2001, 11:31 PM

I think you find Malkia actually said you need 3 triangles to draw a wireframe triangle. The misunderstanding comes from ESL. And iirc OpenGLs basic primitive is a polygon, and actually draws polygons (quads?) for the lines, and very small polys for points.


May 16, 2001, 05:06 AM

Looks cool!

I've got a Q however. I've got an array of tiles in my landscape as well, but there's not that many tris/tile, around 8 in each tile. I want some real view distance :)

Should I copy the mesh data for the visible tiles into a vertex array and do a one-sweep or several larger sweeps for the whole visible landscape?
As it is now, these 8tris tiles are ordered in a vertex array manner and I do a glDrawArray for each of the tiles...I know that 8tris isn't optimal for performance.

Any input appreciated!

This thread contains 49 messages.
First Previous ( To view more messages, select a page: 0 1 ... out of 1) Next Last
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.