EsotericSoftware / spine-runtimes

2D skeletal animation runtimes for Spine.
http://esotericsoftware.com/
Other
4.35k stars 2.89k forks source link

[ios][libgdx]premultipliedAlpha Rendering Issue on iOS Compared to Android #2586

Open zyvv opened 1 month ago

zyvv commented 1 month ago

Description

I'm encountering an issue with premultipliedAlpha rendering for Spine files when transitioning between Android and iOS platforms. On Android, enabling premultipliedAlpha correctly renders the black background as transparent. However, on iOS, the rendering does not display as expected.

Details

Steps to Reproduce

  1. Load the same Spine file on both Android and iOS.
  2. Enable premultipliedAlpha on both platforms.
  3. Observe the rendering differences, especially with black backgrounds.

Expected Behavior

On both platforms, the black background should be rendered as transparent when premultipliedAlpha is enabled.

Actual Behavior

The black background is correctly rendered as transparent on Android but not on iOS.

badlogic commented 1 month ago

The iOS code differs from Android's implementation and results in incorrect rendering.

What do you mean by that? The code inside spine-libgdx is the same on all platforms.

On iOS, your atlas .png files are most likely preprocessed by the MobiVM build tools (actually Xcode). Try rendering with premultipliedAlpha false on iOS. If that gives you the correct output, then the preprocessing is at fault, which you can turn off in the MobiVM configuration if I remember correctly.

zyvv commented 1 month ago

The iOS code differs from Android's implementation and results in incorrect rendering.

What do you mean by that? The code inside spine-libgdx is the same on all platforms.

On iOS, your atlas .png files are most likely preprocessed by the MobiVM build tools (actually Xcode). Try rendering with premultipliedAlpha false on iOS. If that gives you the correct output, then the preprocessing is at fault, which you can turn off in the MobiVM configuration if I remember correctly.

The iOS code differs from Android's implementation and results in incorrect rendering.

What do you mean by that? The code inside spine-libgdx is the same on all platforms.

On iOS, your atlas .png files are most likely preprocessed by the MobiVM build tools (actually Xcode). Try rendering with premultipliedAlpha false on iOS. If that gives you the correct output, then the preprocessing is at fault, which you can turn off in the MobiVM configuration if I remember correctly.

Sorry for the confusion. What I meant is that I’m comparing spine-libgdx with the Metal-based spine-ios renderer. For the same spine animation, enabling premultipliedAlpha works correctly in spine-libgdx, but renders incorrectly in spine-ios.

zyvv commented 1 month ago

Animator’s effect: https://github.com/user-attachments/assets/246efe67-c38a-455b-b203-979c04b4fd2e

spine file: explosion.zip

Actual effect on iOS(spine-ios): https://github.com/user-attachments/assets/061bacb4-7e1d-4dee-a98d-684977b614a2

Effect on Android(spine-libgdx): https://github.com/user-attachments/assets/f77f544d-b3bb-4436-a3bc-6597e3729958

As shown in the effects above, spine-libgdx correctly renders the expected result, but spine-ios, it has a black background.

csbz17027 commented 1 month ago

I encountered the same problem! When playing spine through libgdx on Android, the background is transparent, but when using spine-ios with the same settings on iOS, the background is black. Anyone know why this is?

badlogic commented 1 month ago

Please show the code you use to draw that skeleton on iOS, including the SwiftUI scaffold around it with its background settings etc.

zyvv commented 1 month ago

Please show the code you use to draw that skeleton on iOS, including the SwiftUI scaffold around it with its background settings etc.

I am using UIKit, and my code is as follows:

class ViewController: UIViewController {

    private var spineView: SpineUIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let controller = SpineController { controller in
            controller.animationState.setAnimationByName(trackIndex: 0, animationName: "animation1", loop: true)
        }
        let source: SpineViewSource = .bundle(atlasFileName: "mjhl1_1.atlas", skeletonFileName: "mjhl1_1.json", bundle: .main)
        spineView = SpineUIView(from: source, controller: controller)
        spineView.frame = self.view.bounds
        view.addSubview(spineView)
    }
}

I just tried setting the SpineUIView to a different color, such as yellow, and it correctly renders the background color. However, when using the default clear color, it renders the background color as black (the expected effect from the animator is clear).

When using the default clear color, spineView = SpineUIView(from: source, controller: controller) the effect is as follows:

https://github.com/user-attachments/assets/01116c37-77df-43c8-8109-1f75ec071be0

When using the color orange, spineView = SpineUIView(from: source, controller: controller, backgroundColor: .orange) the effect is as follows:

https://github.com/user-attachments/assets/2f56dda6-c974-4d2c-974e-40f4996296d2

csbz17027 commented 1 month ago

Have a solution to the problem?