Motion blur?

How I do fast motion blur in OpenGL under Win9X?

You need a graphic card that supports accumulation buffers in hardware. Currently there is no such cards in the consumer market but it’s soon to come (ATi Radeon and Voodoo4/5 (well, i wouldn’t recommend the Voodoo’s …))

or else you could render more than once your scene or object.

1: render the scene as usual
2: render the scene 3-4 times with alpha blending, by varying the time point.

IT IS harder this way, but i think it would be faster than to use not-hw-accelerated accumulation buffer available on consumer cards today.

Dolo//\ightY

You reckon it’d be harder? I can’t remember if it’s just my twisted imagination, but try seeing if there is a glAlphaScale() func to modify the alpha values you write. It may opnly apply to read/writing bitmaps, tho’.

in fact, i can’t find the accursed function, but it’s the state variable GL_ALPHA_SCALE i’m talking about. surely motion blur on this per primitive basis can be reduced quite simply to:

setUpBlending();
for(i=0; i<frames; i++) {
moveObjectFractionOfAFrame();
setAlphaScale((i+1)/frames);
drawObject();
}

???

i don’t think you need to go through each vertex and set the alpha channel “manually”.

cheers
John

soldier of fortune game uses motion blur for the knife animations, and i believe it does by direct modification of the alpha value.

it would be interesting to have a function wich changes the defaul alpha value of a glColor3() function… in fact, if not specified, alpha defaults to 1.

i know there’s an extension for a overall alpha scaling value: with that ext, per primitive motion blur would be easier.

…another way could be to use material colors: i didn’t tested yet, and i’ll do it soon now, but is the alpha value of material definition used throughout the rendering process?

Dolo//\ightY

[This message has been edited by dmy (edited 05-23-2000).]

dmy: basically, glColor and glMaterial are equivalent in this case.
You’ll use glMaterial if you have GL_LIGHTING switched on; otherwise glColor. Obviusly with glMaterial you have much more parameters for controlling illumination of primitives, and you have to take into account how much each of them will contribute to the final color values (find a good balance). I.e. I did some simple tests (for translucency, but they do concern also this case), in which I was drawing a primitive in this way:

  • set DIFFUSE property to (1.0,1.0,1.0,a)
    where ‘a’ is the current alpha value
  • bind the texture
  • modulate the texture on the primitive

To speak informally, I must say that I can’t really tell a priori which material property will mainly affect the final result: it’s depending a lot on light source parameters. I found that, in my setup, DIFFUSE was making a big impact on the final rendered image.
So it’s perfectly possible to use lighting and play with alpha values on material properties.

About motion blur, I saw a pretty cool effect used in DemoGL. It’s a quick-and-dirty effect, but results are better than I expected. It could not work in some cases, but maybe you’ll be able to get an idea.
Instead of clearing the color buffer, at the beginning of a new frame, you render the background with blending enabled, so that the color buffer will hold a percentage of its previous contents. Let’s have a look:

void display()
{
// don’t clear color buffer!
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// ortographic projection
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 0.0, 1.0);

// alpha blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDisable(GL_LIGHTING);

// draw a quad that covers the window
glBegin(GL_QUADS);
glColor4f(0.0, 0.0, 0.0, 0.25);
glVertex2f(0.0, 0.0);
glVertex2f(1.0, 0.0);
glVertex2f(1.0, 1.0);
glVertex2f(0.0, 1.0);
glEnd();

glPopMatrix();
glMatrixMode(GL_MODELVIEW);

glEnable(GL_LIGHTING);

// render the scene
// ...

The drawback is that stationary objects get accumulated on the color buffer, so color values could will saturate to full white.
If you can find some way to improve this please let me know.

paolom:
I never thought about doing it this way but after reading your post i tried it in my app and it surely worked nice!
The only problem is that object in front of another object won’t be affected using this method.

i remember once i was trying to obtain motion blur, i implemented that algo.
it worked, technically, but was not so good to watch: this was due to the fact that colors are often dithered (very often with alpha blending) so somewhere the color effectively goes down to 0, but somwhere else not.

also is difficult to use this scheme with backgrounds other than a solid color.

however, i didn’t tried to hint opengl to don’t use dithering, though… maybe i’ll try.

fogging stage… could be helpful? who knows… but seems interesting to speculate.

there’s a case where per-object motion blur could be implemented nicely: when diffuse color comes from a texture.
the color is set with a single call to glColor4f(1,1,1,alpha) and then the whole object is drawn.

Dolo//\ightY

[This message has been edited by dmy (edited 05-23-2000).]

OK. Thanks 4 all!