Improving performance of 3d Racing Game (Clipping/LOD)

Hi everyone, hope someone can give me some advice on this performance issue.
I am making this 3D racing game and plan to bring my terrain data which has been modelled with a 3d app.
Thats all fine and easily coded but what I would really like to know is:

How am I going to display this data keeping a good framerate if the mesh landscape is very detailed(which I hope it will be finally)
I have heard of LOD and clipping but have no idea on how to implement them, also I have heard of people saying break up the mesh and display it in pieces, but I think this would make it more awkward and I might get funny joins or flickering.

Please could someone give any advice on doing this, preferably so I can just import my single mesh landscape and use that.
Thanks for reading.

You should look into quadtrees to split your land up (don’t worry this causes no visual artefacts at all). Then you can use this to quickly work out what you can see with very little overdraw. Once this has been done then you can look into LOD type stuff, one good one is to take this blocks of data from the quadtree the final leaf nodes that should all be the same size and that fit in a regular grid and decrease their LOD when they are far away, you can also check the maximum height changes between LOD levels to make sure that some really ragged bits aren’t put into an LOD that id far too low detailed and so flatens off a ridge or peak. I thought of this all by my self but had problems with joins and things then I found someone had already thought of this Idea and called it geomip-maps, I think there is a .PDF on it at flipcode. I haven’t yet implemented this fully because of time but I have seen the results- very fast, very fast on high end hardware such as GeForce 2 (no slow roam algo or anything) future compatible, programmable LOD (user can choose different detail levels, and there are very little visual artefacts (these can be made more or less obvious depending on the detail level you set). This seems a very good modern solution and is fairly easy to program , also lots of optermisations exist.

Check out Hugues Hoppe’s page at Microsoft Research - http://research.microsoft.com/~hoppe/ . He has an article about dynamic terrain LOD, and his progressive mesh articles reference other terrain work, AFAICR. It’s a good place to start your research of the subject.

A simpler approach (and one I used) would indeed by cutting your terrain into tiles. Just remember that the edges of the tiles must overlap (for example, break a 513x513 terrain into 32x32 tiles of size 17x17). Also you should consider how you plan to texture this terrain. One big texture may not be enough. If you’re using smaller textures, it’s best if you don’t get to their edges, and if you do, use CLAMP instead of REPEAT, so as not to get colours from the other side of the texture, which will show ugly seams.

I assume that by “clipping” you mean culling objects against the view frustum. In the case of terrain tiles, this means checking whether tile is within the view frustum, and if not, not to display it at all. As Tim said, a quadtree is a good way to do this for a terrain, since it’s basically 2D. You then check against the right and left lines of the 2D view frustum.

You’re still left with all the terrain tiles in your field of view - even those very far away. If your terrain design and vehicle location result in only a small part of the terrain seen ahead at any time, you might also want to remove hidden tiles, i.e., those that are far away, and have a tile before them that hides them completely.

The oldest trick in the book is to use fog. The distance will be more fogged, and after a certain distance, where the fog reaches its full density, you’ll be able to stop rendering terrain.

[This message has been edited by ET3D (edited 05-07-2001).]

Thanks for the comments everyone.
ET3D you mention about cutting the mesh up into tiles. I assume you mean doing this in my 3D app.Do I cut them out in exact square blocks or or irregular sized meshs.

You can cut them any way you’d like, as long as the edges match. However, I have to admit that I was thinking about height maps when I described that, and not about a geometric object. That’s what I did - took the object, converted it into a height map (by loading the object into my program, and sampling its height at regular intervals), and then cutting it into tiles. But that won’t work as well if the ground has detailed materials (in my case, I had one large texture that described the colour of the entire terrain, so assigning texture coords wasn’t a problem).

It’s a good idea to have a height map, anyway, as it’s much easier to find the height at any point over it during the game than it would be with a mesh. It should also be easy to do other checks on it, like occlusions. Plus it can be rendered as strips, which are fast to render. So if it’s possible for you to convert the terrain mesh into a height map, it would probably be a good idea.

After you’ve cut your terrain/environment into managable pieces, (or while your artists are doing this) I recommend that you look at these two web sites:
http://www.markmorley.com/opengl/frustumculling.html

and
http://www.nvidia.com/developer, search down the page for the link to the “NvTriStrip Library”.

The first link is a good tutorial on frustum clipping, with a very fast and novel technique to get your frustum directly from OpenGL. Although it is missing a major optimization for axis aligned boxes- it sounds like this will do wonders for your frame rate issues.

The second link is a great resource you should already be aware of, but the specific NvTriStrip Library will allow you to take your terrain pieces and convert them to triangle strips- the fastest rendering primitive that OpenGL provides. I’ve only experience with the older version of the code that was not in library form- which did not handle meshes with different materials applied to different polys in the same mesh. If the new version of the code still has this limitation, then you need to break your new terrain pieces into one mesh per material and submit that to the triangle stripper.

You’ll end up with more individual things to submit to the OpenGL driver, but due to the frustum culling they will only be those things that are in front of the camera and they will be optimized for rendering.

For even more speed, you can perform a sort of all the final items being rendered, grouping all items with matching materials together. That minimizes OpenGL rendering state changes- prividing yet more speed.

Good luck,
-Blake