Weird problem rendering semi-transparent image to FBO

hi… I have been working on some stuff using FBO’s lately… and I’m having a weird problem when I draw a semi-transparent ofImage to the FBO.

I am using the ofFBOTexture class from here: http://forum.openframeworks.cc/t/fbo-addon-for-0.06/1866/12

Basically when I draw the image several times at a small offset (so it overlaps), I want the transparent pixels to accumulate and get stronger as its repeated.

What’s happening though, is that the transparent pixels don’t accumulate and just keep being drawn transparently… almost like it’s accumulating the alpha values and becoming more transparent.

Here is a screen capture illustrating what I mean…

The more transparent blue line (top) is the one rendered to the FBO.
The more opaque blue line (below) is the exact same thing, except drawn directly to the screen. This is the result I am trying to get in the FBO.

[attachment=0:2pkm9y7k]fboRenderingTest.png[/attachment:2pkm9y7k]

I’m guessing it’s probably a simple setting or openGL flag that I’m missing in my FBO?

Any help would be great!

yes, you need to enable alpha blending before writing to the fbo:

  
fbo.swapIn();  
glEnable(GL_BLEND);  
gllBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
...  
fbo.swapOut();  
  

i actually have an enableAlphaBlending inside the fbo to do that so you just need to call:

  
fbo.swapIn();  
fbo.enableAlphaBlending()  
...  

hmm, my copy of fbo doesn’t have enableAlphaBlending… I tried adding the lines you said, just after my swapIn … but I get the same result

are you drawing the FBO transparently? that could cause some issues. If so you should try to draw just to an RGB fbo and see if that changes anything.

Hmm, so I tried disabling alpha blending before I draw the FBO… and the brush stroke renders properly, but I lose the transparent background from the FBO… any ideas how I could still have a transparent background?

I remember memo had some similar issues a while back. It’s some weirdness on how openGL handles alpha:
http://forum.openframeworks.cc/t/fbo-problems-with-alpha/1643/0

I guess it won’t help, but you should check if you reset glColor4f to (1,1,1,1) before drawing the FBO…

Yup, i had the exact same problem as Moka pointed out with a link to my to my frustrated posts.

I found that you need to have blending enabled while drawing to the FBO and still enabled when drawing the FBO to the screen (at least in my case). But when you do that the alpha is multiplied by itself everytime it gets drawn, so gets fainter and fainter. I.e. if you draw with alpha 50% to the fbo, by the time it gets drawn to the screen it is 25% (0.5 x 0.5). I could not find a solution to this problem.

In some instances you can get away with drawing to the fbo with blending disabled, but turn on blending when drawing the fbo to the screen. Since the fbo still has the alpha data in it’s pixel buffer, it draws to the screen with the correct blending… but this scenario isn’t always viable depending on what you are drawing (see the simple example I posted on the other thread).

If you do find a workaround / solution please let us know!!

EDIT: i said above that alpha 50% becomes 25%, actually thats not true, it becomes 31/255 for some reason! :confused: more info in my original post

Hi,

I met this before, and I hope my solution fits your problem. My problem was that I wanted the result of the RTT-stage blitted into the Framebuffer, without altering the colro or alpha-value.

[quote author=“memo”]Yup, i had the exact same problem as Moka pointed out with a link to my to my frustrated posts.

I found that you need to have blending enabled while drawing to the FBO and still enabled when drawing the FBO to the screen (at least in my case). But when you do that the alpha is multiplied by itself everytime it gets drawn, so gets fainter and fainter. I.e. if you draw with alpha 50% to the fbo, by the time it gets drawn to the screen it is 25% (0.5 x 0.5). I could not find a solution to this problem.[/quote]

The pixel-data in the buffer has premultiplied alpha, this means, the alpha was taken into account when rendering the colors into the texture. Observe your glBlendFuncs and you’ll see why. When you render this pixel-data again via OpenGL you’ll have to adjust the blend-func to get the alpha straight.

For the RTT-stage use your normal glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

When rendering the RTT-texture use a different BlendFunc like glBlendFunc(GL_SRC_ALPHA, GL_ONE);

For my problem I had to separate the blendfunc for color and alpha: This is what I am doing in OpenSceneGraph:

  
  
