Voxel Engine Vertex Buffer Wastage

Started by
4 comments, last by lomateron 10 years, 9 months ago

Hi all,

In my voxel engine, I have a vertex buffer for each 16*64*16 chunk. The vertex buffer is created at the maximum size needed (i.e. it has space for the whole chunk full of blocks), however most of the chunks are only half-full. This is done because each block has its own index in the vertex buffer (I have an equation to get the index), and if I made the VB smaller, it could result in access violations when adding blocks, even if the chunk was nowhere near full.

This results in huge memory wastage.

How could I minimise this wastage? I thought maybe I could have no indexing system, and just dump all the vertices in the VB, and make the VB only the size needed. But then I would have to recreate all the vertices and the VB every time I add a block, which could affect performance.

What is the best way to solve this problem?

Advertisement

The best way is to understand the problem. For real. Count the blocks before allocating. When you compute block indices just discard the block position in the chunk and use the sequential number of blocks you've written to VB.

Yes, modifying a block will hiccup. There are at least two ways to minimize the problem:

  • Update only a part of the VB/IB
  • Have an extra texture of "block alpha" so it just takes to write a texture for making a block disappear (might fit in buffer on shader profile 4).

But I don't think you will have to do that considering how rare interaction is. Keep in mind dynamic chunks should be around less than 4MiBs according to a recent AMD paper; the driver keeps around a temporary buffer to optimize this situation. As long as your update is less than that I think there's a good chance it will come at very low cost, even on a per-frame basis.

Previously "Krohm"

Yeah, you need to rebuild the buffer each time you add/remove a voxel. Modifying only a part of the buffer is practically impossible for adding or removing vertices. It will work for changing/updating lets say texture coordinates, but even then you need to store additional data to find the correct location in the buffer.

The buffer should only contain vertices of visible faces (dont add faces facing an opaque voxel) if you didnt already know that.

If the cost of rebuilding the vertex buffer(s) is too high, you can have multiple "graphics chunks" per chunk. So if you game logic side chunk is 64*64*64 and its being edited A LOT (you could even detect this dynamically and adjust the size of your graphics chunks for this chunk) and the generation of buffers is expensive, you could use lets say 4*4*4 16*16*16 graphics chunks to represent it, making it a lot cheaper.

o3o

Ok thanks guys.

I am using the idea suggested - get the size of the chunk before allocating a vertex buffer. Memory usage went down from ~300MB for 25 chunks (yes, a hell of a lot) to ~22MB. Much better. For 256 chunks (16x16) it takes ~40MB memory - shows how much savings you get from culling unseen faces..

The performance loss from creating new vertex/index buffers whenever a chunk is modified is negligible. I placed blocks as fast as I could click, and the FPS remained pretty much constant at around 170FPS. I might implement some feature later which makes the vertex/index buffers slightly too big (room for about 50 more blocks), then extend it when it gets full, so I am doing a lot less buffer re-allocations.

Re-creating the buffers when I modify chunks also means I can make static buffers, which should give a performance gain above using dynamic buffers.

Once again, thanks for the advice.

Have you tried running the application for a long time? Normally the issue with many allocations is the fragmentation of the video memory, which might not manifest itself until a sufficient number of allocations are seen.

Most likely there won't be any issue, but I just thought I would throw that out there.

I only know about D3D10

create a 3D texture with DXGI_FORMAT_R8_UINT format

a texel represents the 3D space location of a cube and the type of cube, only 255 types of cubes, because 8bit texel

render using intancing cubes, the number of cubes is the same number of texels that there is on the 3D texture

This topic is closed to new replies.

Advertisement