- Home /
Problem with CombineMeshes on large number of meshes
I made model generator for voxel objects. I want to combine all voxels generated as simple cubes to one mesh. For small model it works fine, but when i take big model same code works wrong.
public void OptimizeMesh()
{
if (myMeshFilter == null)
myMeshFilter = gameObject.AddComponent<MeshFilter>();
// сбрасываем положение в 0 для корректной постройки меша
Vector3 pos = transform.position;
Quaternion rot = transform.rotation;
transform.SetPositionAndRotation(new Vector3(), Quaternion.identity);
List<Mesh> submeshes = new List<Mesh>();
List<CombineInstance> combiners = new List<CombineInstance>();
List<Material> objMaterials = new List<Material>();
// объединяем воксели в группы по метриалам
foreach (KeyValuePair<int, List<Voxel>> matGroup in voxelsGroupedByMaterials)
{
combiners.Clear();
// каждый воксель из группы добавляем в общий объект
foreach (Voxel v in matGroup.Value)
{
CombineInstance ci = new CombineInstance();
ci.mesh = v.GetFilter().sharedMesh;
ci.subMeshIndex = 0;
ci.transform = v.transform.localToWorldMatrix;
combiners.Add(ci);
}
// присваиваем группе материал по id
objMaterials.Add(MaterialManager.GetMaterial(matGroup.Key));
// формируем меш из вокселей одного материала
Mesh mesh = new Mesh();
mesh.CombineMeshes(combiners.ToArray(), true);
submeshes.Add(mesh);
}
List<CombineInstance> finalCombiners = new List<CombineInstance>();
foreach (Mesh mesh in submeshes)
{
CombineInstance ci = new CombineInstance();
ci.mesh = mesh;
ci.subMeshIndex = 0;
ci.transform = Matrix4x4.identity;
finalCombiners.Add(ci);
}
MeshRenderer rend = gameObject.AddComponent<MeshRenderer>();
rend.materials = objMaterials.ToArray();
Mesh finalMesh = new Mesh();
finalMesh.CombineMeshes(finalCombiners.ToArray(), false);
myMeshFilter.sharedMesh = finalMesh;
// возвращаем изначальное положение объекта
transform.SetPositionAndRotation(pos, rot);
}
Any suggestions what might be wrong?
Answer by Bunny83 · Nov 21, 2020 at 05:03 PM
Set the indexFormat of your target mesh to 32 bit.
Though that said using CombineMeshes for things like voxel games is extremely inefficient. It would make more sense to directly combine / generate / load your data into one mesh. Yes, it requires a bit more work but you would avoid creating tons of gameobject, and meshes which you would need to destroy again once combined. Of course if you combine premade models this way is fine. However if the individual models are generated from voxel data, it makes more sense to directly generate the vertices and indices inside the target mesh.
In this code i'm remove optimization, but i do it. I remove all internal cubes sides and weld coinciding verts.
Yep, it helps me) Now code looks like this:
$$anonymous$$esh mesh = new $$anonymous$$esh();
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
mesh.Combine$$anonymous$$eshes(combiners.ToArray(), true);
submeshes.Add(mesh);
Thanks)