Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blend Mode ADD too bright #1077

Closed
mikeevmm opened this issue Mar 31, 2016 · 29 comments
Closed

Blend Mode ADD too bright #1077

mikeevmm opened this issue Mar 31, 2016 · 29 comments

Comments

@mikeevmm
Copy link

From HaxeFlixel repository:

  • Flixel version: 4.0.1
  • OpenFL version: 3.6.0
  • Lime version: 2.9.0
  • Affected targets: Windows, Neko (Presumably mac?)

Code snippet reproducing the issue:

package;

import flixel.FlxState;
import flixel.FlxSprite;
import openfl.display.BlendMode;

class PlayState extends FlxState
{
    override public function create():Void
    {
        add(new FlxSprite(0, 0, "bg.png"));
        var layer:FlxSprite = new FlxSprite(0, 0, "addLayer.png");
        layer.blend = BlendMode.ADD;
        add(layer);
    }
}

bg.png:
parallax_20160331_131939

addlayer.png:
layer 3 add_20160331_131951


Observed behavior:

Expected behavior:

According to @Gama11:

Flixel just passes whatever blend mode a sprite has on to OpenFL's drawTiles API, so there's not much we can do about it. This can very likely be reproduced using only OpenFL.

@Gama11
Copy link
Member

Gama11 commented Mar 31, 2016

Btw, to properly reproduce this, the original image is needed as well.

@mikeevmm
Copy link
Author

@Gama11 As in, the add layer without the blend?

@Gama11
Copy link
Member

Gama11 commented Mar 31, 2016

Yes. How are you supposed to run the code otherwise? :)

@ashes999
Copy link
Member

ashes999 commented Apr 2, 2016

@mikeevmm your art style is pretty awesome. Can you explain why you're using the add layer like this? (Why not just generate the image in GIMP/etc. with the add layer?)

@larsiusprime
Copy link
Contributor

@ashes999 dynamic animated effects is one use case (varying partially transparent overlay w/ blending)

@mikeevmm
Copy link
Author

mikeevmm commented Apr 2, 2016

@ashes999 Thank you, but I'm just the programmer :(

@larsiusprime is spot on.

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 15, 2016

Hey @mikeevmm, I tried to replicate this but haven't been able to (in the sense that both neko and flash gave the same output - or so it seemed). As a side note, github seems to have autoconverted the above layer.png into a jpeg, so losing the alpha values (although I've also tested it by making it a png with white being transparent).

If you can please post a complete project I'm willing to look into it a bit more, can you?

Also: does something change if you use lime test neko --window-hardware=false?

@mikeevmm
Copy link
Author

I'm sorry I've taken so long to reply; school got in the way -- I'll send a complete project asap.

Disabling hardware made the game unbearably slow.

@mikeevmm
Copy link
Author

@azrafe7 Mind if I send you the project privately/through PM or email? I'm working with a team, so I'm not sure whether disclosing art/etc is okay.

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 22, 2016

@mikeevmm, I'd suggest replacing the art files with temp ones (f.e. from here), and post the minimal project publicly so that others can help/take a look at it. (Also, using different assets might also exclude the hypothesis that the problem has to do with incorrect formats).

On the other hand, I'd be glad to take a look at what you have right now (if you feel so inclined). Of course no guarantee I'll be able to find a solution ;)

@mikeevmm
Copy link
Author

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 23, 2016

Ok, this is not a final answer, but here's what I've found so far:

  • code involving blendmodes in legacy is here
  • for what I could gather it's not possible to exactly replicate MULTIPLY using glBlendFunc() (see this post), but the current implementation is a fair enough approximation of it
  • it could be possible to faithfully replicate it by using a shader

