I am building a voxel engine with a similar mechanism to minecraft(yes, I know...).
It works by loading and unloading individual chunks of 16*64*16 cubes each in a square grid around the player. This works fine for small render distances - like a 9x9 square grid of chunks. However, since updating a single vertex buffer entirely with a new mesh of millions of blocks each time a chunk is loaded/unloaded is inefficient, I have designed it so that each chunk has its own VB of fixed size, and rendering the entire world is basically looping through all the buffers, using d3dDeviceContext->IASetVertexBuffers(...)
.
When I increase the render distance, say to a square grid of 11x11 (around minecraft's large render distance), creating the vertex buffers simply cannot proceed beyond a certain point, and d3dDevice->CreateBuffer()
returns E_OUTOFMEMORY.
So my question is: How do i manage the memory usage of the vertices, to both maintain good FPS (not using a single buffer for the entire terrain) and to have decent memory usage?
Additional Details: My vertex datatype is a struct composed of x,y,z coords, u,v texture coords and 3 normal coords. I know it can be improved in ways like a single byte for normals, since in voxels there are only 6 possible directions, however this will come later.
The fixed size of each chunk's vertex buffer is 16*16*64*18 vertices (16*16*64 blocks with a maximum of half of the sides showing, or 36/2 vertices max per block). This could also use some work, as each of these buffers is around 10MB.
How do games like minecraft handle this amount of data at once? (not to say i am using 64 blocks high chunks, where minecraft has 256) I have briefly considered using points as vertex shader inputs and expanding them to cubes in the geometry shader, to save 87.5% of the space, but this seems rather intense on the GPU.