[Solved] How to optimize my custom characters?

All right so here’s my problem. I have a character model that I can customize (so the model can have different hair, different eyes, etc…). Each part of my model that can be customize is its own geometry with is own material. By changing the diffuse color in each material, I’m able to “tint” the diffuse texture of materials to any color I want. Now, my game is an MMO, so there can be multiple of these custom characters on screen at once, which brings me to the core of my problem; my game’s FPS goes way down when there are multiple characters on screen. This is obvious since each character as many geometries (about 17 per character currently).

I’ve looked into multiple ways to optimize my character models without success of finding a proper solution.

Batching the geometries would make it so that the character would have one geometry with only one material. This would work, however I would need to combine all textures used on the character into one. Now I know this is possible using a TextureAtlas, but now my problem would be that I wouldn’t be able to tint my textures to any color I want like I’m doing right now.

So what I’m looking for is a solution that would both optimize my scene so that I could have a stable FPS as well as keep my current features. Does anyone have any ideas of what I could do?

If I we’re to take the TextureAtlas route described above, would creating my own material shader that can take multiple diffuse colors so that I can then apply them to different parts of my model work?

1 Like

VertexColor is your friend. It’s not without drawbacks as well though, but you already will have batching so it does not matter, almost. For slow machines you just have to give option to not display customization at all.

Regarding shader with multiple diffuse colors - it will work but will be quite a pain to make.

You can generate the texture atlas dynamically after the character has been customized. Either the TextureAtlas class or ImageRaster can help with that. You can tint the texture before you write them to the atlas.
Alternatively, you can put all the textures in a texture array and use vertex color to tint specific features as well as specify which index of a texture array to use. That way you can use the same material for all characters.

Correct me if I’m wrong, but you’re probably attaching geometries to the bone attachment nodes of a base model.
Batching would break the animations cause the attachment vertices wont have the correct weights, if I understand correctly.

I guess the assumption is that there’s a single skeleton for all characters and all parts of the character already have correct bone indices / weights.

Ok, interesting, is that easy to do from the code? For instance if the character has a helmet (all rigid), how should the buffers be filled to make the animations after batching look exactly as before batching?
I guess all vertices of the helmet could point to the same index from a vertex at the top of the head and make it fully influenced by it, but I’m not certain how. I’ll need to look into it. :confused:
Sorry OP for asking, I’ve a similar situation and it seemed a good place to comment.

Thanks for the suggestions. I think I’ll start looking into the tinting prior to putting them in the TextureAtlas first, as it seems to be the most straight forward solution. If that dosen’t work I’ll try the vertex colors.

That is correct. All parts of my character are exported at the same time using the same skeleton. So, in one file I have an empty node with the skeleton and animations. In a bunch of other files, I have the parts of my character. All I do is simply attach the parts to the empty node and everything works.

No problem at all.

Be aware that making new texture atlas per character will eat your GPU memory very fast.

Just a small update for anyone that might be interested. After taking in consideration prog’s comment about how texture atlases would eat my CPU, I decided to try out the texture array with vertex colors first. And that worked like a charm! I derived a material definition from the Lighting one to be able to take a texture array instead of a regular 2D texture. I then derived the Lighting’s vertex and fragment shader to be able to support the texture array. Then in my game, when I batch my custom character, I just take note of which order the geometries we’re batched in and I set the texture coordinates and the color buffer of the new mesh accordingly. I then create a new material using my custom material definition, set all appropriate values in it, set it on the geometry and VOILÀ, you have yourself an optimized version of your custom character. Thanks to everyone who contributed to the thread!

1 Like