PDA

View Full Version : Weird transparency behavior when I render a texture over another



zaldivar.alvarez
06-22-2016, 11:47 PM
Hi guys,
I've been using opengl for a while but there is always a lot new to learn everyday. I hope you can give me a hand, so here's my problem:

I am drawing two 2D textures, one over the other. One of them has transparency, is a texture created from a png file with alpha channel, the other one is another texture from png file but with no alpha channel. The thing is, when I put the texture with alpha over the other without alpha, the one with alpha makes me able to see through it just like if there is no another texture behind. (See the picture attached for more accuracy on the situation, please).

- I am drawing 2D and 3D models, each one with their own projection (ortho and perspective respectively).
- I already enabled the blend function using this:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- My fragment shader, for 2D, just gives the following value to fragcolor:
FragColor = texture(textureSampler, UV); where "textureSampler" is a sampler2D and "UV" are the texture coordinates.
- I am creating the texture like this (I'm using SDL_Image for simplicity on image creation from PNG):
SDL_Surface* image = IMG_Load(filePath.c_str());

glGenTextures(1, &textureId);

glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
image->w, image->h,
0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);

With the information I provided, do you guys have any ideas about this?

I appreciate so much your help :)

*** Attached Image *** (https://1drv.ms/i/s!Aj6XOY-Ou018hpIeK1cIVD3H4ZvxNQ)

john_connor
06-23-2016, 01:46 AM
I am drawing two 2D textures, one over the other. One of them has transparency, is a texture created from a png file with alpha channel, the other one is another texture from png file but with no alpha channel. The thing is, when I put the texture with alpha over the other without alpha, the one with alpha makes me able to see through it just like if there is no another texture behind.



glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// ...

FragColor = texture(textureSampler, UV);


if you enable blending, the alpha-component becomes relevant (depending on the blend function you choose)
https://www.opengl.org/sdk/docs/man/html/glBlendFunc.xhtml

you have 2 textures, 1 has alpha (RGBA), and the other hasnt (RGB)
"completely transparent" means that alpha = 0, "completely opaque" means alpha = 1

the glsl-function texture(textureSampler, UV); grabbs 4 components (vec4): RGBA
if you use that function to sample the colorvalue on a texture that has only 3 components (RGB), you are getting 1 unknown: the alpha component (i assume that it will be 0 by default)
in order to grab only 3 components (those available: RGB), use texture(textureSampler, UV).rgb;

your blendfunction means:
the weight factor for the incoming color value ________________________ will be (alpha)
the weight factor for the color value that's already written in the framebuffer will be (1 - alpha)
if alpha = 0, then the incoming fragment color wont have any effect ("completely transparent")


Transparency is best implemented using blend function (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) with primitives sorted from farthest to nearest.

that means the order of the drawn primitives matters

zaldivar.alvarez
06-23-2016, 10:39 AM
Hi, thanks for the reply.

I think I get your idea, but both textures were created using the same image format "RGBA", so when I say that my back texture has no transparency, I mean its alpha is 1 (opaque), that's why I dont use myvec4.rgb.

What I still dont get, is why my transparent texture is showing the 3D scene (which is good), just like if the texture were overwritting the one at the back.

john_connor
06-23-2016, 11:53 AM
What I still dont get, is why my transparent texture is showing the 3D scene (which is good), just like if the texture were overwritting the one at the back.

i dont see this anywhere:

glEnable(GL_DEPTH_TEST);

have you tried to render a constant alpha value for both textures, like that:
vec3 color = texture(...).rgb;
gl_FragColor = vec4(color, 0.5);

zaldivar.alvarez
06-23-2016, 05:33 PM
i dont see this anywhere:

glEnable(GL_DEPTH_TEST);


Hey my friend,
I just realized that I had to disable the depth test whenever I want to draw a translucent texture, although with that, as you said, the order of drawing really matters. That solved my issue! (you can check the result in the attached image)

Thank you very much for your help, I really appreciate it.

Have a good one!
MJ


*** ATTACHED IMAGE *** (https://1drv.ms/i/s!Aj6XOY-Ou018hpIfbTmjT_EvnfLn7w)