Problem statement

While integrating one of our Spine files into our Unity project, I found that the z-order for the animations was correct, until I modified two of the materials used by this skeleton to use the "rim-light" shader I wrote. At which point the z-order for the symbols changed significantly. Using the default materials here doesn't cause this issue, and the issue also seemingly doesn't occur on another character with even more atlas pages (or at least is a lot less noticeable on this other character if it does still occur).

Here's what it looks like with our custom materials:
{Custom Material Screenshot}
(Note that these characters are both part of the same Spine file/SkeletonData.)

Here's what it looks like without our "rim-light" outline shader:
{Default Material Screenshot}

I attempted to add a Sorting Group component, but it didn't seem to change the behavior at all (and indeed I already had set a sorting layer on the Skeleton component).

Each of these atlas pages are already 4096x4096 pixels, and we are hoping to optimize for PC and Mobile, so we are trying to avoid making the textures any larger than 4k. What is causing the Z-Order discrepencies and is there any way to reasonably work around this issue without resorting to a single atlas page and material for this fight?

Runtime information

We're currently using Spine Runtimes v4.2.xx, with plans to upgrade to v4.3 when it is released on the stable branch.

Any help you can provide would be great, and I can email and project files needed to reproduce this issue if requested. Thank you!

Related Discussions
...

The issue you're experiencing with the z-order discrepancies when using custom materials in Unity is likely related to how the custom shader handles depth and rendering order. When you modify materials to use a custom shader, it can affect the rendering pipeline, especially if the shader changes how depth is calculated or if it introduces additional passes that interfere with the default rendering order.

To address this, you can try the following steps:

  1. Check Shader Settings: Ensure that your custom "rim-light" shader is correctly handling depth and does not introduce any additional passes that could affect the z-order. You might need to adjust the shader's ZWrite and ZTest settings to ensure proper depth handling.
  2. Sorting Group and Layers: Although you mentioned adding a SortingGroup component didn't help, double-check that the sorting layers and order are correctly set for all relevant components. Sometimes, small adjustments in sorting layers can resolve such issues.
  3. Shader Passes: If your shader has multiple passes, ensure that they are necessary and correctly ordered. Unnecessary passes can sometimes cause rendering issues.
  4. Material and Shader Consistency: Ensure that all materials using the custom shader are consistent in their settings. Inconsistencies can lead to unexpected rendering behavior.

If these steps do not resolve the issue, you might consider sending a minimal Unity project that reproduces the problem to Esoteric Software for further investigation. You can email it to contact@esotericsoftware.com.

@ExNull-Tyelor Sorry to hear you're having troubles. What render pipeline are you using? URP is unfortunately sometimes batching elements to a single draw call too aggressively, messing up draw order. Did you try the Advanced - Fix Draw Order property at your SkeletonAnimation component? It has been introduced just to work around this issue, but might not always fix it unfortunatley.

Apart from that, have you tried changing the RenderQueue or similar settings in your shader? How does your shader compare to the working one shown below in regards to these settings?

    Harald Hey Harald! I'm not sure how I overlooked the "Fix Draw Order" checkbox in the Advanced tab. I did look for setting like that.

    That said, toggling this to enabled seems to have fixed the problem (or at least greatly reduced it's severity). Thank you for pointing me in the right direction!!

    As for your second question, I'm honestly still very new to shader coding. I'm not seeing anything called RenderQueue in my .shader nor .cginc files. I do see "Queue" and both your Spine-Skeleton.shader and my Spine-Skeleton-RimLight.shader files use the Tag: "Queue"="Transparent"

      @ExNull-Tyelor Very glad to hear it helped!

      ExNull-Tyelor As for your second question, I'm honestly still very new to shader coding. I'm not seeing anything called RenderQueue in my .shader nor .cginc files. I do see "Queue" and both your Spine-Skeleton.shader and my Spine-Skeleton-RimLight.shader files use the Tag: "Queue"="Transparent"

      Sorry, while the name is Render Queue in the Material properties, it's just "Queue" in the shader instead of "Render Queue", I misremembered the name.

      The most important keywords here are: "Queue"="Transparent" and "RenderType"="Transparent", determining when and how your shader pass is rendered in the render pipeline. You can either override the Render Queue property via the Material property or let the shader determine it.

      Also "RenderPipeline" = "UniversalPipeline" is an important setting if you are using URP.

      Harald Thanks for the information! 🙇‍♂️

      I've checked and we don't have any Render Pipeline Assets set, so we're using the default render pipeline and not either URP nor HDRP, so I think the "RenderPipeline" = "UniversalPipeline" won't be needed for us. Though it's good to keep in mind if we do decide to switch to URP in the future!

      But as for the Render Queue and RenderType, my shader matches your shader for both of these tags, both being set to "Transparent".