18
\$\begingroup\$

I have a full 2D environment, with sprites going around as landscape, characters, etc.

To make it more state-of-art looking, I want to implement a motion blur effect, similar to modern FPS games (i.e. Crysis) blur when moving the camera quickly.

In a sidescroller, the desired effect is having this slight blur appearing to give the idea of fast movement when the camera is moving. If anyone could give me some tips on doing this, I'm assuming in a pixel shader, I'd be grateful.

\$\endgroup\$
4
  • \$\begingroup\$ Keep multiple copies of your rendered buffer. For example, blur four of the previous frames to create your current frame. That should create the effect you want. \$\endgroup\$
    – knight666
    Feb 19, 2011 at 10:23
  • \$\begingroup\$ @knight666 wouldn't it be better (memory certainly, speed I'm not sure) to keep 1 extra buffer (call it A) and than mix a fraction (say 0.75) of that with the output buffer (going to the screen, call it B) and then copy B to A afterwards. This would create a rolling average and increasing motion blur wouldn't cost anything extra. \$\endgroup\$
    – Elva
    Feb 19, 2011 at 15:44
  • 1
    \$\begingroup\$ I meant to make this a comment, but couldn't find the comment button. Anyways, what Dave O. says is probably you're best bet and what's used in games like Crysis. This works a bit like this. During object render, Render object velocities into a separate buffer. MRT will make this a bit quicker, and there are multiple ways to compute the velocities, but you want to end up with an additional buffer that has the velocities for the entire render buffer. Then in a post-process shader, based on the velocity at every pixel, you sample into the color buffer in the opposite direction of the veloc \$\endgroup\$
    – Arelius
    Feb 23, 2011 at 20:03
  • \$\begingroup\$ The HLSL/Cg code in Listing 27-1 uses the previous equations in a full-screen post-processing pixel shader to compute the world-space position of the objects rendered at a given pixel, using the depth buffer and the inverse of the current view-projection matrix. ... HLSL.... In your code it's not GLSL ..... \$\endgroup\$
    – user18122
    Jul 18, 2012 at 8:48

2 Answers 2

7
\$\begingroup\$

Keep a copy of the last framebuffer. Get the camera movement vector and invert it. Draw your scene as usual, then draw the last framebuffer with a slight offset (the camera delta you just calculated) and 0.75 alpha. Repeat as many times as you like to give the motion blur effect.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This approach is very easy to implement but very hard to fine tune (it can look like objects leaving traces instead of being blurred). Another also simple approach is to "smear" pixels in the inverted camera movement direction in a post processing pixel shader. \$\endgroup\$
    – Dave O.
    Feb 20, 2011 at 2:31
  • 7
    \$\begingroup\$ The main problem with this approach is that it's framerate dependent - it'll look very different if you're running at 20 fps to how it looks if you're running at 100 fps. So long as you're aware of that and get the result you want at the framerate you run at it's fine, but you do need to be aware of it. \$\endgroup\$ Jul 18, 2012 at 11:50
21
\$\begingroup\$

I would recommend using this method : Motion Blur as a Post-Processing Effect

Very simple to implement, it's the one I used in my glsl demo Ruin island [link]

\$\endgroup\$
3
  • \$\begingroup\$ This method is far superior to blending in past frames... \$\endgroup\$
    – Steven Lu
    Feb 15, 2012 at 15:33
  • 1
    \$\begingroup\$ As it is now, this answer just provides a link. If the link breaks in the future, nobody is going to know how to actually solve their problem. Try at least to include the essential information the link gives you \$\endgroup\$
    – user100681
    Dec 12, 2017 at 13:54
  • 1
    \$\begingroup\$ Yeah, let's make a copy of the Internet, because that copy totally won't break any day :J \$\endgroup\$
    – SasQ
    Apr 17, 2019 at 8:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .