Efficient Terrain Tiling (GL/Xbox/GameCube)

I am RE-implementing our games tiled terrain heightfield renderer. I cant change too much
as I have to finish this up by friday. (beta following tuesday)

we currently use a metapatch/tile/node system (which i cant change at this stage)

definitions:

METAPATCH: 9x9 nodes forming 8x8 quads
TILE: 3x3 nodes forming 2x2 quads sharing a common material
NODE: heightfield vertex (normal/pos,color,UV)

METAPATCHES are where frustum culling occur.

The Old renderer would build vertex buffers
during the render call (inserting appropriate clamped UV’s), using a premade index buffer, rendering a tile at a time. My 1st optimization was to generate a single vertex array (in host mem) and an index buffer per material, lowering the number of state changes.

Next, I tried getting the entire terrain into one vertex buffer as a preprocessing step (using shared, wrapping UV’s) and then in the render call - generating an index buffer per material, rendering a batch per material. this worked good EXCEPT for texture filtering + wrapping was causing seams. cant use uv clamp because i wanted a shared vertex buffer for the whole terrain. oh well…

then I started working on a scheme where i would dupe the verts, giving them unique UV’s (not wrapped) so i could use uv clamp, causing trilinear filtering to look good.
at first i was going to use 1 big vertex buffer again, but that will cause me to use
32 bit indices. then i thought i would use a vertex buffer per metapatch, unfortunately that will increase the number of batches significantly, as i will have to render per metapatch PER material.

this particular renderable needs to work on PC/OpenGL, XBox(Pushbuffers or DX), and possibly gamecube. we have a ps2 port, but that one is easier since the vu’s have logic
and can generate the uv’s appropriately using that logic.

is there a texture addressing scheme between GL_CLAMP_TO_EDGE and GL_WRAP (with equiv on Xbox/GC) that would let me use uv wrapping (so i can have shared vertices) and not allow filtering to wrap (preventing seams) ?

probably something else simple im missing…

anyone else have any other ideas to minimize batches/statechanges AND getcorrect rendering without changing the fundamental heightfield architecture (again i have to get this done by friday and all the source art is already done)

thanks,

mtm

Michael T. Mayers
Senior Engineer
Jaleco Entertainment
mmayers@jaleco.com
michael@tweakoz.com

ps.
if it helps some screenshots of the terrain in question is at http://www.goblincommander.com

Try this scheme:

then I started working on a scheme where i would dupe the verts, giving them unique UV’s (not wrapped) so i could use uv clamp, causing trilinear filtering to look good.
at first i was going to use 1 big vertex buffer again, but that will cause me to use
32 bit indices. then i thought i would use a vertex buffer per metapatch, unfortunately that will increase the number of batches significantly, as i will have to render per metapatch PER material.

Allocate two smaller vertex buffers and two smaller index buffers ( see VBO )

Instead of one giant buffer stream into a smaller one so you can use 16bit indices. When you small buffer is filled submit it too the card, start writing to the begining of your second buffer. When that one is full submit again and swap back to the first bufer. Hopefully this will give you some parrellism.
( see NV_fence, APPLE_fence, ATI? ).

Guy

Maybe you can use a big buffer and pray that for a given material the range of used vertices fit in 16 bits, Just apply a 32 bit offset before rendering.
If a material don’t fit in a single 16bit buffer you can use more applying each time a different offset, imho it’s far better to have static vertex buffer and a little more element buffer than a streamed vertex buffer.

Hope it helps.
Sorry for by bad english.