I’m creating a minecraft style voxel game and have hit a slight performance issue on the javascript side, with applyToMesh taking a long time.
Currently I’m generating a chunk mesh on each block placement/removal which creates an entirely new mesh. Here’s a sketch of the code which does this:
// meshData has been generated by iterating through the chunk...
let mesh = new BABYLON.Mesh('chunk', scene);
let vertexData = new BABYLON.VertexData();
vertexData.positions = meshData.positions;
vertexData.indices = meshData.indices;
vertexData.normals = meshData.normals;
vertexData.applyToMesh(mesh);
I’ve profiled the code and a significant bottleneck is the applyToMesh function. In fact, this takes roughly as long (~30ms for a 32x32x32 chunk worst case scenario) as it takes to generate the positions/indices/normals arrays in the first place.
It looks like this function is slow because it is creating a vertexbuffer object and copying a lot of data from the vertex data object. This seems like a lot of unnecessary overhead, so would my best approach here be to try and create a vertexbuffer directly, or is there another way which is better? And if so, is this supported by the engine or will I have to use unsupported apis/properties for this? No problem if I have to hack the engine, I just want to make sure I have the right approach.
Hi @tyro and welcome to the forum.
Any reason why you are using a custom mesh approach? Not knowing very much at all about minecraft I would have thought using individual blocks would allow you to mine easier? Babylon.js Playground
Minecraft style engines typically render the entire chunk (16x256x16 blocks for Minecraft) as a single mesh as this significantly reduces the render time. The trade-off (as you state) is that adding/removing blocks is slower computationally, however it’s a trade off that works for this case - see here for more info.
ps. Minecraft classic uses this engine which I believe also uses the custom mesh approach with vertex data.
By re-use i mean that you shouldn’t need 65k boxes in your scene,
superset a position array saying “at position x/y/z, a box is located with this uv(texture)”, then re-use geometry, move them around depending on your player’s position.
Minimalize the original box if possible, remove any meshData you don’t need. (it’s replicated in the SPS mesh, bloating memory that isn’t used)
Thanks for the reply! I don’t think SPS is a good fit for me here as it only uses one material and doesn’t seem (?) to support shader attributes which I would need to apply on a per block face basis (for flood fill lighting).
However, I will check out the SPS source to see if it has a different approach to creating the mesh vertexbuffer.
@tyro may also benefit by looking at the code for open source Minecraft-inspired games like Minetest. It is definitely a cool idea. I am hoping to do something similar with BabylonJS after I advance my coding skills a little more.