g->getOrCreateStateSet()->setAttributeAndModes(  
    new osg::BlendFunc(  
        osg::BlendFunc::SRC_COLOR, osg::BlendFunc::ONE_MINUS_SRC_COLOR,   
        osg::BlendFunc::ZERO, osg::BlendFunc::SRC_ALPHA),  
    osg::StateAttribute::ON  
);  
  

this translates to glBlendFuncSeparate, see http://www.opengl.org/sdk/docs/man/xhtm-…-parate.xml for the specs.

HTH,
Stephan

After searching today I also came across glBlendFuncSeperate but still could not fix it.

Hmm… I tried playing with the glBlendFuncSeparate function a bit, and it seems like it’s a step in the right direction, I just can’t seem to get the parameters right. Right now, I’m getting what looks like the right result for everything except the FBO’s background…

Here’s a screen cap. the white box is the FBO being rendered… and you can see it has the semi-transparent pixels around the edge of the blue stroke… But it’s still rendering a solid background (I cleared the fbo using glClearColor(0.0f, 0.0f, 0.0f, 0.0f);). The second blue line (lower down) is drawing directly to the screen what I draw in the FBO.

I’m drawing to the FBO with normal ofEnableAlphaBlending(), and then drawing it to screen using this blend configuration:

  
  
	glEnable(GL_BLEND);  
	glBlendFuncSeparate(GL_ONE, GL_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
  

[attachment=0:1tghbaj0]fboRenderingTest1.png[/attachment:1tghbaj0]

I have some other workarounds in mind that I will try for now… but glBlendFuncSeparate seems like it’s probably the right way to go if I can get it working!

Hmm… managed to get it blending with the transparent background… But now it seems to be having troubles blending the colours properly…

Using this blending mode when I render into the FBO…

  
  
	glEnable(GL_BLEND);  
	glBlendFuncSeparate(GL_ONE, GL_SRC_COLOR, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);  
  

And normal glEnableAlphaBlending() when I draw the FBO to screen, I get this result:

[attachment=0:1sompiv9]fboRenderingTest3.png[/attachment:1sompiv9]

I’m not sure if it’s helpful, but I recently had a problem with alpha and drawing into an FBO… I was getting mixtures that didn’t look right…

this paged helped alot:

http://www.opengl.org/discussion-boards-…-ber=257628

I wound up replacing ofEnableAlphaBelnding with

glBlendFuncSeparate(GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);

and for what I was doing, it seemed to make blending (in the fbo) be more normal… I wasn’t doing transparent fbo tho.

  • zach

just out of curiosity, did you fix it?

We haven’t found a solution to the alpha rendering problem yet. I found a temporary workaround using GL_ALPHA_TEST, which works OK for a quick fix, but definitely isn’t the desired end result. Alpha blending seems to work properly inside the FBO, but I need to disable alpha blending for it to draw on the screen properly. Using ALPHA_TEST lets me disable alpha blending, but still hide any transparent pixels. What I really want to do though is have alpha blending working inside the FBO, and also be able to draw the FBO to the screen with a transparent background and with the semi-transparent pixels blended with the screen.

  
  
	glEnable(GL_ALPHA_TEST);  
	glAlphaFunc(GL_GREATER, 0.0f);  
	fbo.draw(0, 0, 500, 500);  
	glDisable(GL_ALPHA_TEST);  
  

I’ve attached a test project that draws a test pattern to an FBO at the start. Then each frame, renders the FBO to the screen (upper ‘X’), and also draws the test pattern directly to the screen. In the test project, how the test pattern that gets drawn directly to the screen (lower ‘X’) is ideally what I am trying to achieve with the FBO.

I’ve been playing with so many different options for glBlendFunc, but can’t seem to get it to draw correctly. If anyone is up for an interesting FBO alpha blending challenege, it’d be great if you could help us find a solution.

Thanks for all the help so far!

fboAlphaRenderTest.zip

hi plong0, i met this problem. your solution can’t download ,so can you share your solution again? or tell me how to fix this problem. thanks

The thing that solved this for me was to do ofSetColor(255,255,255,255); before drawing the FBO.
Otherwise, if you have set a different color, it apparently gets multiplied

(Sorry for digging out this old thread, but maybe this helps someone.)

Actually.

glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

This worked for me if put just before the fbo.draw().

Note the GL_ZERO instead of GL_SRC_COLOR.

1 Like