Filming shaders

April 5, 2013

Some of the most interesting shaders are self contained 4 dimensional worlds defined entirely by maths. With a powerful GPU rendering them in real time at 60 frames per second, they can look utterly stunning.

But what to do in case you don't have the most powerful GPU to enjoy these?

Well, if you are willing to give up on interaction, another option is to render the shader frames to a file and create a video from them.

Real time shaders often need to cut some corners to achieve good frame rates, but when rendering to file you can use as much processing time as you have patience for to raise the quality of individual frames.

One obvious thing to do is to render very large frames and scale them down with a filter to the desired final resolution. This can smooth away any jagged edges in the scene while still preserving sharp details.

The same trick can be played in the time dimension - render multiple frames with a slightly different timestamp, and combine them together. The result is a beautiful motion blur which makes the resulting video appear smoother.

Hollywood has used this trick for years. The standard frame rate for films is a paltry 24 frames per second. But film cameras traditionally exposed the film for half of that time using a "180-degree shutter" (see this great animation to understand how it worked). The result was blurring of moving objects, and the film appearing smoother despite the low frame rate.

Combining these ideas, for each pixel of our film, let's render 16 times at slightly different positions and slightly different times, spread over half a frame to simulate 180-degree shutter.

Here is the result. First, rendered once per pixel:


Now 16x oversampled and motion blurred:


Choosing a good shader and putting it all together into a film rendered at a YouTube-friendly 30FPS, gives you something like this: Shader Worlds: Elevated

That was Inigo Quilez' amazing Elevated shader, derived from his famous 2009 4k demo of the same name.

I rendered it with normal OpenGL rather than WebGL, using a small python program which may in time develop into something more fully featured: