Search code examples
opengl-eslibgdxblending

How to blend two texture colors in Libgdx


I'm trying to blend two circles, one black and the other white. The parts where they intersect must be in grey. I tried to use blend functions but I don't get the expected results.

The objective is to mix ONLY this two elements, other elements (like the background) can't mix there, and I don't know how to do this maintaining the 100% of the alpha channel.

This is my current render code, circle1 and circle2 are TextureRegion.

public void draw(Batch batch, float parentAlpha) {
    super.draw(batch, parentAlpha);
    batch.enableBlending();
    batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE);

    batch.draw(circle1, c1.getX(), getY(), getWidth(), getHeight());
    batch.draw(circle2, c2.getX(), getY(), getWidth(), getHeight());

}

This is an example of the color mix. blend example

EDIT: Problem solved. I did a test using Spritebatch, I drew a third circle with reduced opacity, this is the code used to test and the result:

        Gdx.gl20.glEnable(GL20.GL_BLEND);
        Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setColor(1, 1, 1, 1f);
        shapeRenderer.circle(15, 5, 5);
        shapeRenderer.setColor(0, 0, 0, 1f);
        shapeRenderer.circle(19, 5,5);
        shapeRenderer.setColor(1, 1, 1, 0.5f);
        shapeRenderer.circle(15, 5, 5);
        shapeRenderer.end();
        Gdx.gl20.glDisable(GL20.GL_BLEND);

solved problem


Solution

  • I've never used libGDX so I'm not sure how the specific implementation goes, but I'll give you the general outline of what you're trying to achieve.

    The most basic blending you can achieve is a linear blend between two colors with a single parameter t. Consider this example - let's say each color is represented by a single channel value for simplicity - black is 0.0 and white is 1.0. What you want to achieve is the mid range gray that is 0.5, to do this you would blend by scaling each channel appropriately ( black * 0.5 + white * 0.5 = 0.0 * 0.5 + 1.0 * 0.5 = 0.5)

    A more sophisticated way of blending colors is by using the source alpha channel to govern the blend weight, so say you have a color black and a color white with 0.4 alpha, or opacity. You would blend using the following method black * 0.6 + white * 0.4 (your alpha sums up to 1.0), which would give you 0.4 a slightly "darker" than mid range gray.

    To tie this back to your question, you specify the blend method as ONE, ONE, i.e, you're doing black * 1 + white * 1 which should result in 1 (all white).

    Looking over the docs for libGDX, you have either the GL_ONE_MINUS_CONSTANT_ALPHA option for constant weight blend, or if you want to do "alpha blending" you could go for GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA.

    Hope this helps and clears up blending a bit :)