- Изменено
How can I export an 8-bit atlas
How can I export an 8-bit atlas
Hi @Mario. I tried running through pngquant the png output of spine. It successfully reduces the file size by 3X while keeping the dimensions exactly the same and it looks virtually the same to the naked eye (which is a huge win for us). However when I load the animation with spine-phaser it gets some green shades surrounding the parts.
Do you have any idea what could be going on or what could I do to debug the problem? Thank you so much for any guidance or insight you might have for me!
Hi @Mario this seems to be very related: kornelski/pngquant353
Flagging just in case it makes sense to you, in hopes it helps understand what is going on.
In the meantime, I asked the designer to try the premultiplied alpha export and I will report back, but seems from that link there might be something else behind it (bleeding workaround)?
I pngquant'ed our raptor's atlas in the spine-phaser examples and can confirm the issue.
I can modify our shader to discard pixels with alpha=0, which will get rid of most of the green pixels. However, that doesn't work for the fringes of images, where alpha is slightly above 0, as those pixels will still get rendered. The end result is a green shimmer on the fringes.
I
So that's not going to work. The reason: WebGL unpacks premultiplied alpha when creating textures. You can disable that via:
spine.GLTexture.DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL = true
That kinda works, but you will loose some of the benefits of premultiplied alpha, visible around the mouth of Spineboy. It's not as pronounced as not using premultiplied alpha at all, still annoying.
I don't quite get why the pngquant author refuses to set the transparent color's palette entry to rgb(0, 0, 0). That's a much simpler solution than relying on framework authors to set the correct blend modes and image unpacking for this case, which may be out of control for the users. For example, we have to use Phaser's texture loader, and we can't control what it does to the pixels when unpacking them.
I've just pushed NPM packages for spine-phaser: 4.1.47 and 4.2.28 that will allow you to use the DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL "trick".
- Изменено
If I understand correctly, you export PNG files from Spine as an atlas, convert them to 8-bit with pngquant, then display them with spine-phaser.
The linked issue for pngquant says it uses PMA in its processing and it doesn't preserve colors for transparent pixels, which makes sense for a palette. Checking or unchecking Bleed
should not matter, as it sounds like pngquant is going to premultiply. If you check Premultiplied alpha
and pngquant premultiplies again, that will ruin your images. If pngquant has no way to tell it the PMA is already done then be sure not to give it PMA images.
I don't understand where green color comes from!
Mario I don't quite get why the pngquant author refuses to set the transparent color's palette entry to rgb(0, 0, 0).
Is the green coming from the 8-bit palette using green for transparent? That does seem odd, but the results would still be poor using black and alpha=0. The only reason non-PMA rendering looks reasonable is because Spine performs Bleed
. To render without PMA, you'd need to perform bleed after pngquant. Here's some code to do that, but the result would be a 32-bit PNG, which isn't what you want. An 8-bit PNG can't be PMA (it uses a palette), so you'd need to PMA while loading the image data or in a shader. Performing bleed at runtime is harder and the rendering is worse, so I wouldn't do that -- use PMA like the image gods intended.
The WebGL "unpacking" is dividing the color by the alpha? That's crazy and never something you want, plus it will need to use some color (black?) when alpha is zero: now you have no "bleed" and non-PMA rendering will look bad. The image of the PMA unpacking looks pretty good, but the dark borders would indicate rendering is not done for PMA, or is done for PMA but the image is not PMA.
One more thing, if you are using 8-bit images, you should be able to load them into an 8-bit texture rather than using 32-bit textures (reducing runtime video memory usage). Then you'd need to do PMA in a shader. One problem at a time I suppose.
Wow! You guys are clearly experts at this, I'm just a n00b trying to get small footprint assets on my phaser game Thank you so so much @Mario and @Nate for taking a look, for the insights, and help.
I don't understand how or why, but I can report that exporting from Spine PNG atlas with premultiply alpha turned on, will make those green areas disappear.
I also learned that the export with webp has similar small size to a PNG atlas export + pngquant (though I have even less experience with webp) and turns out it doesn't have the green shadows problems. Mentioning in case it is useful to someone reading this in the future.
Totally forgot about webp, but yes, that's a good option!