Batching draw buffer calls

I have a 256x256x256 world. Divided into 8x8x8 cells, this is 32x32x32 = 32k cells.

Each cell, depending on voxel config, may have anywhere between 0 to 3 x 512 visible faces.

Right now, per frame, I need to do 32k distinct draw calls. Is there some way in webgpu to create an ARRAY of VERTEX_BUFFERS, so I can just make 1 call instead of 32k different calls ?


Try looking into wgpu instancing, it should be designed to do what you want.

You could also try to reduce the number of faces you actually have to draw. For example faces that are not visible because behind the camera or other faces could be removed. The general term for this is culling.

If you're writing some voxel-like game you could also look into voxel meshing in order to further reduce the number of surfaces you have to draw.

Yeah, I'm implementing voxel meshing. The problem with wgpu instancing is that the 8x8x8 cells can have different # of faces to be drawn.

Can't you use instancing per-face rather than per-cell?

If I am misunderstanding your solution, please clarify.

So the world is dynamic (user can destroy / add voxels). With 8x8x8 cells, it is clear what to update when a voxel is created/destroyed. If we have one giant buffer of the meshed faces, the re-meshing calculation is not obvious to me.

No. But if you can manage to sub-allocate your meshes into one big buffer (it doesn't have to be free of gaps), then you can use multi_draw_indexed_indirect to issue multiple draw calls based on an "indirect buffer" of ranges to draw.

1 Like

I feel like this is getting into the category of writing your own malloc/free for GPU memory (but managed from the CPU).