• Editor
  • Spine Atlas Optimization for Multi-Part Skins & Game Size

Hello!

I'm a developer currently working on a 2D mobile game using Spine.

We're facing a challenge where, when applying multiple skins to various parts within a single Spine file, the number of atlases inevitably grows. This leads to a drawback where the game's overall size progressively increases with long-term updates.

From a programmer's perspective, I'd like to share an example: within a development tool like Unity, there's a program called sprite-dicing (link: elringus/sprite-dicing). It's an open-source tool that slices images into smaller pieces and packs them into an atlas, resulting in a significant reduction in file size.

I believe that if a feature like this were added to Spine's export options, it would be a massive optimization for games like ours, which rely on creating diverse skin variations for individual parts. Would it be possible to implement such a feature?

I'm not sure if that specific open-source tool can be directly referenced for implementation, but if it's feasible, I wanted to suggest adding this functionality.

  • Misaki ответили на это сообщение.
    Related Discussions
    ...

    Currently, Spine does not have a built-in feature to pack atlas textures per skin, which could help in optimizing the game size when using multiple skins. However, this feature is on the roadmap for future updates, as noted in the GitHub issue. In the meantime, you can use workarounds such as organizing images into folders for each skin and using command line exports to pack each skin into its own atlas. Additionally, you can write scripts to automate this process or integrate it into your build system. While the sprite-dicing tool you mentioned is not directly supported, similar functionality could potentially be achieved through custom scripting and automation.

    • shinyu ответили на это сообщение.

      Spinebot Thank you for the detailed explanation. It's great to hear that a built-in feature for skin-specific atlas packing is on the roadmap!

      In the meantime, regarding your suggestion about achieving similar functionality through custom scripting and automation, could you please provide any reference materials, examples, or guidance on best practices for this approach?

      This would be incredibly helpful for optimizing our atlas generation until the native feature is available.

      shinyu If you need a large number of skins for your skeleton, it is better to consider setting them at runtime rather than setting everything in Spine. General information about this is explained on the following page:
      https://esotericsoftware.com/spine-runtime-skins

      The above page contains information common to all runtimes, so the approach may differ slightly depending on the runtime. What runtime do you plan to use?

      • shinyu ответили на это сообщение.

        Misaki Thank you for the advice on runtime skins. We are indeed already utilizing dynamic skin loading and setup at runtime in our game.

        However, my primary concern was about optimizing the number and size of atlases generated during the Spine export phase. While dynamic loading helps with memory management and reducing initial load times, it doesn't change the fact that multiple atlases might still be generated if a smart packing feature (like the sprite-dicing concept) isn't present in the export options. Our goal is to reduce the overall asset footprint before deployment, because as the project extends long-term, the atlas size inevitably grows, and it might become unmanageable later.

        To answer your question, we are using the Unity runtime

        • Misaki ответили на это сообщение.

          shinyu Thank you for the additional information.
          In that case, you should use On-Demand Loading UPM Packages. While the size of the atlas file increases with the number of pages, the .txt.atlas file itself will only be a few megabytes at most. The main concern is that the texture atlas page images can become quite large. However, this package replaces textures with low-resolution placeholder images until they are actually needed, which helps reduce the initial download size of the application.

          For details, please refer to the documentation:
          https://esotericsoftware.com/spine-unity-on-demand-loading

          • shinyu ответили на это сообщение.

            Misaki Thank you for the detailed information regarding the 'On-Demand Loading UPM Package'. This seems very helpful for efficiently managing initial application download size and runtime memory usage.

            However, my original concern was about the draw call increase that inevitably occurs as the project extends long-term and we add more skins for various parts, leading to a growing number of atlases. While 'On-Demand Loading' offers an approach to efficiently load and manage these atlases, it doesn't seem to fundamentally resolve the draw call issue by reducing the number of atlases themselves.

            Therefore, our problem lies in the need for a feature that directly optimizes draw calls by reducing the atlas count through more intelligent packing during the Spine export stage, similar to sprite-dicing, especially since multiple atlases are unavoidable in our project.

            While I appreciate the guidance you've provided, it seems this is not the fundamental solution I was looking for. I am still curious if a feature that directly reduces the number of atlases to optimize draw calls is still planned for future provision.

            • Misaki ответили на это сообщение.

              shinyu To reduce the number of draw calls, use the Skin.GetRepackedSkin() method to combine the used texture regions of a collected skin into a single texture at runtime. For more details, please refer to the following section of the spine-unity runtime documentation:
              https://esotericsoftware.com/spine-unity-main-components#Runtime-Repacking

              • shinyu ответили на это сообщение.

                So, if my understanding is correct, the 'Runtime Repacking' feature via the Skin.GetRepackedSkin() method is a function that, provided the important notes are properly observed, allows us to repack images from multiple atlases into a single texture in real-time, thereby reducing the number of atlases and, consequently, actually decreasing draw calls. Is that right? If so, this would be a highly effective solution for the draw call increase that can inevitably occur as the project extends long-term.

                Thank you very much for providing such crucial information. I will refer to the documentation you provided and begin testing immediately!

                Also, could you please confirm if there are any specific Unity version constraints for this 'Runtime Repacking' feature? I'm curious about its compatibility with our current Unity version.

                • Misaki ответили на это сообщение.

                  Misaki So, if my understanding is correct, the 'Runtime Repacking' feature via the Skin.GetRepackedSkin() method is a function that, provided the important notes are properly observed, allows us to repack images from multiple atlases into a single texture in real-time, thereby reducing the number of atlases and, consequently, actually decreasing draw calls. Is that right? If so, this would be a highly effective solution for the draw call increase that can inevitably occur as the project extends long-term.

                  Thank you very much for providing such crucial information. I will refer to the documentation you provided and begin testing immediately!

                  Also, could you please confirm if there are any specific Unity version constraints for this 'Runtime Repacking' feature? I'm curious about its compatibility with our current Spine version.

                  shinyu

                  So, if my understanding is correct, the 'Runtime Repacking' feature via the Skin.GetRepackedSkin() method is a function that, provided the important notes are properly observed, allows us to repack images from multiple atlases into a single texture in real-time, thereby reducing the number of atlases and, consequently, actually decreasing draw calls. Is that right?

                  I'm a little unsure about what you mean by "real-time," but other than that, you have a correct understanding.

                  Runtime repacking is an expensive process, so it's not ideal for cases where skins change frequently. For example, if you use repacking for a skeleton that changes the character's facing direction via skins and run this process every time the player moves and the character changes direction, it would be inefficient.

                  Therefore, you should consider the timing of when to perform repacking. For example, it is better to perform repacking only after all visual changes have been finalized, rather than every time the player switches part of the skeleton's appearance. For details, please refer to the example in Spine Examples/Other Examples/Mix and Match.

                  Also, could you please confirm if there are any specific Unity version constraints for this 'Runtime Repacking' feature? I'm curious about its compatibility with our current Unity version.

                  Runtime repacking has been available since Spine 3.6 was released in 2017. Spine 3.6 is compatible with Unity 5.6-2018.2, so it can be used with these and later versions.

                  I'm a bit late to add my 2 cents, but here goes.

                  the number of atlases inevitably grows

                  Often you have a single atlas with many pages. You can control what goes on the same page with subfolders. However, it sounds like you are actually doing runtime packing, so you should have individual images until you pack them at runtime. If that's right, confusing that you mention exporting atlases.

                  Our goal is to reduce the overall asset footprint before deployment

                  You mean the unpacked PNGs? PNGs use compression and won't see a benefit from breaking them into slices. To reduce your PNG size without losing quality, use Oxipng (it's free).

                  Slicing might help pack your images at runtime, particularly because polygon packing at runtime is hard/slow so you'll just be packing rectangles. The gains shown at your link aren't anything like what you'll get though. They are slicing to compress full frame images.

                  my original concern was about the draw call increase that inevitably occurs as the project extends long-term

                  This can be solved with runtime packing of only the attachment images you will use, as Misaki explained.

                  Note draw calls aren't just about atlas page count. If you have 1 atlas page, you can draw in 1 draw call. As soon as you have 2 atlas pages, your draw count can explode. It depends on your draw order. Worst case is if every other attachment image is on a different page. If you can't fit in 1 atlas page, images should be sorted using your order to minimize page switches when rendering.