I have a complex mesh in Blender that features 10+ different materials that I’d like to render as-is in Unity.
For technical reasons I must stream the mesh from Blender to Unity but unfortunately Blender’s ability to have a single vert map to a number of materials (each having different uv) doesn’t appear to be possible with Unity…
Which is odd because if I import the same mesh into Unity via FBX and the Unity editor it will render beautifully without seams between the textures without adding any verts.
Currently the only way I was able to make this work was to manually split the vertices in Blender to enforce one-vert-per-uv and if I adjust the normals at the split verts then everything looks perfect but this is complex and expensive.
Since the Unity importer can make this work without splitting verts is there a way to programmatically accomplish the same via C#?
Thanks so much for a hint in the right direction! That one got me stumped!!
Vertices are not linked to any material, only triangles are. A normal mesh has only a single material and a single “triangles list”. However a mesh can have multiple “submeshes”. That means the mesh uses the same vertices but seperate index lists, one for each submesh.
However keep in mind that all vertex attributes stay the same for all submeshes. So you can’t have different UV0 coordinates on the same vertex for different materials. If you need this the vertex has to be splitted. Unity does this automatically on import. In general if any vertex attribute is different for two triangles which share that vertex it has to be splitted, even when both triangles use the same material / blong to the same submesh. That’s why a cube has 24 vertices instead of 8 since each side need to have it’s own normal. Since each of the 8 corners are shared by 3 different sides you need 8*3 == 24 vertices.
To manually set the triangles for a submesh you first have to set vertices, then the subMeshCount to the number of submeshes you have and finally use SetTriangles for each submesh index to define the triangles for each submesh.
The used MeshRenderer need to have as many materials as there are submeshes in the mesh. The order is the same. So submesh0 uses the material at index 0.
It turns out that I’ve been using this method (with ‘subMeshCount’ and SetTriangles()) in the past and I get perfect results if I set normals to the split verts the same.
So to confirm… I guess there is no other way to do it eh? Split verts are indeed a must?
If so it is just so odd that the Unity importer makes this happen without adding verts… perhaps it does split the verts but adds an order of indirection so that the C# code can still refer to the mesh using the original (smaller) mesh indices?