views:

620

answers:

3

I'm thinking of chucking motion blur into my 2D program, but I doubt the results of my current algorithm.

My approach looks like this at the moment:

  • Draw to backbuffer.
  • When time to update front buffer, blend the backbuffer onto the front buffer.
  • Repeat

What would cause the "motion blur" effect is obviously the blending, as objects in motion will leave a fading trail.

This is clearly not very demanding on the hardware, the double buffering will be done anyway and the only extra step is the alpha blending, which is a simple calculation. However, the trails will be very sharp, and not blurry at all which may looks a bit strange. I could do a box blur on the back buffer before the blending step, but it feels like it could be very taxing on low-end systems like the Nintendo DS.

Are there any solutions that let me do it more efficiently or yield a better looking result?

+1  A: 

It might not be very sharp at all. It all depends on the blending function used. For instance 0.1/0.9 for previous/current image respectively will provide some faint trail.

I might add that this is essentially how motion blurring in OpenGL is done (through accumulation buffer)

EFraim
Thanks for the input. Good to know that my idea wasn't too amateurish :)
Skurmedel
+1  A: 

There is no real way to do it more efficiently to my knowledge. Thats about as efficient as it gets. It looks pretty good if frame rate is good and movement isn't too sharp as well.

The best looking plan would be to, for each pixel, draw a semi-transparent line from the new position to the old position. This is not a trivial calculation, however.

Goz
I should add that even this better looking plan will look wrong if between frames the object has not move linearly.
Goz
Thanks. That's an interesting thought Goz, hadnät considered that. It could look odd if an object went from one end to the screen to the other in a single frame if the opacity of the backbuffer is low.
Skurmedel
+1  A: 

Really you should render many intermediate frames and blend them into one result. Say, for example, that your output frame rate is 50 fps. You'd probably get a reasonable result if you rendered internally at 500 fps and blended groups of ten frames together before showing that to the user.

The approach you are using at the moment simulates persistence, as if you were rendering onto an old CRT with slow phosphor. This isn't really the same thing as motion blur. If your frame duration is 20ms (1000/50) then a motion blurred frame consists of renderings spanning the 20ms frame duration, all with the same alpha weighting. The persistence solution consists of renderings from 20, 40, 60, 80, 100ms ago, gradually fading out.

Andrew Bainbridge
This is a good suggestion, however it sounds like it could take a lot of processing power.
Skurmedel
Indeed. Depending on the kind of primitives you are rendering, there are probably some optimizations you could apply. Or you could try a hybrid of my suggestion and yours. The algorithm you proposed was a standard demo coding trick back in the 90s. It can produce nice results.However, if you are looking for a general purpose, simple, fast implementation of motion blur, you are out of luck. That's why you hardly ever see it implemented.
Andrew Bainbridge