Hello! I'm trying to solve a couple of issues that I suspect might be really common and I'm not addressing them correctly. We have humanoid models, and we can mix & match clothes on them. The approach we took for the mix & match is the second one explained here: https://en.esotericsoftware.com/spine-unity-mix-and-match

i.e.: Use template attachments in Spine and generate Attachments from UnityEngine.Sprites in Unity.

Problem 1:
When we do the Runtime Repacking, all the textures that the character uses get atlased into one atlas, which is good because we want to keep draw calls as low as possible. But the issues is we need to make a shader that only affects the skin, another one that only affects the hair and so on. Our plan is to make an all-in-one shader so we keep draw calls low (making separated shaders is a no-go, because one shader for skin and another one for clothes increase draw calls dramatically because of layering), but for that we would have to dynamically generate masks depending on the final textures. Is this the correct way to go? I feel like there should be a better option?

Problem 2:
When we export from spine, all the template images get exported as well, and we don't want this, because we have things like nose options, which we have a different skin per option. This means all the noses are exported because each nose is it's own template. You can see how this is using a huge unnecessary amount of memory, because we use the noses from separated textures anyway, and we might not want them all loaded at any point in the app. Is there a way to prevent spine from exporting templates?

    Related Discussions
    ...

    kadak Our plan is to make an all-in-one shader so we keep draw calls low (making separated shaders is a no-go, because one shader for skin and another one for clothes increase draw calls dramatically because of layering), but for that we would have to dynamically generate masks depending on the final textures.

    Could you please describe what exactly you mean with "dynamically generate masks"? What you would normally do in a case of covering multiple materials in a single shader is having the material-type-ID stored in a separate texture or use the color or alpha channel of an existing texture. Then your shader would choose the respective code path based on the material ID. With the exported Spine atlas textures, you could either manually author the material-ID map or automate your atlas exports on the command line accordingly and re-export the same attachments with a replacement texture.

    What would be even better in your case would be to utilize vertex colors to convey the material information to the shader. This way you would save any atlas texture preparation work. Depending on your current skeleton requirements, you could perhaps use the slot color alpha channel as material-ID, if you never use slot alpha for transparency at the same skeleton.

    kadak Is there a way to prevent spine from exporting templates?

    You have many options regarding atlas texture packing.
    E.g. you can pack by folder structure:
    http://esotericsoftware.com/spine-texture-packer#Folder-structure
    Another solution would be to isolate unused template textures in a second atlas texture page and then exclude the texture form the build, downsize it or replace it with e.g. a 1x1 white placeholder texture.

    Exporting the textures in 1x1 worked flawlessly, thank you!

    As for the other problem, I'll elaborate a bit more. We have a character model with 3 main features:

    1. Clothes
    2. Skin
    3. Hair

    The clothes we want to just render normally
    The skin we want to apply a gradient, since it is grayscale, this gradient has values shifted depending on shader values to better emulate different skin tones. The skin must also support freckles and vitiligo, and other potential shader powered features.
    The hair just needs the gradient at the moment.

    Since we are packing the albedo at runtime, I thought of having a mask that replicates the albedo atlas. Said mask would use one channel for the skin, one for the hair and another for the clothes. Using this mask, we could tell the shader what to do in each part of the model.

    This being said, I'm not sure this is the right approach and I think you brought some interesting points to the table. Do you think we could just flax vertex with an ID, being 1= cloth, 2 = skin, 3 = hair, etc. and depending on the ID do the corresponding logic? I think this would be optimal

    Regarding the material ID solution I'm a bit lost, I would need multiple material IDs in the same shader, so I'd be in the same problem as before. How to I assign a material different material ID to the skin than to the clothes?

      kadak Since we are packing the albedo at runtime, I thought of having a mask that replicates the albedo atlas. Said mask would use one channel for the skin, one for the hair and another for the clothes. Using this mask, we could tell the shader what to do in each part of the model.

      This is the slightly more flexible and quality-wise better approach, but at the same time a bit more costly (since it requires one channel per material). It's slighly more flexible and better in quality since you can create transitions from any Material to any other in adjacent screen pixels with nice [0.0 - 1.0] blending. With an ID you could only transition between two material IDs that are next to each other.

      kadak Do you think we could just flax vertex with an ID, being 1= cloth, 2 = skin, 3 = hair, etc. and depending on the ID do the corresponding logic? I think this would be optimal

      By "flax vertex" I assume you meant "flag a vertex" right? In general you would usually normalize the values to use the whole 0-255 range, e.g. if you have 3 materials they would get assigned 0, 128, 255 respectively. Likely the most comfortable way to flag your vertices would be by naming your Slots (or Attachments) with material suffixes, like "Head_skin" in the Spine Editor. Alternatively you could assign material-IDs by creating an array for each Material type and then adding the slots or attachments to one of these material lists. Then you can programmatically change the vertex color accordingly, either on import via a custom SkeletonDataModifierAsset, or at runtime whenever changing attachments. Otherwise, when already setting the vertex color in the Spine Editor, you will see "incorrectly" colored or transparent attachments in the Spine Editor.

      Whether your Slot or Attachment defines your material (and thus the material ID) is up to your project requirements.

      Using the vertex color worked like a charm. Thank you very much!