[Solved][Libgdx] How do I blend textures? (like Flash)

Back then when I was working with Flash and Actionscript, I can blend sprites like this:


main.addChild(backgroundSprite);
overlaySprite.blendMode = BlendMode.OVERLAY;
main.addChild(overlaySprite);

In which overlaySprite will be overlayed on top of backgroundSprite.

How would I achieve the same thing using Libgdx? I’ve tried messing around with textures and the spritebatch, but I couldn’t really get it working, and I’m not that much experienced with shaders. But if it can be as simple as to how it was done in Flash, then it could be simple with Libgdx too, right?

batch.enableBlending();

Or if you’re using Material use:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/attributes/BlendingAttribute.html

But blending is enabled by default, and if I simply rendered the overlay sprite on top of the other sprite, then I assume the blend mode would be “normal”, not “overlay”?

Nope, it’s just in 2D, although might come in handy for other people

You can try to emulate that blend function with the gl blend mode settings, but i doubt that they are customize-able enough to allow for that specific effect.
Example for additive blend:

Gdx.gl.glBlendEquation( GL20.GL_FUNC_ADD );
Gdx.gl.glBlendFunc( GL20.GL_SRC_ALPHA, GL20.GL_ONE );

This below is what you are trying to achieve right?

Looks like you need a custom shader ;D
You could “just” copy the shader files and classes from the libgdx source to your project and add your blend function.

I’ll try that out, thanks!

Bear in mind that to do custom blending in a shader you need to do multi-texturing with an additional texture having a copy of the destination region of the sprite - you cannot read the existing pixel colour from a shader.

I highly recommend you use pre-multiplied alpha if you want to do lots of different blending or you can soon run into trouble. In which case the above additive blending would be -


Gdx.gl.glBlendFunc( GL20.GL_ONE, GL20.GL_ONE);

Without shaders using the built-in blend function you can at least cover normal blending, additive blending, subtract blending, and multiply blending.

These slides from an NVidia talk about their blending extension is worth a flick through too (and check out slide 16 if you’re questioning my position on pre-multiplied alpha! :wink: )

Alright, after looking some more, I finally got the answer:


//render first image
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA); //Acts like Flash/Photoshop's overlay
//render next image

Found it here

^^^ There is no way that is Overlay! :wink:

Well it’s not the wrong one either, so whatever it is, I’m not complaining! 8)

If the effect works for you, fine. But it’s not “useful for people lurking Google searches” because you’re replicating a wrong answer to your question!

Fine, I guess you’re right. But if it’s not overlay, what is it? And why did it work?

It’s a weird (lighter) version of Multiply, which would normally be -


batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA)

That assumes the source (sprite) is pre-multiplied alpha or opaque (otherwise you can’t do Multiply). Multiplying the destination by SRC_ALPHA is unlikely going to match any of the Photoshop / Flash blend modes, because they tend towards a no-op as the source becomes transparent, whereas in that case a transparent source would erase the destination (ie. 0 * DST).

In this case, for opaque pixels you’re effectively doing


batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE)

which is Multiply and Add together ((SRC * DST) + DST). The reason it may look similar to you is that Overlay is defined as a brighter Multiply operation (2 * SRC * DST) where the source colour is below half. It’s not Overlay, but depending on the colours in your source image may be close enough.