PDA

View Full Version : Efficient Terrain Mapping



Psiborg
05-07-2006, 09:24 PM
Ok so i am making a game and i want to render a map. I input the map cordinates from a bitmap and everything is nice an dandy when i try to draw a nice low res map (ie. 100x100 vertexes).

The problem is when i try to use a really high resolution map (ie. 1000x1000 vertexes) I get really bad performence.

I am already using a display list to display my map.

The function i compile into the display list is essentially a nested for loop which draws each triangle separately.

Psudo code;

START compiling display list

For X
Begin (GL_TRIANGLE_STRIP)
For Y
Vertex
Normal of vertex
Texture cord

Vertex
Normal of vertex
Texture cord
end for
glEnd ()
end for

stop compiling display list


I then go on to call it every time i move the camera. but with high res maps there it is really slow.

I know that people can make really high res maps display really effeciently. So what can i do to make my code super-efficient?

Thanks Guys,

Psiborg

05-08-2006, 12:11 AM
To render really big terrains efficiently you need some sort of level of detail algorithm (LOD). This is a huge subject and there are lots of techs out there, each with its own strengths and weaknesses. The trouble is that these methods are often complicated and can be difficult to implement if you don't have the background.

But to get things started, I'll just suggest a few things.

1. Visit your IHV website and read all the docs on performance. No one knows better than those guys how to optimize for their own cards.

2. Use culling to eliminate GPU processing of terrain outside the view frustum. Sometimes just limiting the distance of the far plane can help enormously (fog can hide the visible cutoff). Arrange your terrain in a hierarchical structure like a quad tree, for quick frustum bounds testing.

3. Consider using VBOs (vertex buffer objects) to store your (static) mesh data.

This is just generic sort of stuff. If you want some real meat and potatoes, do some research on LOD algorithms, and be prepared to do some serious reading ;) .

You can read about LOD at www.vterrain.org (http://www.vterrain.org) .

Best of luck to you.

Bill

CrazyButcher
05-08-2006, 01:33 AM
be warned that most LOD papers are quite old, and are pretty CPU heavy. I think the most gpu friendly way are geo mipmaps as seen in ogre/irrlicht. cause they dont need a lot of cpu interaction, and are friendly to render.

Robert Osfield
05-08-2006, 03:00 AM
1k by 1k is high resolution for a single tile, but modern hardware can still manange it at 60Hz if you pass it as vertex arrays. You should not us OpenGL slow paths for big objects - glBegin/glEnd is going to kill you straight away.

The most efficient way of handling a 1k by 1k by breaking it up into smaller tiles - this will allow view frustum culling to get rid of most of the geometry straight away, and also provide the data is better sized chunks for downloading to the GPU.

Also run a simplifier on each tile to remove triangles in flat areas, but be careful about the boundaries of each tile making sure that the heights are maintained.

Given the use of OpenGL fast paths, and the above tricks you could probably get away without any LOD with the performance of modern hardware.

Adding LOD will allow you to scale higher, and using paged LOD (storing tiles on disk and paging in/out as you roam the database) will allow you break the shackles of main memory and really scale up your database to terrabytes if you wish.

If you really fancy scaling things up then look to a 3rd party library for doing it, plenty of others have gone before you w.r.t terrain rendering.

Robert.

05-08-2006, 05:18 AM
Does the nested for loop cause any performence difficulty? or is it simply because of all my calls to glVertex3f...

05-08-2006, 06:34 AM
Hmm, why is a compiled display list slow? The Implementation could decide, how to get things fast!?

Robert Osfield
05-08-2006, 06:34 AM
Originally posted by <Psiborg>:
Does the nested for loop cause any performence difficulty? or is it simply because of all my calls to glVertex3f... The loop has no effect on the final performance due to use the display list. However, using glBegin(), glEnd() is an OpenGL slow path that is a serious problem if you want top performance.

You really really need to vertex arrays and combine this glDrawArrays or glDrawElements.
I'd recommend looking at an existing high level graphis toolkit, as it'll do everything w.r.t terrains you want to do and do so efficiently.

Robert.

Groovounet
05-08-2006, 11:04 AM
I am sorry but if he uses display lists, glVertex haven't any effect on performance. However, it's true that glVertex isn't recommand and moreover the display lists needs more memory than Vertex buffer objects. Finally, if you want dynamic mesh (as some terrain techniques need), you will call too many glVertex, computers could not handle glVertex in real-time for huge mesh like that.

Obli
05-09-2006, 07:50 AM
Originally posted by CrazyButcher:
be warned that most LOD papers are quite old, and are pretty CPU heavy. I think the most gpu friendly way are geo mipmaps as seen in ogre/irrlicht. cause they dont need a lot of cpu interaction, and are friendly to render. Well, saying that every DLOD method is more friendly to render is correct.
Geomipmap gives good results, takes very few programming skills to get running and can be preprocessed really fast but it does have some issues.
I've seen some DLOD-based systems providing somewhat higher quality at similar performance but they take more preprocessing time and are a bit harder to get running so it's always the same tradeoff.

Originally posted by Robert Osfield:
Given the use of OpenGL fast paths, and the above tricks you could probably get away without any LOD with the performance of modern hardware. I confirm that - I've hit over 30fps on a 1Mvertex mesh on NV25 using static VBO and no optimization. I was also killing the vertex cache very badly so I would say I could have gone far beyond 45fps... on GeForce4!

Originally posted by Robert Osfield:
You really really need to vertex arrays and combine this glDrawArrays or glDrawElements. Although DrawArrays saves some CPU work, it's far less efficient that DrawElements. I raccomand against it, especially in this context.