- Home /
Automatic mesh combine and texture atlasing
I was wondering if there is anyone who has built a script for combining meshes and their textures into atlases while also modifying the UVs to fit the atlas.
In this way I could build meshes and have they use their own textures (one texture per mesh) and then in Unity combine all textures and meshes that uses the same type of shader into one. Would just be easier to work in that way while also keeping the optimizations of texture altasing.
So the script would have to be able to combine meshes, their textures and modify their UVs and change all meshes to use the same material.
Maybe this is just a stupid idea, just something I thought might be nice.
just TBC, if you mean strictly for 2.5D in Unity, this is all done totally in 2DToolkit - a popular and magnificent product.
If you mean in general for 3D meshes. Yeah it's a great idea - surely, there must be various tools like this for sale already. And many companies small and large make their own tools like this, for specific situations.
Don't forget to that Unity does have an amazing thingy built in where you can flag things as static and Unity does a lot of this automatically. Eg http://docs.unity3d.com/Documentation/$$anonymous$$anual/DrawCallBatching.html
I'm talking about full 3D scenes. Yeah the static and dynamic batching are great, although the static batching breaks if you use one texture per mesh though. Therefor it would be awesome for workflow if I could chose what meshes should be combined (both mesh and texture).
$$anonymous$$aybe you wouldn't want to combine the meshes since this removes the ability to cull meshes that aren't in the view. But a tool to combine meshes textures into using the same texture atlas and material would be awesome.
Now I have manually made atlases of objects but you always end up with a too large or too small texture in the end. If this was done for you the workflow for the artist could be improved while keeping the optimizations.
If anyone has something like this please shout out! :P
Edit: posted as comment ins$$anonymous$$d of answer, sorry guys
You may be interested in this recent question ...
http://answers.unity3d.com/questions/340800/on-combining-two-objects-.html
"$$anonymous$$aybe you wouldn't want to combine the meshes since this removes the ability to cull meshes that aren't in the view. But a tool to combine meshes textures into using the same texture atlas and material would be awesome."
Yes, everything you say is exactly correct, as I already said. We have a number of in-house tools for just this. Is there anything in the Asset Store maybe??
"Now I have manually made atlases of objects but you always end up with a too large or too small texture in the end. If this was done for you the workflow for the artist could be improved while keeping the optimizations."
Something to cinsider is that in the "industry" if you will typically the "art department" will do all this, as a matter of their skill and engineering. Like, part of the nature of being "an incredible art department" is doing (very skillfully) what you describe manually. In a sense, there'd be no need for what you describe on BIG jobs but yeah it would be great for everyday use, for sure. Just as you say it's surprising there is not such an asset for sale on the Asset Store already:
handy texture convertor and re-uv-mapper.
Don't forget too that there is, of course, much professional (very expensive) "uv packing" software which is very expensive and used constantly as a daily critical tool, by top modellers -- I think the leading one is that french product I can't think of the name (uv master? uv pack or something?)
it is very very difficult to write tools like this that pack and rearrange textures - not to mention repainting them on the UV on the 3D models - indeed in verges in to lite-AI for sure.
"Edit: posted as comment ins$$anonymous$$d of answer, sorry guys" it should be a comment, not an answer. You can however convert comments to answers using the Zoop button the smallest one near your nickname on a comment.
Yeah combining meshes into one ins$$anonymous$$d of static batching might not be worth it since it sort of destroyes the culling.
It could work if there was anyway to offset and scale the UVs of each mesh to the correct values in the atlas. For instance I have three objects, one uses a 1024x512 texture and the other two uses two 512x512 textures. This would become 3 drawcalls as they are since they need to use one material each.
If the script would combine these textures into a 1024x1024 and offset and scale each meshes UVs to the correct positions and then assign the same material to all three of them static batching would work. All meshes count as one drawcall and culling would still work and the artists can work on their separate textures without atlasing them themselves.
But this might be difficult as you say... Damn :P
Answer by mrmadprofessor · Apr 08, 2013 at 07:26 AM
Thanks! Also while checking over this one more time I found a tool on the asset store that does this, I haven't tried it yet but I will. So if anyone wants the same tool check out,
http://u3d.as/content/ian-deane/mesh-baker-2/3DL
It's $55 but it might be worth it on larger projects.
Answer by LoganBarnett · Nov 17, 2012 at 12:35 AM
I did something like this for our character creator. There's a lot of moving parts involved, but I'll try to show you the relevant parts:
Part is just an enum to determine which character part to use, which turns into an index into the texture atlas. Any part potentially shows skin, so we have an edge case for those UV offsets.
MapToRange() comes from David Koontz's GoodStuff, which you can find here: https://github.com/dkoontz/GoodStuff
Once you've offset all parts used you can do your CombineMeshes() call as normal. Make sure to pass true as the second argument so it flattens everything into a single material.
I hope this helps!
void OffsetUvs(SkinnedMeshRenderer partRenderer, Part part, TextureAtlas atlas) {
var uvOffsetMesh = (Mesh)Instantiate(partRenderer.sharedMesh);
var skinIndex = -1;
var materialIndex = 0;
foreach(var material in (Application.isPlaying ? partRenderer.materials : partRenderer.sharedMaterials)) {
if(material.name.ToLower().Contains("body")) {
skinIndex = materialIndex;
break;
}
++materialIndex;
}
var partIndex = -1;
switch(part) {
case Part.Head:
partIndex = 1;
break;
case Part.Torso:
partIndex = 2;
break;
case Part.Legs:
partIndex = 3;
break;
case Part.Feet:
partIndex = 4;
break;
}
var skinUvIndexes = new List<int>();
var uvs = uvOffsetMesh.uv;
0.UpTo(uvOffsetMesh.subMeshCount - 1, i => {
uvOffsetMesh.GetTriangles(i).Each(vertexIndex => {
if(i == skinIndex) skinUvIndexes.Add(vertexIndex);
});
});
var uvIndex = 0;
uvs = uvs.Select(uv => {
if(skinIndex > -1 && skinUvIndexes.Contains(uvIndex)) {
uv = new Vector2(uv.x.MapToRange(0f, 1f, atlas.Dimensions[skinIndex].xMin, atlas.Dimensions[skinIndex].xMax),
uv.y.MapToRange(0f, 1f, atlas.Dimensions[skinIndex].yMin, atlas.Dimensions[skinIndex].yMax));
}
else {
uv = new Vector2(uv.x.MapToRange(0f, 1f, atlas.Dimensions[partIndex].xMin, atlas.Dimensions[partIndex].xMax),
uv.y.MapToRange(0f, 1f, atlas.Dimensions[partIndex].yMin, atlas.Dimensions[partIndex].yMax));
}
++uvIndex;
return uv;
}).ToArray();
uvOffsetMesh.uv = uvs;
partRenderer.sharedMesh = uvOffsetMesh;
}
Answer by baha · May 04, 2013 at 09:12 PM
Hi,
GameDraw has that feature plus modeling, texturing, sculpting, primitives, free assets and much more for only 45$ :)
Here is a video showcasing the optimization feature in GameDraw http://www.youtube.com/watch?v=glqbWsc4CXQ
GameDraw in the asset store https://www.assetstore.unity3d.com/#/content/2811
Answer by jmunozar · Jan 30, 2015 at 05:36 PM
Hey there, there's a free utility on the asset store, checkout: https://www.assetstore.unity3d.com/#/content/16888