Binding multiple alpha textures in a GLSL shader


#1

Hi to everyone,
Let’s start by saying sorry for my english, it’s a difficult topic to explain for me.
Practically I’m currently trying to display multiple videos (with alpha channel) in one single frame, the alpha channel is calculated by each shader for every single video, then passed in a FBO, then all the FBOs are passed to another shader which should mix them, the problem is that i can only see one video instead of all of them.

The shader applyied to each video converts black pixels to transparents one, and it seems to work, in fact, if i try to set the color to 0, 255, 0, 255 here’s the result and the code:

vec4 sampleTex(sampler2DRect t) {
vec4 sampledColor = texture2DRect(t, vec2(gl_FragCoord.x, gl_FragCoord.y)).rgba;
//Converting black pixels to transparent pixels
if (sampledColor.r <= 0.035f && sampledColor.g <= 0.035f && sampledColor.b <= 0.035f) sampledColor = vec4(0, 255, 0, 255);
return sampledColor;
}

If i try to return a transparent pixels (Alpha value to 0) i cannot see the background image, i can only see a black background.

I don’t know what to do, i’ve tried everything i know with no results at all, i hope to have some help.


#2

color components in glsl are normalized, you need to use 0…1 not 0…255


#4

Practically what i’m trying to do is:

  • Getting a frame from an ofVideoPlayer
  • Calculating alpha channel and saving it into an FBO by using a shader

    shader.begin();
    shader.setUniformTexture(“tex”, videoPlayer.getTexture(), 0);
    m.draw();
    shader.end();
  • Looping through an array of FBOs, and than displaying all the selected ones at once

    for (int i = 0; i < N_FX; i++) {
    deckADrawingVector[i].allocate(ofGetWidth(), ofGetHeight(), GL_RGBA);
    if (gui->deckASelectedFx[i] != 0) {
    deckADrawingVector[i].begin();
    ofClear(0, 0, 0, 0);
    deckA[i]->draw();
    deckADrawingVector[i].end();
    }
    else {
    deckADrawingVector[i].begin();
    deckADrawingVector[i].clear();
    ofClear(0, 0, 0, 0);
    deckADrawingVector[i].end();
    }
    }
  • The shader is in charge of merging all the textures

    blendShader.begin();
    blendShader.setUniformTexture(“tex_0a”, deckADrawingVector[0].getTexture(), 0);
    blendShader.setUniformTexture(“tex_1a”, deckADrawingVector[1].getTexture(), 0);
    blendShader.setUniformTexture(“tex_2a”, deckADrawingVector[2].getTexture(), 0);
    blendShader.setUniformTexture(“tex_3a”, deckADrawingVector[3].getTexture(), 0);
    blendShader.setUniformTexture(“tex_4a”, deckADrawingVector[4].getTexture(), 0);
    blendShader.setUniformTexture(“tex_5a”, deckADrawingVector[5].getTexture(), 0);
    canvas.draw(); // This is the plane mesh where we are going to draw
    blendShader.end();

    Here’s the blend shader frag code:

    #version 150
    uniform sampler2DRect tex_0a;
    uniform sampler2DRect tex_1a;
    uniform sampler2DRect tex_2a;
    uniform sampler2DRect tex_3a;
    uniform sampler2DRect tex_4a;
    uniform sampler2DRect tex_5a;

out vec4 outputColor;

vec4 sampleTex(sampler2DRect t) {
return texture2DRect(t, vec2(gl_FragCoord.x, gl_FragCoord.y)).rgba;
}

void main()
{
vec4 out0a = sampleTex(tex_0a);
vec4 out1a = sampleTex(tex_1a);
vec4 out2a = sampleTex(tex_2a);
vec4 out3a = sampleTex(tex_3a);
vec4 out4a = sampleTex(tex_4a);
vec4 out5a = sampleTex(tex_5a);

outputColor = out0a + out1a + out2a + out3a + out4a + out5a;

}


#5

Try changing the location to be unique for every texture you pass in.
blendShader.setUniformTexture(“tex_0a”, deckADrawingVector[0].getTexture(), 1);
blendShader.setUniformTexture(“tex_1a”, deckADrawingVector[1].getTexture(), 2);
blendShader.setUniformTexture(“tex_2a”, deckADrawingVector[2].getTexture(), 3);


#6

I’ve tried but nothing happend,
The shader works if i try to nest a video and a simple sketch without a video in it, i’ve tried to create a simple sketch which draws a bunch of squares and it works flawlessly, so it seems that the alpha calculation in the shader isn’t working.


----EDIT----
Okay, I managed to get some improvements by changing a bit the fragment shader which calculates alpha

vec4 sampleTex(sampler2DRect t) {
vec4 sampledColor = texture2DRect(t, vec2(gl_FragCoord.x, gl_FragCoord.y)).rgba;
if (sampledColor.r <= 0.045f && sampledColor.g <= 0.045f && sampledColor.b <= 0.045f) discard;
return sampledColor;
}

But now the shader only draws when the background pixel alpha value is 0