Click here to Skip to main content
15,867,141 members
Articles / Multimedia / OpenGL
Article

Full Scene Motion Blur

Rate me:
Please Sign up or sign in to vote.
4.84/5 (27 votes)
28 Mar 2005CPOL4 min read 133.1K   3.6K   54   11
How to obtain a motion blur effect.

Sample Image - Motion Blur Effect.jpg

Introduction

Motion Blur is a quite excellent effect, but very hard to make. In order to obtain such an effect, the OpengGL developers recommend the use of the accumulation buffer. Basically, the accumulation buffer redraws the object n times using different alpha values. I have nothing against this method but when the scene is full of "hard-to-render" objects, it leads to a low FPS rate. In full scene motion blur, in order to obtain the effect, the scene must be drawn more times. The big problem comes from the accumulation buffer, it is not always supported on all the graphical cards. So how can this problem be passed?

Background

A very good method that I will explain in the following lines is to render our scene into a texture. Why should this be useful? Easy, by rendering the object into a texture, we can easily access the precedent frame, and by accessing it, we can render it with a lower alpha value. Doing this in a recurrent mode, we can obtain the desired effect.

The only thing needed is a texture used for storing the precedent scene. The algorithm is simple now:

  1. draw the old scene (stored into the texture, which is a simple textured polygon) with a lower alpha (<1).
  2. draw the current scene.
  3. read into the texture the whole screen.

With this implementation, the effect is visible only outside the object, the object looks the same in the rest. But we all know that with motion blur, the objects appear blurry not just a simple trace surrounding the object. So how can we do this? Simple: first draw the scene then render the old scene. Doing this, the object appears blurry.

This method is not the best and not the worse, is just a method and I hope it will help many others because it helped me.

Using the code

The small demo shows how the effect works on a single object and on a whole scene. The single object is a textured cube and the whole scene is a vortex effect.

For each basic utility, there exists a distinct module. The core (main) module contains all the definitions that may be necessary in other modules. On the next level there are three modules: glBasic (handles initializations and other GL things), glDraw (handles all the GL drawing) and keyboard (handles a keyboard management routine). glDraw has relations with motionblur (stores the procedure needed for rendering the motion blur - this is why all the application is built) and tunnel (holds the vertex creation and handling). glBasic has calls into texture module (texture handling). (Note - a module is physically represented by a C file, the code does not use OOP.)

The texture used for the motion blur is defined in the core (main) module and is exported in all the other modules. But the processing is made in the motionblur module. There are three procedures:

  1. int CreateMotionBlurTexture(int quality, int interpolation); - creates the motion blur texture and is recommended to be called into the init procedure.
  2. void RenderToMotionBlurTexture(bool FirstRenderTexture, int SceneFunc()); - "renders" the SceneFunc() onto the motion blur texture together with the previous frame. The boolean flag specifies if the previous frame is rendered first or not (see the background point).
  3. void ShowMotionBlurTexture(); - is like a flush procedure, it displays onto the screen the final result.

In order to make the effect more real, the blending is made with the following parameters: GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. Because the application uses alpha blending, the intensity of the effect can easily be changed by changing the previous frame alpha value.

In the demo application, the following keys are usable:

  • 's' - for changing the rendered scene.
  • 't' - for changing the FirstRenderTexture flag that is passed to the RenderToMotionBlurTexture procedure.
  • 'w' - for wireframe rendering.
  • 'm' - for the use of motion blur or not.
  • press 'a' and then '+' or '-' to adjust the alpha intensity.

Note that the demo runs with GLUT.

Points of Interest

This method is very useful especially when doing full scene motion blur. If this method is used just for a single object then it is recommended to use masking.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Romania Romania
-

Comments and Discussions

 
Questionconsult Pin
yecongli8-Dec-11 20:44
yecongli8-Dec-11 20:44 
GeneralWell done! Pin
rvangaal26-Mar-07 7:05
rvangaal26-Mar-07 7:05 
Generalthanks Pin
orichisonic5-Aug-06 15:33
orichisonic5-Aug-06 15:33 
GeneralCool! Pin
Yuval Naveh15-Jul-05 23:23
Yuval Naveh15-Jul-05 23:23 
GeneralVery good Pin
FireStorm31-Mar-05 0:54
FireStorm31-Mar-05 0:54 
Generalcombine frames if exceeding refresh rate Pin
Anonymous30-Mar-05 0:22
Anonymous30-Mar-05 0:22 
say you can render at 240fps and your refresh rate is 60Hz, you can draw 4 frames, combine them and have motion blur with no lower visable fps and it will not be performance dependant. i have been screaming for years this should be build into the drivers (just like the anti aliassing)


GeneralRe: combine frames if exceeding refresh rate Pin
Stanciu Vlad30-Mar-05 7:42
Stanciu Vlad30-Mar-05 7:42 
Generalframerate dependencies Pin
Member 128251828-Mar-05 10:20
Member 128251828-Mar-05 10:20 
GeneralRe: framerate dependencies Pin
Stanciu Vlad28-Mar-05 20:17
Stanciu Vlad28-Mar-05 20:17 
GeneralRe: framerate dependencies Pin
Member 128251828-Mar-05 22:05
Member 128251828-Mar-05 22:05 
GeneralRe: framerate dependencies Pin
mzeo772-Apr-05 5:04
mzeo772-Apr-05 5:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.