Friday 12 April 2013

Motion Blur

This week's blog is going to go over a simple shader that gives the effect of motion blur! So allow me to give a brief explanation of what motion blur is. Motion blur is the streaking of rapidly moving objects in a still image or a sequence of images such as a movie or animation. This happens when the image being recorded changes during the recording of a single frame, either due to rapid movement or long exposure. As you can see in the photo above, this is not the case. The reason why you can tell is because according to the definition of motion blur, everything moving in the image would be blurred. There is lots of places in the image that are very in focus, this means that the photo was taken and it was perfectly clear. Then someone took it into photoshop and applied blur to it in specific spots.

Now remember what we know about photoshop and shaders, that everything you can do in photoshop can be programmed into a shader! First you might be asking yourself, why would we even want this? Most time people are trying to get rid of motion blur in their photos and videos. Everyone's looking for crystal clear imaging nowadays so why add motion blur? We would add this motion blur to games because we are looking to add a sense of realism to the game. This kind of blur occurs naturally and therefore, makes a games graphics look more natural.  
Here is another image that demonstrates good motion blur. This could have actually been the raw image since all the static objects in the scene are in focus while the moving objects have motion blur on them. 
I found this image while searching for good motion blur photos for this blog. Thought it was funny so I shall share it. 

Now below is the difference between having motion blur in games and not.  As you can see, when motion blur is off it looks good because the graphics in general are alright. The difference motion blur makes on the left image be more natual and visually appealing. 

This effect can easily be applied in photoshop with a large arsenal of tools at the developers disposal.There are all sorts of blurs and they even have a nice motion blur tool such as the one below.

Here the developer has access to the angle of motion blur and how far the blur will streak. When programming this tool, we can give the same controls to the developer. To start, the angle of blur will be dynamic. So no matter which way the objects are moving they will cause blur in the direction they are moving. Now, if this wasn't the desired effect or you wanted to constrain the areas where objects have motion blur, then these conditions will be covered with conditional statements on the CPU side of things. As for the amount of blur or the distance in which the image will be blurred, that is controlled by how many frames we add together for the blurring effect. 

When it comes to the actual programming of this, there are many different ways it can be done. The first way I'm going to cover is all done entirely on the CPU using an OpenGl function called glAccum. Now what we are going to do with this is we are going to store a certain number of frames into an accumulation buffer. The amount is up to how much blur we want to have. Then we will check to see if we have accumulated enough frames and once we have then will blend them together and reset the frame counter and draw. This is a slow but extremely simple way of doing it. http://www.cse.msu.edu/~cse872/tutorial5.html A link is provided if you are interested in seeing line by line how it works. 

The other way to do this is on the GPU side in shaderland. This way is a little more annoying but it is still fairly simple. So what we are going to do here is manually do what we did on the CPU but instead have it occur on the GPU processed in a fragment shader. We are going to need those frames though. Let's use our favourite tool, FBO's, and let's use a bunch. We will take about five of them, yeah that should be good. We will slap four frames from the screen onto four of the five framebuffers. Now lets send these textures through the pipeline and put that fragment shader to work. We're going to have the shader mix all of the frames together and return one final fully blended version. This will give the bluring effect we need when an object moves. We would still apply the same logic as we had on the CPU. There are even more efficient ways of creating motion blur than that but those are two different ways it can be done. 

No comments:

Post a Comment