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.
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?
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! more info in my original post
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
);
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:
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!
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.
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.
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.)