Search Unity

Question Best Practices for Performance with Character

Discussion in 'General Graphics' started by ElXill, Feb 28, 2023.

  1. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    I'm working on a character and I have a few questions about best practices for seperating mesh and how it would effect performance. Considering materials, skin weights and shape keys.

    Let's say I want to seperate character into different parts: Legs, Arms, Torso, Head.

    1 - Material wise;
    a - If I use same material for whole mesh, how does seperating mesh would effect performance?
    b - If I use different materials for each part, how does seperating mesh would effect performance?

    2- Skin weight wise;
    Does it effect performance positively if I seperate meshes, skin weight wise?

    3- Shape key wise;
    Would it effect performance if I seperate shape keyed parts compared to keeping them all in one mesh?

    I have some assumptions but really I can't be sure. Seperating them would be better to work with but should I merge everything in at end or keep them seperated I can't really decide.
     
  2. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,924
    General rule of thumb: the less meshes and less materials you use, the better for performance.

    Now, there's thing thing called batching, that works differently depending on the render pipeline you're using, whether your meshes are static or dynamic, and a few other things. This allows Unity to automatically draw multiple meshes that share some characteristics (the material being one of them) in a single batch, which saves performance.

    Characters however (skeletally animated, skinned meshes) are generally not batched at all. So you have to be extra careful with them and use as few meshes/materials as possible.

    For thousands of animated characters (like crowds) you need to ditch SkinnedMeshRenderers entirely, and look into instancing and VATs (vertex animation textures).
     
  3. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    Thanks for the answer so, I guess it is best to merge textures and meshes and use a single material for performance then.

    I just sometimes check characters from big games, and see that they seperate everything arms, head, hair etc. Also every thing has their own texture sets, materials. It just made me wonder if this is the best way to do, but maybe they try to keep their workflow as clean as possible and doesn't care too much about this kind of optimization becouse maybe the bottle neck nowadays is workforce/productivity and not hardware for them.
     
  4. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,924
    Depends on what you're doing, what your target hardware is, how you actually render stuff, etc.

    If your target hardware is mobile phones, this stuff often becomes critical. Having a separate draw call for every single object in a scene (assuming every object has its own material/texture) is just not viable. Drawcall count in desktop computers however is a lot less critical.
     
  5. kenamis

    kenamis

    Joined:
    Feb 5, 2015
    Posts:
    387
    If you're using and SRP then you can use the SRP batcher, which works on skinned meshes, and makes drawcalls using the same shader variant very cheap (shader needs to be srp batcher compatible too). I found that it's usually better not to merge meshes and atlas textures then, and you save memory from not having unique meshes and textures for every character if you're making characters from reusable parts.

    3- Shape key wise; I think, but I have not tested, separated parts might be a win for shape keys. For a single unified mesh, the entire vertex buffer needs to be looped over even for a small blendshape (like eye blink) each frame.
    Memory consumption-wise, I believe, the imported blendshapes are stored as sparse arrays, but it's unclear if blendshapes created through the API are sparse arrays too or not. If they aren't, and the blendshapes are being procedurally created through that (like from runtime merging), then there's potentially a lot of wasted memory from blendshapes that affect only a tiny bit of the unified mesh.
     
    tmonestudio likes this.