PDA

View Full Version : render textures with blend



phil0stine
01-28-2018, 10:52 AM
Simple setup, fbo with 2 textures which I want to render to the default framebuffer with blending. If I render one or the other texture, the screen renders what I would expect, including alpha transparency. But, if I try to render both one after another, only one (the first) of the two is rendered. My basic setup:

Simple shaders:

#version 450 core
layout (location = 0) in vec3 vert;
layout (location = 1) in vec2 texCoord;
out vec2 fTexCoord;
void main() {
fTexCoord = texCoord;
gl_Position = vec4(vert, 1);
}


#version 450 core
uniform sampler2D tex;
in vec2 fTexCoord;
out vec4 fColor;
void main() {
fColor = texture(tex, fTexCoord);
}


Assuming the handles corresponding to the input textures are tex1 and tex2, which I want to blend (and again render fine individually):



glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glDepthMask(GL_TRUE); // Enable depth test (z-buffer)
glDepthFunc(GL_LESS); // z buffering
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// ...
// ... set up blend program
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex1);
blend_program->SetUniform("tex", 0);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, render_indices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex2);
blend_program->SetUniform("tex", 0);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, render_indices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
// unbind program

GClements
01-28-2018, 12:12 PM
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex2);
blend_program->SetUniform("tex", 0);


You're binding the texture to texture unit 1 but setting the uniform to 0.

Also:




glDepthFunc(GL_LESS); // z buffering


If you draw the same geometry twice, the second pass will have all fragments fail the depth test. You need to use GL_LEQUAL if you want them to pass.

phil0stine
01-28-2018, 04:28 PM
You're binding the texture to texture unit 1 but setting the uniform to 0.


That was an artifact of the many permutations I went through to before posting, although I don't know whether it's best to bind to different texture units or overwrite texture unit 0.

Also:



If you draw the same geometry twice, the second pass will have all fragments fail the depth test. You need to use GL_LEQUAL if you want them to pass.

This, on the other hand, was a life-saver of a catch. Many other things that weren't rendering that I didn't even mention began working, and it makes perfect sense.

Unfortunately, with the setup before, and fixing the binding to the wrong texture unit, now only the second of the textures is rendered....

GClements
01-29-2018, 06:38 AM
Unfortunately, with the setup before, and fixing the binding to the wrong texture unit, now only the second of the textures is rendered....
Does the second texture have an alpha channel?

What happens if you change the blending function to glBlendFunc(GL_ONE,GL_ONE)? That should result in additive blending (i.e. both textures should have an effect regardless of the presence of an alpha channel).

phil0stine
01-29-2018, 09:01 AM
Does the second texture have an alpha channel?


Turns out, both textures were setup incorrectly, with


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width_, height_,
0, GL_RGB, GL_FLOAT, NULL);

instead of


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_,
0, GL_RGBA, GL_FLOAT, NULL);

What threw me off is that, by changing the alpha value I was using as a test, I could see each one's transparency change as expected when rendering only one texture. Why that is, I am still not sure. Nevertheless, this was the final issue, great catch again considering I didn't even post the setup code. Thanks for helping me learn to diagnose.