On TextureOptions, PreMulitplyAlpha, Blendfunctions + Alpha

  ... tutorials on how to use AndEngine.

On TextureOptions, PreMulitplyAlpha, Blendfunctions + Alpha

Postby Nicolas Gramlich » Thu Oct 14, 2010 1:16 pm

Hello Community,

recently I fixed a visual bug that was hiding in AndEngine. It caused sprites that have antialiased edges or somewhat differently caused semi-transparency to have a kind of greyish halo around them. See this screenshot:
wrong-color-after-blending.PNG
wrong-color-after-blending.PNG (223.58 KiB) Viewed 7385 times


This visual bug was caused by the so called "pre-multiplication of alpha values" when loading an image onto a Texture using the Android internal method:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. GLUtils.texSubImage2D(...)
Parsed in 0.012 seconds, using GeSHi 1.0.8.4


So what I did was adding a couple of new TextureOptions that allow us developers to use that "pre-multiplication of alpha values"-feature or not. Internally the Sprites/Text/... objects get another Blendfunction applied.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public static final int BLENDFUNCTION_SOURCE_DEFAULT = GL10.GL_SRC_ALPHA;
  2. public static final int BLENDFUNCTION_DESTINATION_DEFAULT = GL10.GL_ONE_MINUS_SRC_ALPHA;
  3.  
  4. public static final int BLENDFUNCTION_SOURCE_PREMULTIPLYALPHA_DEFAULT = GL10.GL_ONE;
  5. public static final int BLENDFUNCTION_DESTINATION_PREMULTIPLYALPHA_DEFAULT = GL10.GL_ONE_MINUS_SRC_ALPHA;
Parsed in 0.011 seconds, using GeSHi 1.0.8.4


Visually you won't see any difference when using a simple sprite as long as you do not (directly or indirectly) touch the setAlpha() method of that Sprite.

So what does all this mean for you :?:
The changes to your code are either Zero or not dramatic and most likely fixable within seconds but we should understand what is actually going on here.

The DEFAULT TextureOptions[/url ](when not specifying one manually when creating a [url=http://code.google.com/p/andengine/source/browse/src/org/anddev/andengine/opengl/texture/Texture.java]Texture) is NEAREST_PREMULTIPLYALPHA which is how it was all the time before. The difference is that where the default Blendfunction before was (GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) it is now: (GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA) as so there are no more dark halos as shown in the beginning. :)

:exclamation: But there is a little drawback here, when using any of the _PREMULTIPLYALPHA TextureOptions with its default (GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA) Blendfunction AND changing the alpha-value of the sprite manually through setAlpha or an AlphaModifier to a alphavalue < 1.0f, the results look somewhat weird :!:

PREMULTIPLYALPHA_WITH_setAlpha.png
PREMULTIPLYALPHA_WITH_setAlpha.png (1.23 KiB) Viewed 7385 times


This can be fixed either by swapping the Blendfunction back to the 'old' (GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) which will give you back the 'dark halos' described in the beginning or by doing the following trick, which will NOT give you those 'dark halos' and still allow you to dynamically set the Alpha of that Sprite:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. final Sprite sprite = new Sprite(x, y, this.mSomeTextureRegion) {
  2.         @Override
  3.         public void setAlpha(float pAlpha) {
  4.                 super.setAlpha(pAlpha);
  5.                 super.setColor(pAlpha, pAlpha, pAlpha); // <-- This is the trick !
  6.         }
  7. };
Parsed in 0.013 seconds, using GeSHi 1.0.8.4


So to summarize and give solutions for possible problems:
  • :exclamation: In the case you simply want to have everything as it was before the introduction of this weird PREMULTIPLYALPHA thing, you'd do this:
    1. Change all your Texture to use a PREMULTIPLYALPHA TextureOption.
    2. Apply the (GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) to all Sprites/Texts you create...

  • :exclamation: In the case you've had dark halos or other darkened areas on a sprite that should be semi-transparent:
    • :check: Change the TextureOptions to the corresponding one ending with *._PREMULTIPLYALPHA.

  • :exclamation: In the case calling setAlpha directly or indirectly on a Sprite that is using the *._PREMULTIPLYALPHA TextureOptions doesn't really make it transparent:
    • :check: Apply the above "setAlpha"-trick.
    • :check: OR swap back to the NOT *._PREMULTIPLYALPHA TextureOptions if you don't care or don't need to care about the 'dark halos'.

Hope this helped more than it destroyed :P

Best Regards,
Nicolas
Nicolas Gramlich
Site Admin
 
Posts: 1734
Joined: Mon Jun 07, 2010 6:20 pm
Location: Schriesheim, Germany

Re: On TextureOptions, PreMulitplyAlpha, Blendfunctions + Al

Postby jam » Thu Jan 13, 2011 9:49 am

but there is Shadow like the picture
Attachments
yingying.png
yingying.png (27.95 KiB) Viewed 6929 times
jam
 
Posts: 13
Joined: Tue Dec 28, 2010 3:40 am

Re: On TextureOptions, PreMulitplyAlpha, Blendfunctions + Al

Postby zorobabel » Tue Jan 24, 2012 7:47 pm

Good tutorial!
zorobabel
 
Posts: 20
Joined: Wed Jan 18, 2012 4:50 pm

Re: On TextureOptions, PreMulitplyAlpha, Blendfunctions + Al

Postby igor.mats » Sat Dec 08, 2012 1:33 pm

Thanks! It's great solution!
igor.mats
 
Posts: 55
Joined: Mon Jul 11, 2011 3:17 am

Re: On TextureOptions, PreMulitplyAlpha, Blendfunctions + Al

Postby Sergio » Wed May 28, 2014 4:42 pm

Thanks Nicolas, you're a genius.
Image
Sergio
 
Posts: 14
Joined: Wed Jul 10, 2013 6:12 pm


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 8 guests