Chunking vertices

Started by
4 comments, last by ET3D 16 years, 6 months ago
Hello all i'm having some trouble understanding how i would go about batching vertices into smaller chunks. At the moment i have terrain of size 129 x 129 and this is just stored in an array of floats i render the entire thing in one call, but i get (obvious) problems when the terrain gets above 255 x 255 vertices. The solution to this would be to store the terrain in chunks. I just cant figure out how i would do this in my head, would i use more than one array of floats to store it or could i still store the data this way and just render it differently. Would i need to use multiple Vertex and Index buffers? If i used a really small chunk size of say 7 x 7 would the multiple calls to Lock not slow down my loading time?
Advertisement
You can easily get round the 64k indices limit by using the second parameter to DrawIndexedPrimitive() - BaseVertexIndex. That means you only need one vertex buffer. You can probably reuse the same index buffer for each draw call too.

Since you're only using one vertex buffer you'll only need one lock call too, although several calls to lock shouldn't noticeably slow down loading.

You want to split up the terrain to avoid rendering bits of terrain that aren't on screen. However giving the graphics card less than around 1000 primitives per draw call will tend to bottleneck you on the CPU, and a few more won't harm so I'd say the chunks should be at least 64x64 verts, and 128x128 or more isn't excessive. Try some different sizes and see what works best for your setup.
Quote:Original post by Adam_42
You can easily get round the 64k indices limit by using the second parameter to DrawIndexedPrimitive() - BaseVertexIndex. That means you only need one vertex buffer. You can probably reuse the same index buffer for each draw call too.

Since you're only using one vertex buffer you'll only need one lock call too, although several calls to lock shouldn't noticeably slow down loading.

You want to split up the terrain to avoid rendering bits of terrain that aren't on screen. However giving the graphics card less than around 1000 primitives per draw call will tend to bottleneck you on the CPU, and a few more won't harm so I'd say the chunks should be at least 64x64 verts, and 128x128 or more isn't excessive. Try some different sizes and see what works best for your setup.


Ok thanks for the advice, if i was to use 128 x 128 would i just use multiple arrays of floats to hold the data but render it the same as i would i large chunk of data or would there be another better alternative?
For the CPU side it really doesn't matter how you store it, one big array for the whole terrain would be fine. You just need to be able to split it up into chunk sized pieces when you put it in the vertex and index buffers for rendering purposes.

The vertex buffer will need to contain some duplicated verts down the edges of the chunks to make them join up correctly as you can't just index them due to the 64k index limit.

For each chunk you need to keep track of the vertex buffer offset, and the index buffer to use (if some of the chunks are smaller than full size you'll need at least two different index buffers). You should store a bounding box with them too for frustum culling.
Quote:Original post by Adam_42
For the CPU side it really doesn't matter how you store it, one big array for the whole terrain would be fine. You just need to be able to split it up into chunk sized pieces when you put it in the vertex and index buffers for rendering purposes.

The vertex buffer will need to contain some duplicated verts down the edges of the chunks to make them join up correctly as you can't just index them due to the 64k index limit.

For each chunk you need to keep track of the vertex buffer offset, and the index buffer to use (if some of the chunks are smaller than full size you'll need at least two different index buffers). You should store a bounding box with them too for frustum culling.


so i would store it anyway cpu side but when writing to the VB and IB i would write the values in with a offset to both, and i wouldn't have to have more than one vertex and index buffer? Unless the terrain chunks where different sizes like you said.

In that case how would the BaseVertexIndex help the situation?

I guess it would make sense to store the terrain in arrays of floats the same size as the chunks to simplify calulations.
You don't really have to store things on the CPU side.

As for the base vertex, the idea is that you can store different meshes (in this case terrain blocks) in a single vertex buffer, and select the one you want by offsetting into the buffer (for example, using 129x129 vertices, one will start at 0, the second at 16641, the third at 33282, etc.). Assuming all terrain blocks have the same structure, the same index buffer can be used for them.

This topic is closed to new replies.

Advertisement