AristurtleDev / monogame-aseprite

A Cross Platform C# Library That Adds Support For Aseprite Files in MonoGame Projects.
https://monogameaseprite.net
MIT License
166 stars 15 forks source link

Add option to import layers seperatly. #19

Open manbeardgames opened 3 years ago

manbeardgames commented 3 years ago

This was brought up on the discord server by Mooosik

I noticed that if I hide a layer in Aseprite, the layer will be hidden in Monogame aswell. Being able to do enable / disable layers in Monogame would be super useful but I dont think its possible yet, is it?

For example if I have one walk animation with several types of hand poses on other layers (for carrying different types of items), i could just set the layer i need to "visible".

So ideally here, what would happen is instead of flattening the layers to a single layer texture, each layer itself would be its own texture data. One hurdle I can think of for this is how the blending between layers would be handled.

AristurtleDev commented 1 year ago

The Problem

I've been going back and forth on this for a bit now since the v4 update, and I'm struggling to see how I can make this possible. There are issue comes down to blending.

When the image for a single frame is created, all cels in that frame have to be merged in a process called "frame flattening". Essentially what happens, starting with the bottom most cel in the frame, the pixels in that cel are blended with the cel above it using the blend mode defined by the layers.

When processing an Aserpite file as a TextureAtlas (or indirectly a SpriteSheet for animations), frame flattening happens for every frame in order to generate the source Texture2D. Since all cels are blended in each frame during this processes, there's no concept of layers any more in the resulting source image.

Possible Solutions?

As I've though about it more, I started to come up with some possible solutions for this. One was to see if there was a way to override or create a custom blend state to use in the SpriteBatch when calling SpriteBatch.Begin. If this was possible, then I could re-implement all of the blend functions that way and could use that. This however, has two issues: (1), it's not possible as far as I can find in research. Regardless (2) this would mean a new SpritBatch.Begin call would need to be made for each layer rendered, and each layer would also be a separate Texture2D which could lead to a ton of texture swapping on the SpriteBatch which is not a good thing for performance.

I think ultimately what you want to accomplish here can be done with the library, but it would require a more advanced use case and setup to do. Something along the lines of creating your own processor to generate source images of each cel, and pack them a single image, then have a class that uses this to put it all together at runtime.

So I'm not going to close this issue, for now, I would like to think on it more, but I don't see this being implemented any time soon. I'm going to remove it from the 4.1.0 Milestone and put it on a backlog for now. I apologize about this, and if anyone has an idea on implementing this, I'm open to listen.

NitroPlum commented 10 months ago

I wanted to give my input here. I was working on implementing something similar in my own Aseprite loader in another language. There is a very valid use case for where you want this and don't care if blending works. It's Spritestacking. In Aseprite you build a sprite out of multiple layers, usually not needing special blending. You simply need to work on a sprite but import each layer as a separate animated sprite in the engine. Think a topdown game where characters are made of many parts and you want to represent them as separate sprites in game,

e-Forest commented 9 months ago

I wanted to give my input here. I was working on implementing something similar in my own Aseprite loader in another language. There is a very valid use case for where you want this and don't care if blending works. It's Spritestacking. In Aseprite you build a sprite out of multiple layers, usually not needing special blending. You simply need to work on a sprite but import each layer as a separate animated sprite in the engine. Think a topdown game where characters are made of many parts and you want to represent them as separate sprites in game,

This is exactly what I need for my project. There is an Aseprite Lua script that exports individual layers into separate .png files. It would be a great thing if this intermediate step were no longer necessary.

https://community.aseprite.org/t/script-export-sprites-layers-separately/3679