Hey there! I’m making a 2.5D platformer game that uses 3D tiles (basically voxels) and quickly ran into performance issues. With around 30k draw calls and 500k triangles (95% percent of which are unnecessary) I really need to change something So I read up quite a bit on voxel engines, made chunks (10x10x10) and let each chunk deal with its voxels like this:
- The voxels are placed by hand, so instead of being generated, they are scanned, aligned and then indexed on game start. The result is the same, though: the world consists of a 3d array of chunks, each containing a 3d array of voxels.
- Voxels that are entirely surrounded by other voxels are then disabled altogether.
- All the remaining voxels’ meshes are cleared and only the faces that are next to empty space are re-added to the mesh.
This all works, but I still have to combine all the meshes that are the same. Of course, i’ve been googling around and almost everyone advised to use the CombineChildren script, disabling it by default and then enabling it after the chunks have done their thing, but when I enable the script at the end of the chunk’s scripts, the game crashes. Is there another way to combine an object’s children’s meshes?
My second question is whether I should already notice a major improvement in the performance, even without combining the meshes. unfortunately, im actually getting a longer rendering time per frame at the moment (about 30% longer). This makes sense because i’m also getting an increase in draw calls, but… should i be getting an increase in draw calls, or am i doing something horribly wrong? I do get about a 90% reduction in tris and verts, though, so i guess at least that part of my code works xD
Here is the function i made that deals with generating the mesh of a single voxel:
function GenerateMesh(block: GameObject, position: Vector3) {
// clear old mesh
var meshFilter: MeshFilter = block.GetComponent(MeshFilter);
meshFilter.mesh.Clear();
// make vertices
var size = 0.5;
var vertices = [
Vector3(-size, -size, -size),
Vector3(-size, size, -size),
Vector3( size, size, -size),
Vector3( size, -size, -size),
Vector3( size, -size, size),
Vector3( size, size, size),
Vector3(-size, size, size),
Vector3(-size, -size, size)
];
// make triangles
var top_triangles = [
5, 2, 1,
5, 1, 6
];
var back_triangles = [
0, 1, 3,
1, 2, 3
];
var left_triangles = [
0, 7, 6,
0, 6, 1
];
var front_triangles = [
4, 5, 6,
4, 6, 7
];
var right_triangles = [
3, 2, 5,
3, 5, 4
];
var bottom_triangles = [
3, 4, 7,
3, 7, 0
];
// generate uvs
var uv: Vector2[] = new Vector2[vertices.Length];
for (var j = 0; j < uv.Length; j++) {
uv[j] = Vector2(vertices[j].x * 0.5, vertices[j].z * 0.5);
}
// set materials (these are defined globally per chunk)
var side_material = (CheckBlock(position + Vector3.up)) ? ground_side : ground_side_top;
block.renderer.materials = [
ground_top,
side_material,
side_material,
side_material,
side_material,
ground_bottom
];
// build new mesh
var mesh = new Mesh();
mesh.subMeshCount = 6;
mesh.vertices = vertices;
if (!CheckBlock(position + Vector3.up)) mesh.SetTriangles(top_triangles, 0);
if (!CheckBlock(position + Vector3.back)) mesh.SetTriangles(back_triangles, 1);
if (!CheckBlock(position + Vector3.left)) mesh.SetTriangles(left_triangles, 2);
if (!CheckBlock(position + Vector3.forward)) mesh.SetTriangles(front_triangles, 3);
if (!CheckBlock(position + Vector3.right)) mesh.SetTriangles(right_triangles, 4);
if (!CheckBlock(position + Vector3.down)) mesh.SetTriangles(bottom_triangles, 5);
mesh.uv = uv;
mesh.RecalculateNormals();
// set mesh
meshFilter.mesh = mesh;
}
The last question i have is about the materials. I think I did something wrong generating the UVs of the voxels, because the textures are rendered as a solid color. I’ve tried messing around with the UVs (again after reading up on them), the textures and the materials’ tilings, which changed some stuff, but didn’t make it render correctly. Does this make sense with the function above?
I would love to hear your input, cause i have no ideas left anymore. will continue browsing for answers in the meantime thanks a bunch guys!!