What is the best way to optimize character armor/cosmetics?

I am beginning to work on a standard clothing and character customization system for my game (similar to the clothing systems in most RPGs like wow, darksouls, skyrim, etc) where players can mix and match any combination of armor/clothing pieces.

So far I have two base character models that were created with MakeHuman, so the player can choose a male or female, and then scale the bones to alter height and size, and also choose from a few different hair styles/colors, etc etc… The clothing and armor is created with the MakeHuman models in Blender by using the shrink wrap modifier, so that it fits the model well and shares the correct vertex groups so the clothing is properly is animated when attached to the base model.

But now I am struggling to determine what is the best way to set things up so that every piece of armor can share a material and be batched into a single geometry.

I had two ideas so far, but I am not quite sure the first solution would work, and I’m not sure if the second solution may be making things more difficult than they need to be

  1. Put every piece of armor/clothing and every cosmetic option into a single texture atlas, so that any combination of clothing can be batched easily at run time when the player model is initiated.
    This seems like the obvious and best solution, but I will be frequently adding new armor and cosmetics options, so I think that would then require manually altering the texture atlas, as well as the texture coordinates for every piece of clothing using that texture atlas anytime I want to create a new piece of armor.

  2. I could try to make some utility that compiles a collection of textures into a single texture atlas automatically, and then modifies every model’s texture coordinates to match the new texture atlas. Then I could run that utility anytime I create a new piece of clothing/armor that needs added to the texture atlas.

The second option seems like it would be the best so far, but I think that could also be a somewhat time intensive task to create such a utility, and I am not sure if I may be overlooking a simpler solution, or if such a utility may already exist - so I thought I would ask for some input here before I start coding. Any advice or ideas would be greatly appreciated :slightly_smiling_face:

1 Like

we would like to know best way too.

  1. Are you sure you want batch it all into single texture atlas?
    i think it might be just “too big” for a lot of armors. Am i wrong?

  2. i think there already is something like this. Batch related utility.

Still i could say something that might be interest for you:

The clothing and armor is created with the MakeHuman models in Blender by using the shrink wrap modifier, so that it fits the model well and shares the correct vertex groups so the clothing is properly is animated when attached to the base model

In Blender there is something like copy weight, and can set it to “from character to armor” way with interpolating properly, that could help to avoid “overlaping”

Also one thing that could speed up FPS + avoid overlaping is: creating pixel discard map for character body that could discard character parts of body that is under cloth/armor.
But since it gonna be atlasmap, then it might be bad.

Last thing is 3.3 related. there are morph shapes. i think you already seen video i posted with “character lipsync + topic how to do it”. you can use it too. But again, if you want batch it all, then idk if morph will not break, thats why anyway we have “head” split from body.

In summary, i think TextureArlas is good option and i think there was point 2. utility already.

But Im not sure if for a lot of variants, it will work, and also dont know what related “AAA” games do really about optimizing it this way.

One solution to this above “predicted issue” come in mind for me, if there would be “too much variants for one texture atlas” is just put more texture atlas, and batch what is needed, so one character would be 1 Geom(since 1 atlas for all) and second would be 2 Geoms(since some of armor would be from second atlas)

OFC you cant batch it all in one geometry(each character would need own anyway, but still much less than each part of armor as geometry), because then animations might be broken, and also other geoms should be Armature related, so i hope animations will not break anyway.

1 Like

MakeHuman includes a Blender plugin called MakeClothes. I’ve never used it, but it looks like it might be helpful to you:

Documentation:Clothes - MakeHuman Community Wiki

1 Like

Thanks for the replies.

I never heard of MakeClothes, but I’ll have to get the plugin and give it a try soon.

I was wondering this as well. Would there be any drawback to using a large 10,000 x 10,000 sized texture atlas that is shared by 100 individual clothing models? As opposed to having 100 clothing models that each have their own material with 1,000 x 1,000 sized textures that cannot be batched.

Assuming there is no performance drop for using a massive texture, then this seems like a good solution.

Do you mean the option to “Batch with Texture Atlas” in the SDK? Or are you referring to a different utility. (unless I’m wrong, I thought that the Batch with Texture Atlas option broke the vertex groups for the model, unlike the standard batch… but it was a long time ago i tested this so I could be wrong).

Ihaven’t done much with morph anims yet myself, but if the morph anims are not batchable then that should be alright, since only one geometry (the human model with skin material) will have morph anims, so I could still batch the rest of the clothing and retain the vertex groups for the regular anim control.

However I wonder if it would be possible to update the batching code to also account for the morph animations. Morph animations were added long after the batching code, so I suppose it makes sense that batching breaks morph animations as of now, but I wonder if this could be a feasible task to update the batching code to account for morph anims?

1 Like

Do you mean the option to “Batch with Texture Atlas” in the SDK? Or are you referring to a different utility. (unless I’m wrong, I thought that the Batch with Texture Atlas option broke the vertex groups for the model, unlike the standard batch… but it was a long time ago i tested this so I could be wrong).

you can look at JME TextureAtlas TestCase. im not sure if this is the same, probably yes.
When you will look at this Test, it have all models properly UV and using one texture.
(or maybe im wrong and it just generate TextureAtlas but dont change coords, but then you might just need adjust coords to match atlas texture)

there is:

Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048);

you said:

I could try to make some utility that compiles a collection of textures into a single texture atlas automatically, and then modifies every model’s texture coordinates to match the new texture atlas.

