Skip to main content
GameDev.net gamedev.net
🔒 Locked

Terrain Rendering Question

Started by Formski Jun 17, 2007 at 9:47 PM 6 replies 1.7k views
Original Post
Formski
Formski
I'm currently working on terrain rendering in DirectX 9 and have a basic heightmap system working, where it renders the entire mesh in one hit using vertex and index buffers and HLSL shaders. The mesh is somewhere between 180,000 to 200,000 triangles and my notebook doesn't miss a beat (running on an ATI Mobility Radeon 9700 with 64MB) My question is what would be more efficient to break the terrain down into smaller batches or simply send the entire mesh out and let the driver/graphics card handle any triangles not visible? My thinking is that drawprimitive calls are expensive, but so is passing info that isn't required. I'm going to have to break down the meshes into smaller chunks to handle certain driver/card combinations that have lower rendering limits, plus I want to throw larger heightmaps at it. Thanks Formski
Squirell
Squirell
The common solution to your problem is breaking the terrain into chunks and this is generally considered to be more efficient. Most major commerical games do this (although I can't back that up with a link). When you do this, you can store the chunks in a quad tree (or the equivalent) and cull out large blocks of triangles at once which is going to be faster than letting the video card do it on a per-triangle basis.

A good resource for different LOD techniques is vterrain . One of the most popular general techniques is geomipmapping . I would advise researching some and then trying it out.
Armadon
Armadon
I'd agree with Squirrel,
Breaking your terrain up and doing some Frustrum Culling (Which is basically, removing/not rendering triangles that aren't seen by the user) will already increase the performance.

VTerrain is a good resource for white papers and information on terrain rendering.

I hope this helps.
Take care.
Rasenger
Rasenger
I have a question thas has been bothering me: why we need more ways to drop triangles or bigger chunks out, won't backface culling and z-buffer already remove all unseen triangles? Is there even after those some triangles left that aren't seen?
Zao
Zao
The fastest triangle is the one that never enters the graphics pipeline.
In the case of backface culling, you need to transform every triangle to determine the winding it has.
In the case of Z buffering, you have to determine the depth of each fragment of the triangle.
If an entity fails broad-phase culling, it will not even be transformed, let alone rasterised.
Transforming say a simple bounding box is much much cheaper than transforming a whole mesh.
To make it is hell. To fail is divine.
mittens
mittens
Quote:
Original post by Rasenger
I have a question thas has been bothering me: why we need more ways to drop triangles or bigger chunks out, won't backface culling and z-buffer already remove all unseen triangles? Is there even after those some triangles left that aren't seen?

You don't want to be rendering a crap ton of vertices all the time if the visual influence they would have is minimal. If you have an entire terrain grid and the "chunks" that are far away from the eye position would, at most, be taking up a 10x10 pixel area on the screen, then why would you want to waste time rendering the, say, the hundred+ triangles that make up the geometry even if the user will, at most, only see a heavy influence of a few vertices if the chunk represents particularly jagged land. It's much easier to keep the farther chunks at a lower-level of detail so that the CPU cycles it takes to process the individual chunk LOD -- and you don't need a complicated algorithm to take care of this whatsoever -- can eliminate a whole bunch of triangles, vertices, and indices from ever reaching the rendering pipeline.

You don't need a complicated terrain rendering algorithm like people did a few years ago due to the huge power of modern graphics hardware, but just a little bit of work can save yoy hundreds (to, at times, thousands) of triangles from ever even reaching the pipeline.
jbarcz1
jbarcz1
Quote:
Original post by Formski

My question is what would be more efficient to break the terrain down into smaller batches or simply send the entire mesh out and let the driver/graphics card handle any triangles not visible? My thinking is that drawprimitive calls are expensive, but so is passing info that isn't required.

Thanks
Formski


Its actually the state changes that are expensive, not the DrawPrimitive calls. If you take care to pack all of your data into one set of buffers and textures, you can use multiple calls over the entire vertex and index range to submit your geometry without too much of a penalty, as long as you dont change render state. You can also mitigate the penalty a bit by merging adjacent ranges whenever you can find them. If you have a quadtree or something like that, you can pre-compute the VB/IB ranges under each node, and submit multiple blocks in one draw call when you find that an entire node is visible.

EDIT: And if you dont like multiple draw calls, there's always a dynamic index buffer.
Joshua Barczak3D Application Research GroupAMD
ET3D
ET3D
It's not really true that DrawPrimitive calls don't have a cost. Their overhead is equivalent to at least hundreds of vertex draws.

It's a balancing act. You'd have to play with the terrain block size to see what works best in terms of speed and CPU usage.

Note about CPU usage: in a simple program, you might gain speed with small batches at the expense of CPU usage. The overall result will be faster. However, if you then use that in a real program, where other threads may be competing with the rendering thread for the CPU, this will be overall slower.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.