0
votes

I'm trying to add two textures (.PNG) images in LibGDX to my own shader. Everything works great, except the math/ blending part. Hopefully someone can help me with this blending problem!

enter image description here

This is my base texture. (256 x 256 px, 32-bit texture)

enter image description here

This is my "ontop" texture. (256 x 256 px, 32-bit texture)

enter image description here

The effect I want. A simple base texture with another texture ontop, ofcouse with the transparency working.

enter image description here

And the current result. Blending between the textures, a bit brighter where the "dots" of the texture are.

I've tried several different solutions. This is from renderer, my class that implements the Shader of LibGDX:

     Gdx.gl20.glEnable(Gdx.gl20.GL_BLEND); <-- Doesn't do any difference.
     Gdx.gl20.glBlendFunc(Gdx.gl20.GL_ONE, Gdx.gl20.GL_ONE_MINUS_SRC_ALPHA); <-- Dosen't do any difference with the cube, but make vertices transparent on a more advanced mesh.

The fragment shader:

 #ifdef GL_ES 
 precision mediump float;
 #endif

 varying vec2 v_texCoord0;
 uniform sampler2D u_texture1;
 uniform sampler2D u_texture2;
void main() {
vec4 bodyColor = texture2D(u_texture1, v_texCoord0);
vec4 addColor = texture2D(u_texture2, v_texCoord0);

gl_FragColor = bodyColor + addColor;
}

Something is clearly wrong.

1

1 Answers

1
votes

Since you're mixing the two textures from within the shader, blend functions have nothing to do with this.

Your current shader just adds the two colors, which is the same if you had drawn two meshes, with the second one using GL_ONE, GL_ONE.

You actually want the second texture to completely replace the first texture based on its alpha, the same as if you had drawn two meshes, with the second one using GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA. This means the RGB of texture two is multiplied by its alpha, while the RGB of the texture one is multiplied by (1- texture2's alpha). And then the two results are added together.

So you create the same equation that a blend function would have done, but now we do it in the shader.

gl_FragColor = vec4(bodyColor.rgb*(1.0-addColor.a) + addColor.rgb*addColor.a, 1.0);

I think you could also write it like this; performance is probably equivalent, but possibly better if the GPU has a way to optimize the mix function:

gl_FragColor = vec4(mix(bodyColor.rgb, addColor.rgb, addColor.a), 1.0);

That final 1.0 is your output alpha. You didn't specify what kind of resulting alpha you want for the final output. If you want the whole thing to inherit the alpha of your base texture, change the 1.0 to bodyColor.a.