Motion Blur of a Spinning Sphere in iPhone OpenGL ES

The task is simple: how to go about a motion blur of a fast-spinning OpenGL ES sphere on the iPhone? That is, how to achieve the following effect.

openGL ES Blur

Attempt #1 – drawing on top of previous frames – rejected

Very simple but occasionally powerful effect of blending with the previous frame (looks like what’s going on when you get hit in Call of Duty 4). It works for slow motion, but as soon as the globe starts spinning quickly, you can see the individual frames.

Attempt #2 – accumulation buffer using FBO -  rejected

Also simple to implement. Basically it’s simulating the accumulation buffer (which is not available on the iPhone). I wasn’t able to find a sweet spot between a nice-looking motion blur and maintaining high fps (even if the rendering is performed at a much lower resolution).

Attempt #3 – screen space blurring – rejected

Originally sounded like a good idea – thought no one would be able to tell that it’s only a 2d blur. Not true. Rejected.

Attempt #4 – pre-blurred texture maps – used

Main idea: if the globe is spinning along its “main” axis (south pole to north pole), the motion blur can be simulated by just blurring the texture horizontally. How about generating a couple of pre-blurred texture maps corresponding to different rotations axes.

Globe Blur

Before I get into details I must say that it works really well. I only use 32 different versions (making the amount of rotation axes 64) and it’s really hard to tell that it’s blurred along an axis that’s slightly off (in the actual iPhone application that this was developed for I am actually snapping to the correct axis which is impossible to notice).

The next disadvantage is also obvious: I only have a limited amount of blur values. In the application I work around that by accelerating and decelerating rapidly.

Step 1

How to find the best distribution of 32 points on a sphere (actually 64, but the other 32 are just opposite versions of the first 32)? I wrote a Flash application that does it for me. It runs a simulation of the following algorithm. Thirty two points are randomly positioned in space, each has a positive charge and is restricted to the unit sphere. The purpose of the positive charge is that the points are repulsed from each other, eventually ending up in an even distribution.

Distributed Points

Step 2

Blurring the original texture by a general axis is just a matter of writing down a couple of equations and hoping that you haven’t made a typo.

Step 3

Using the pre-blurred textures is now a piece of cake. Just find the nearest axis and use the corresponding texture.

Attempt #5 – am I missing something obvious here?

Let me know if I am.

Categories: Codify
Tags: , ,

  • makc

    1 you can use single-step distribution formulas such as this one by Robert Bauer:
    for (i = 1; i <= N; i++) {
    var phi:Number = Math.acos ( -1 + (2 * i -1) / N);
    var theta:Number = Math.sqrt (N * Math.PI) * phi;
    2 you can cross-fade textures to accept arbitrary directions