Super simple fade effect not working

Hey,

I’m doing this super simple fadout effect by drawing a transparent rectangle in a fbo which wasn’t working so I made basic app without fbo and other stuff and still have the same problem. I have been using this technique a few times in the past in Cinder and OF. I feel stupid asking this but I’m kinda clueless why it’s not working.
Tested with the latest release of Cinder on OSX.

The below program should output a white trail coming from the mouse movement.

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class fadeoutApp : public App {
  public:
    
	void draw() override;
       bool clearedOnceAtStartup = false;
};


void fadeoutApp::draw()
{
    
    gl::enableAlphaBlending();
    
    // clean the screen only once at startup
    if(!clearedOnceAtStartup){
        clearedOnceAtStartup = true;
        gl::clear();
    }
    
    
    // draw transparent black
    gl::color(0, 0, 0, 0.01);
    gl::drawSolidRect(ci::Rectf(0,0,getWindowWidth(),getWindowHeight()));
    
    //drawing a white circle
    ci::gl::color(1, 1, 1);
    ci::gl::drawSolidCircle(getMousePos(), 20);
}

CINDER_APP( fadeoutApp, RendererGl )

Hi,

I think what is happening is that OpenGL’s double buffering is causing the flickering. It uses two main buffers that alternate, so one is used for the odd frames and the other for the even frames. The distortion of the graphics might be a driver, memory or concurrency issue due to differences in the OpenGL 3.3+ driver compared to the old, pre 3.3 GL.

I’d recommend using an Fbo, because only then do you have complete control over the buffer you’re drawing to. See this gist I created based on your code.

For an even better fade-out, use two Fbo's and a special shader that reads the color from the other Fbo and draws it slightly darker without having to rely on blending modes.

-Paul

1 Like

Why not gl::clear() every frame, then just increment the fade amount as time passes? You’ll usually need to clear out the main renderbuffer each frame anyhow, once things start to be moving.

Hey Paul,

Thx for the super documented code, I did test something like that before but then always got stuck on the the issue where it doesn’t get completely black. Probably has something todo with blending modes where the alpha doesn’t get calculated like I expect it to be? Maybe I should read the theory on how these blend functions work again.
https://vimeo.com/187091325

@rich.e do you mean drawing the whole trail every draw and fading each individual circle?

The fading is not perfect, because of precision issues. You can either increase the alpha value of the black rectangle from 4.0f / 255.0f (8.0f / 255.0f seems to work for me), or use float precision on your Fbo. The latter can be done like this in resize:

gl::Fbo::Format fboFormat;
fboFormat.setColorTextureFormat( gl::Texture2d::Format().internalFormat( GL_RGBA32F ) );
mFbo = gl::Fbo::create( getWindowWidth(), getWindowHeight(), fboFormat );

-Gabor

1 Like

Wow thx for this fix. It makes sense but I would never found this on my on.
Thank you all for the help!