• RuntimesUnity
  • Detailed Explanation of Current Issues with Spine Skeleton Rendering in Unity

Core Issue
I'm experiencing inconsistent depth occlusion behavior with Spine skeletons in my Unity 2D game. Despite multiple shader modifications, I'm still encountering unexpected rendering behavior.

Technical Details
Depth Testing Inconsistency:

I'm building a 2D game where the -Z axis should represent foreground and +Z axis should represent background
However, the transparency occlusion is working opposite to expectations - objects that should be occluded are visible, and vice versa
Spine SkeletonMecanim Configuration Issue:

When setting objects closer to the camera as "background" and objects further from camera as "foreground", the occlusion works correctly
This is counter-intuitive and conflicts with the standard Unity rendering pipeline
Setting objects according to logical foreground/background positions results in incorrect occlusion
Shader Attempts:

I've made multiple modifications to the Spine-Skeleton_custom.shader
Attempted various ZTest configurations (LEqual, GEqual, Less, Greater)
Implemented Z-axis inversion in vertex shaders
Added alpha feathering and threshold effects
Created depth-only passes and simplified the shader
Current State:

The shader now correctly renders with alpha feathering
Depth interactions are still working incorrectly without manually reversing the foreground/background assignments
Created a SpineZOrderCorrector component as a potential solution
Questions
What's causing this reverse relationship between Spine's foreground/background settings and actual Z-depth?
Is there a way to fix this at the shader level without needing a custom component?
Does the SkeletonMecanim component have built-in functionality that's reversing the expected Z ordering?
Are there any performance concerns with my current shader implementation?
Is there a more elegant solution to achieve proper occlusion while maintaining alpha feathering effects?
I need a solution that allows me to set objects according to logical foreground/background positions and have them render with correct occlusion, while maintaining good performance in the built-in render pipeline.





<iframe src="https://1drv.ms/v/c/a6f0114fb2c74c10/IQQZcaCQdXXgTZGRrCzqaWzNAbNYteeYtJg0pkQTXJke8JY" width="2560" height="1380" frameborder="0" scrolling="no" allowfullscreen></iframe>