but hey, it already do that right?

that already generate texture atlas and change coordinates of models to match it, so you might want use it.

even if you dont want it all, you can just use part of its code.

when i look at code there is something like:

private static void applyAtlasCoords(List<Geometry> geometries, Mesh outMesh, TextureAtlas atlas) {
    int globalVertIndex = 0;

    for (Geometry geom : geometries) {
        Mesh inMesh = geom.getMesh();
        geom.computeWorldMatrix();

        int geomVertCount = inMesh.getVertexCount();

        VertexBuffer inBuf = inMesh.getBuffer(Type.TexCoord);
        VertexBuffer outBuf = outMesh.getBuffer(Type.TexCoord);

        if (inBuf == null || outBuf == null) {
            continue;
        }

        atlas.applyCoords(geom, globalVertIndex, outMesh);

        globalVertIndex += geomVertCount;
    }
}

so i belive it also change geom coords to match atlas.

just look at TextureAtlas class in JME

edit:

still, im unsure what about animations, but since TestCase show models that should have animations, it might maintain them properly, you should check it.

so the first thing i would try would be if animations work after batchWithAtlas.

Please note myself im interested in batching this way(except head that will have morphs) so if you will have it working with animations, let me know how you did it(or if it just work) :slight_smile:

1 Like

I don’t see why even batch custmized models. I would expect to batch similar, repetetive objects and not customized. Also why use an atlas? Using so few textures is absolutely doable.

As for the MakeCloth mentioned ITT, it isnt doing what you arent doing already - it duplicates body mesh, modifies it and lets you import a cloth for the purpose of fitting it onto a human model. The only advantage of it is automatic weight painting, which you have already handled.

1 Like

For a single player game, it would probably be okay to leave the customized models unbatched without any performance issues.

But the problem arises whenever there is a multiplayer match with up to 20 player who have each have on a unique armor set, with different hair, eyes, eye brows, eye lashes, and weapons. That totals up to be at least 10 unbatched geometries (or more if you include small armor pieces like gloves, shoulders, boots) being rendered on the gpu per player. Then if you factor in that many players in one place also means many more spells and particle effects, then it becomes even more important to reduce the total object count on the gpu.

So it isn’t necessarily the most important thing to add right now, and the clothing system can still work using individual textures for each piece of clothing/armor. But finding a way to batch the customized outfits by having all of the individual pieces share a material would drastically help to improve the framerate for lower spec devices playing in a hectic multiplayer match.

I got an error when i tried to batch a few different pieces of PBR clothing in the SDK saying that the model has invalid textures. But the texture atlas batching still works for materials using the old phong lighting shader. It also completely whitewashed the texture colors so it looks very strange, and it just deleted the animation and skeleton control. So I don’t think it currently works to effectively batch a node of geometries with a texture atlas unfortunately.

I also just realized that the way the TextureAtlas.batch() method works is still a bit off from what I’m looking for. That method creates a new texture atlas for each batched character model - so this would potentially take up a large amount of memory to store a new 4k sized texture atlas for each player.

My initial idea was to take the whole collection of armor/clothing models before the assets are compiled, then use those to create a large texture atlas and alter all of their texture coordinates. then they can be batched normally when the unique character models are assembled at runtime, as they will all share a material already.

1 Like

i think it would be easy to make it for PBR, it just use different texture names :slight_smile:

It also completely whitewashed the texture colors so it looks very strange, and it just deleted the animation and skeleton control

that sounds bad, if animations dont work, then it cant be used for characters…

That method creates a new texture atlas for each batched character model - so this would potentially take up a large amount of memory to store a new 4k sized texture atlas for each player.

hmm, but think about this way: you create offscreen Node with character and all cloth elements, you make TextureAtlas for it(one material for all) and later you just apply this material(textureatlas based material) to your character geom(yes this geom might anyway need to know tex-coords, but you can also copy it from prepared batched models).

so based on what you said, i see solution, but i still dont see how to solve animations issue :neutral_face:

1 Like

Now I haven’t read the whole post thoroughly and I will face that challenges as well in the future, but we should first talk about texture atlasses and then batching:

This works fine, provided the maximum texture size of the GPU is supporting that. Some games even only use one “Megatexture” or “Gigatexture”, which contains everything.

Now there is one drawback: Mip-Mapping and LODing. For instance: If far enough, the armor normal map could vanish, the resolution can be smaller, etc pp. That’s benefits you loose when batching all together.

You could bypass this by having two batches: Near and Far, but then you could also try something like instancing or only batching the whole playermodel together (because if not, would animation even apply all the other geometries?)

Actually I suspect this is your best bet: batching every player separately with what they just wear. You can make those textures one atlas, if you want, and then everything LODs and MipMaps together, but it’d still be one drawcall per Player, however not 10 (Head, shoulders, … ).

It’d try it and see how it works out. Unless you aim for 100 Players close quarter PvP combats, I guess that should be enough already. I wonder how you can configure that the animations work, though, that was my concern. Especially for Skirts which might even need their own movement.

1 Like

I think none of the “built in” utilities will work for doing this with animation because the only way they could work is in such a narrow use-case… as compared to the amount of code necessary to support them.

It’s going to require some special jiggery-pokery to combine the separate animation buffers, animation clips, etc… Doable but non-trivial… and would only work if the models were setup in a very specific way (animated together in the first place or animated in a compatible way, etc.)

1 Like