Fbo as mask texture for alpha mask shader

I have been trying to use the texture from an FBO as a mask source based on the alpha mask shader example (05_alphaMasking from the shaders examples folder). I want to apply a gradient colour to some text drawn with true type font (the gradient is a jpg and loaded as an ofImage) but I cannot get it to work (this is also drawn into an Fbo). It seems like a simple problem, the patter matches, if I use a different texture as the mask, like a jpg it works fine, but the texture from my Fbo does not work, it is plain black and white (white background and black text, so the text should be coloured.

topicTextFbo.begin();
ofClear(255);
ofSetColor(0);
topicFont.drawString( 900, 500);
topicTextFbo.end();

projectionFbo.begin()
ofClear(0);
shader.begin();
shader.setUniformTexture("imageMask", topicTextFbo.getTextureReference(), 1);
gradientImage.draw(0, 0);
shader.end();
projectionFbo.end();

projectionFbo.draw(0,0,1920,1080);

Is there something I need to do to the FBO texture to make it work in a shader?

Hey,

You’re almost there tho I’m not sure what’s going on your shader code, so I’ll just assume.

You’re drawing gradientImage outside of shader but you’ll need to pass it into shader and cooperate with your topicTexFbo. (I’m saying this cause I have no idea how your shader code looks like). So, the code would be like this.

topicTextFbo.begin();
ofClear(255);
ofSetColor(0);
topicFont.drawString( 900, 500);
topicTextFbo.end();

projectionFbo.begin();
ofClear(0);
shader.begin();
shader.setUniformTexture("imageMask", topicTextFbo.getTexture(), 0);
shader.setUniformTexture("gradientImage", gradientImage.getTexture(), 1);

// I assume the size of drawing based on the size you're trying to draw with your fbo below
// and I also assume this is your screen resolution so I'll use gl_FragCoord in shader. 
// if you want to draw image in different resolution with the resolution of screen then you'll need to work on your own texCoord for the rectangle you will draw. 
ofBeginShape();
ofVertex(0, 0, 0);
ofVertex(0, 1080.f, 0);
ofVertex(1920.f, 1080.f, 0);
ofVertex(1920.f, 0, 0);
ofEndShape();

shader.end();
projectionFbo.end();

projectionFbo.draw(0,0,1920,1080);

in fragment shader (I assume you don’t call ofdisablearbtex() if you do you’ll need to change sampler2DRect -> sampler2D, texture2DRect -> texture2D and your texcoord will be gl_FragCoord/vec2(1920,1080))

#version 120
uniform sampler2DRect imageMask, gradientImage;
main(){
    float mask = 1. - texture2DRect(imageMask, gl_FragCoord.xy).g; // inverse it by subtract from 1. cause your textcolor is black. 
    vec3 gradient = texture2DRect(gradientImage, gl_FragCoord.xy).rgb;

    gl_FragColor = vec4(gradient, mask);
}

Hope this help.

oh just one thing, you’re fbo will need to be allocated with rgba, if you don’t wanna deal with alpha then your shader code will be like,

#version 120
uniform sampler2DRect imageMask, gradientImage;
main(){
    float mask = 1. - texture2DRect(imageMask, gl_FragCoord.xy).g; // inverse it by subtract from 1. cause your textcolor is black. 
    vec3 gradient = texture2DRect(gradientImage, gl_FragCoord.xy).rgb;
    
   gradient *= mask; // this will make a black background 
   gradient += (1. - mask); // make a white background. not the best solution if your mask has a gradient but no need to make the code complicated now isn't it heh 😁

    gl_FragColor = vec4(gradient, 1.);
}