<iframe src="https://1drv.ms/v/c/a6f0114fb2c74c10/IQTYaSW7NaE3Spf7-QxRjRM6AdH75w1nYVpTKiEjRGfge_Q" width="2560" height="1380" frameborder="0" scrolling="no" allowfullscreen></iframe>

    Related Discussions
    ...

    The issues you're experiencing with depth occlusion in Unity when using Spine skeletons are likely due to the inherent challenges of rendering semi-transparent objects and the way Unity handles depth sorting. In Unity, transparent objects are typically rendered in a back-to-front order, which can conflict with the Z-buffer's depth sorting, especially when using shaders that write to the depth buffer. This is a common issue with alpha blending, as described in the spine-unity Rendering documentation.

    1. Reverse Z-Depth Issue: The reverse relationship you're seeing might be due to the way Unity's transparency sorting works. Unity sorts transparent objects based on their distance from the camera, which can lead to unexpected results if the Z-axis is used for depth sorting. This is compounded by the fact that Spine's rendering order is determined by slot draw order, not Z-depth.

    2. Shader Modifications: Your attempts to modify the shader with different ZTest configurations and depth-only passes are valid approaches. However, the fundamental issue is that depth writing with transparency is inherently problematic. The spine-unity Rendering documentation suggests using alpha blending without depth writing for clean semi-transparent transitions.

    3. SkeletonMecanim and Z-Ordering: The SkeletonMecanim component itself does not inherently reverse Z-ordering. The issue is more likely related to how Unity handles transparency and depth sorting. You might consider using Unity's SortingGroup component or adjusting the Advanced - Z-Spacing setting to help manage draw order.

    4. Performance Concerns: Using complex shaders with multiple passes can impact performance, especially on lower-end devices. Simplifying the shader and avoiding unnecessary depth writes can help maintain performance.

    5. Elegant Solution: A more elegant solution might involve using Unity's built-in sorting layers and order in layer settings to manage draw order, combined with careful management of transparency and depth writing in your shaders. You could also explore using a custom component like your SpineZOrderCorrector to adjust draw order dynamically.

    In summary, achieving correct occlusion with transparency in Unity requires careful management of draw order and shader settings. Using Unity's sorting layers and avoiding depth writes in transparent shaders can help achieve the desired results.

    suanLoBeach Thanks for the detailed explanation. However, it would be most helpful for us to advise you if you could provide us with a minimal Unity project that can reproduce the problem, not just text and screenshots, so could you please create a minimal Unity project and email it to us?: contact@esotericsoftware.com

    Below are the required files:

    • Assets/
    • Packages/
    • ProjectSettings/

    Excluded Files (To keep the project size minimal, please do not include the following):

    • Library/, Logs/, Temp/, obj/
    • Builds/
    • .git/

    Create a new folder and copy only the required files and folders mentioned above, then compress the folder into a .zip or .rar file.

    Also, please include the URL of this forum thread in the email so we know the context. Then we can take a look at what's wrong. Thanks for your cooperation!

      suanLoBeach When setting objects closer to the camera as "background" and objects further from camera as "foreground", the occlusion works correctly
      This is counter-intuitive and conflicts with the standard Unity rendering pipeline

      The SkeletonMecanim component just fills a MeshRenderer's mesh with triangles, in proper back to front order for transparent rendering. The provided spine-shaders also do not magically invert the draw order behind the scene, they use standard Unity render queues, it's all a shader can do. If you modify the shader, you might need to adjust the Render Queue accordingly. SortingOrder in the SkeletonMecanim Inspector is just exposing the MeshRenderer.sortingLayerID (m_SortingLayerID), as the tooltip also shows. If you think that SortingOrder works incorrectly, please file a bug over at Unity, as this feature is not provided by us.

      If you are seeing incorrect sorting, your custom shader modifications or other sorting related setup is not doing what you want it to do.

      Note that you are repeatedly asking general transparency rendering related questions here on the Spine forum, which are unrelated to Spine and the spine-unity. Normally you would want to ask them on the Unity forums instead:
      https://discussions.unity.com/

      suanLoBeach I've made multiple modifications to the Spine-Skeleton_custom.shader
      Attempted various ZTest configurations (LEqual, GEqual, Less, Greater)
      Implemented Z-axis inversion in vertex shaders
      Added alpha feathering and threshold effects
      Created depth-only passes and simplified the shader
      Current State:

      The shader now correctly renders with alpha feathering
      Depth interactions are still working incorrectly without manually reversing the foreground/background assignments

      Please note that you need to get familiar with how rendering, render queues (transparent vs opaque sorting), the z-buffer, ztesting, and so on works in Unity and in general. Trying all different kinds of shader configurations randomly will never lead to the desired effect. You need to understand what you are doing. Please note that this forum is dedicated to Spine and Spine runtimes like the spine-unity runtime.

      Unity documentation on rendering and render order:
      https://docs.unity3d.com/6000.0/Documentation/Manual/rendering-and-post-processing.html
      https://docs.unity3d.com/6000.0/Documentation/Manual/built-in-rendering-order.html

      suanLoBeach Created a SpineZOrderCorrector component as a potential solution

      What does this component do?
      In general your problem is independent of spine-unity components, it is due to your custom shader or sorting layer settings.

      suanLoBeach What's causing this reverse relationship between Spine's foreground/background settings and actual Z-depth?
      Is there a way to fix this at the shader level without needing a custom component?

      Yes.

      I saw that you've created a video of your shader code instead of sharing the code as text. Apart from wasting a lot of bandwidth (consider the environment before doing things like this), sharing code as screenshot images is already bad for reading and prevents testing it, but creating a video is even worse and makes it terrible to review. If you want us to look at your code, please always share it in text form. Either enclose it in triple-backticks, or upload the file as attachment to a forum posting.

      Harald I made sure I sent the project file to this email address

      @suanLoBeach I just checked again, unfortunatley nothing arrived, also not in spam, and search did also not find anything related. Likely it has been blocked for other reasons. You could upload the project somewhere and share a link to the project, either sharing the link at a forum posting or send it by email (best from another email address) and hope that it gets through.

        Harald https://1drv.ms/u/c/a6f0114fb2c74c10/EeMBO-oROOxKsthwZ9S5_WQB2EyuEA8WC-fpwAktHjj2zQ?e=J8OveN

        link here

        When I recreated a minimal project, I noticed some differences compared to the original project, such as sort layers. I'm not sure if sort layers are set by Spine, as my newly created project doesn't have sort layers. So I transferred my original project, and now the issue is that I added depth occlusion functionality to the spine/skeleton shader, but now the depth occlusion and sort layer settings are reversed - backgrounds can occlude foregrounds, but foregrounds cannot occlude backgrounds. This is the main problem I'm asking about. Regarding different Z values for background and foreground layers, I plan to add code in the Spine script to set different Z values for different layers after solving the sorting issue, to better adapt to requirements.

          suanLoBeach . I'm not sure if sort layers are set by Spine

          No. As I mentioned above, Spine and spine-unity just fill a Mesh of a MeshRenderer with triangles. You can configure rendering as you like, spine-unity does not setup anything in this regard.

          suanLoBeach as my newly created project doesn't have sort layers.

          Sort layers are user defined, it makes no sense if two layers would be pre-set in a new project.

          suanLoBeach When I recreated a minimal project, I noticed some differences compared to the original project, such as sort layers.[..]. So I transferred my original project

          Your download link to your Unity project is a 1.077GB rar package. Misaki told you above how you should create this package, and even took the time to explicitly tell you what to include and what to exclude:

          Misaki Below are the required files:
          Assets/
          Packages/
          ProjectSettings/

          Excluded Files (To keep the project size minimal, please do not include the following):
          Library/, Logs/, Temp/, obj/
          Builds/
          .git/

          Create a new folder and copy only the required files and folders mentioned above, then compress the folder into a .zip or .rar file.

          You completely ignored these 10 lines that Misaki wrote and the term "minimal" which is preceding "Unity project" for a very good reason. Your package contains a Library directory of 2.7GB, a .vscode directory and so on. And what's much worse, your Assets directory contains unecessary 3rdparty packages like CorgiEngine, Behavior Designer, Verpha etc. and when opening your project, there is even a broken package dependency to a local package on your disk O:/软件插件包/unity插件包(package)/com.esotericsoftware.spine.timeline-4.2, which is also not needed for the reproduction either.

          We ask for a minimal Unity project because it's the users responsibility to boil the problem down to the essence to ensure:

          1. Other components and packages are not interfering and
          2. It's actually related to spine-unity components and
          3. We can efficiently test and potentially fix any bugs on our side, or point out the problem on the user's side.
            Aside from that it's a matter of respect to not make the work of the other peer harder than necessary if you want help from them.

          We have patiently tried to help you with your rendering setup which is unrelated to Spine and spine-unity, and so not related to our Spine support forum. You have now shown that you either can't follow simple instructions or are deliberately making it hard to help you. If you can't follow instructions, there is no use telling you what to do. If you're deliberately doing something else, then we can't help you either.

            Harald

            Hi there

            I apologize for the trouble I've caused on the Spine forum these past few days. Since I'm not proficient with shaders, I couldn't determine whether the sorting layer issues were related to spine-runtime (now it seems more likely to be an issue with handle the occlusion order of sorting layers).

            The lady asked me to provide a project. Does this mean a Unity project? My understanding is a complete Unity project, so I dare not delete the part that Unity automatically creates, because I am worried that I may not be able to reproduce the problem.

            With your help I have been able to resolve most of the issues I mentioned earlier, thank you very much! Since I encountered the issue when setting the sorting layer in Spine scripts, I instinctively assumed it was caused by spine-runtime.That's why I posted these issues on the Spine forum.

            If this project does not meet the requirements, please ignore my submission, so I am asking here, if I need to send a project, don't I have to send the Unity project? I only need to send the assets and the packages and project settings I use? Because Misaki mentioned the minimum project, I thought I had to send a complete project.
            So the correct approach is to create a new project containing only spine-runtime and then import the assets and send it?

            I only have one remaining issue now. If the sort layer is not set by spine-runtime, then it must be set by other packages, which have set background to Layer 1 and foreground to Layer 5. Is it possible that the Spine Skeleton Mecanim component's Sorting Layer follows the principle that smaller layers are occluded by larger layers? The issue I'm facing now is that when I use a custom ZWrite shader or the official Spine Lit ZWrite shader, larger Layers cannot occlude smaller Layers. I will create a clean project with only spine-runtime installed and try again. If I still encounter this problem, I will send the assets and project settings to you.

            Thank you very much and Apologize again

              Thanks for your understanding and for your apology.

              suanLoBeach The lady asked me to provide a project. Does this mean a Unity project? My understanding is a complete Unity project, so I dare not delete the part that Unity automatically creates, because I am worried that I may not be able to reproduce the problem.

              It is important to provide a Unity project which contains no thirdparty assets or otherwise unrelated non-Spine packages. If you can only reproduce the issue with a certain thirdparty asset, then the problem must be with this asset, not with spine-unity. So you need to start from a fresh clean new Unity project and add only the spine-unity runtime and your custom shader and your sorting setup. If you can't reproduce the problem like this, you've just discovered that it must be some special setting or asset which is causing the troubles.

              Side note: you should also never start from a template project, this is also not a clean minimal starting point. It has to be a new clean Unity project.

              For size and download reasons, certain directories that Misaki mentioned shall be excluded, since they are generated upon import anyway.

                Harald

                I created a new project containing only the spine-runtime and tested it. This issue might not be related to Spine but is rather a phenomenon in Unity's Built-in RP. However, to be cautious, I'm responding here with the detailed cause of the problem.

                The origin of the issue is that most textures used in my project are semi-transparent (you can imagine Spine Boy's body becoming transparent, so when two boys stand together, you can see the boy behind through the front one). Even the colored parts of my textures are transparent. During testing, I found that when multiple objects overlap, the visual effect is quite poor. Therefore, I wanted to use ZWrite to make the frontmost object block the transparent objects behind it while remaining transparent to other non-transparent objects (like being able to see the wall behind Spine Boy, but not being able to see a second Spine Boy positioned in between).

                I initially modified the basic Spine shader, but then I tried using the Spine Lit ZWrite shader as an example. After changing the shaders for both the raptor and Spine Boy to Spine Lit ZWrite shader, they became transparent (I had processed the textures to 50% alpha). At this point, the raptor's sorting layer was Layer2 (foreground), while Spine Boy was Layer1 (background), both with Z-axis at 0, so they blended together.

                However, what I really wanted to achieve was for one to completely block the other. I discovered that implementing this effect required a strange combination: Spine Boy (background) needed to be closer to the camera than the raptor (foreground), meaning Spine Boy's Z-axis had to be closer to the camera. This gave me the effect I needed. But obviously, this is incorrect, because Spine Boy is in the background and shouldn't be closer to the camera - it should be further away than the raptor. This is the problem I'm currently facing.

                ,
                To better demonstrate this effect, I set the Depth alpha cutout value of Spine Lit ZWrite to 0, though in actual projects I usually set it to 0.1.

                So, the functionality I needed (ZWrite occlusion for transparent textures) has actually succeeded, but I'm facing another problem, which is that the Z-axis values are opposite to the sorting layer settings. The background must be closer to the camera than the foreground to achieve ZWrite occlusion.

                I'm not skilled with shaders, so I'm not sure if this is a Unity issue or a problem with the Spine shader.