As I said, not a final answer (I'll probably tink more with it tomorrow). In the meantime I'd hope to be successful in summoning @mrcdk (sorry to bother you) - who seems quite knowledgeable about the matter at hand - and see what his opinion is about this.

Worth noting is that the ADD blendmode behaves in a very similar way in both flash and neko, while MULTIPLY is much more different.

(f.e.: this is a diff made with imagemagick compare command between flash and neko, using only ADD (no MULTIPLY), with a fuzz factor of 5%):
diff-add-flashvsneko-5p

Also, it seems that blendmodes work correctly with openfl next (anyone correct me if I'm wrong here).

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 25, 2016

Hey @mikeevmm, can you please test the pure-openfl branch here and report what you see by running lime test openfl-project.xml neko -Dlegacy?

I've added 2 screenshots in there that show what I see on my laptop, and was surprised to see that they are very similar (as opposed to what I experienced by running the flixel test).

Don't feel to exclude that I'm doing something different on my end though (I've rebuilt lime ndll quite a few times lately).

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 25, 2016

(I'm starting to suspect that there's something weird with TileSheet, not sure on what side - my code?, openfl?, flixel?)

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 26, 2016

@mikeevmm Maybe I've found a solution... \o/

Not an official fix as this could break somewhere else, but the results are encouraging (and hope someone more knowledgeable than me will chime in to comment).

My understanding is that it has to do with premultipliedAlpha and BlendMode.MULTIPLY.
Might be wrong, but it seems that glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) works correctly only if the supplied texture-to-be-multiplied-with is in premultiplied alpha format.
(curious about the possibility of using glBlendSeparateFunc, feasible??)

Probably the fix could be applied directly to OpenGLContext.cpp, or legacy openfl (haven't tried honestly - and don't forget that this is legacy!).

In the meanwhile please test this repo and report back.

@mikeevmm
Copy link
Author

@azrafe7 thank you! \o/

Will test ASAP

@mikeevmm
Copy link
Author

@azrafe7 Have tested the master branch of your fork; everything looks fine, both on lime and windows:

flash:
image

lime:
image

windows:
image

👍 👍 👍

@azrafe7
Copy link
Contributor

azrafe7 commented Apr 30, 2016

Great! 👍

@mikeevmm
Copy link
Author

mikeevmm commented May 7, 2016

@Gama11 Perhaps this could be temporarily fixed in HaxeFlixel by setting premultiplied alpha to true if blendMode = MULTIPLY and cpp?

@Gama11
Copy link
Member

Gama11 commented May 9, 2016

I'd rather not, that sounds like a pretty nasty hack. Who knows what side-effects enabling premultiplied alpha could have...

@mikeevmm
Copy link
Author

mikeevmm commented Jun 6, 2016

Just a note: with flixelopenfl 4, premultipliedAlpha seems to be gone.

@Gama11
Copy link
Member

Gama11 commented Jun 6, 2016

You mean OpenFL 4?

@mikeevmm
Copy link
Author

mikeevmm commented Jun 6, 2016

Oh, sorry, I made a big mess between branches, premultipliedAlphais a property of BitmapData and not FlxSprite!

And yet, it does seem to be gone?

@Gama11
Copy link
Member

Gama11 commented Jun 6, 2016

Probably a side effect of it only exisiting in OpenFL legacy, and legacy having been removed?

@mikeevmm
Copy link
Author

mikeevmm commented Jun 6, 2016

Legacy has been removed? #if next still yields different results with and without -Dnext

@jgranick
Copy link
Member

jgranick commented Jun 6, 2016

It depends on whether you are using a development branch, or haxelib

@jgranick
Copy link
Member

jgranick commented Jun 6, 2016

The core difference is that old code used non-premultiplied alpha, the new code has premultiplied alpha in textures

This changes how blend modes behave, if you guys have suggestions, I'd be happy to look at moving to blend modes that match the GL blend functions appropriate for premultiplied alpha

Thanks

@mikeevmm
Copy link
Author

mikeevmm commented Jun 7, 2016

@jgranick Ah, I'm a bit out of my league here...

@jgranick
Copy link
Member

jgranick commented Jan 4, 2017

I am closing this issue, because it no longer applies to current OpenFL/Lime releases (very different codebase), but I am also tracking here:

#1414

In general, we need to look at our blend mode support across GL, canvas and Cairo, and visit what we can reliably support out-of-the-box, and what we should consider making up with filters

Thank you

@jgranick jgranick closed this as completed Jan 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants