Netpbm Animation Showcase

Ever since I worked out how to render video from scratch some years ago, it’s been an indispensable tool in my software development toolbelt. It’s the first place I reach when I need to display some graphics, even if it means having to do the rendering myself. I’ve used it often in throwaway projects in a disposable sort of way. More recently, though, I’ve kept better track of these animations since some of them are pretty cool, and I’d like to look a them again. This post is a showcase of some of these projects.

Each project is in a ready-to-run state of compile, then run with the output piped into a media player or video encoding. The header includes the exactly commands you need. Since that’s probably inconvenient for most readers, I’ve included a pre-recorded sample of each. Though in a few cases, especially those displaying random data, video encoding really takes something away from the final result, and it may be worth running yourself.

The projects are not in any particular order.


Source: randu.c

This is a little demonstration of the poor quality of the RANDU pseudorandom number generator. Note how the source embeds a monospace font so that it can render the text in the corner. For the 3D effect, it includes an orthographic projection function. This function will appear again later since I tend to cannibalize my own projects.

Color sorting

Source: colorsort.c

The original idea came from an old reddit post.

Kruskal maze generator

Source: animaze.c

This effect was invented by my current mentee student while working on maze / dungeon generation late last year. This particular animation is my own implementation. It outputs Netpbm by default, but, for both fun and practice, also includes an entire implementation in OpenGL. It’s enabled at compile time with -DENABLE_GL so long as you have GLFW and GLEW (even on Windows!).

Sliding rooks puzzle

Source: rooks.c

I wanted to watch an animated solution to the sliding rooks puzzle. This program solves the puzzle using a bitboard, then animates the solution. The rook images are embedded in the program, compressed using a custom run-length encoding (RLE) scheme with a tiny palette.

Glauber’s dynamics

Source: magnet.c

My own animation of Glauber’s dynamics using a totally unoriginal color palette.


Source: fire.c

This is the classic Doom fire animation. I later implemented it in WebGL with a modified algorithm.

Mersenne Twister

Source: mtvisualize.c

A visualization of the Mersenne Twister pseudorandom number generator. Not terribly interesting, so I almost didn’t include it.

Pixel sorting

Source: pixelsort.c

Another animation inspired by a reddit post. Starting from the top-left corner, swap the current pixel to the one most like its neighbors.

Random walk (2D)

Source: walkers.c

Another reproduction of a reddit post. This is recent enough that I’m using a disposable LCG.

Manhattan distance Voronoi diagram

Source: voronoi.c

Another reddit post, though I think my version looks a lot nicer. I like to play this one over and over on repeat with different seeds.

Random walk (3D)

Source: walk3d.c

Another stolen idea personal take on a reddit post. This features the orthographic projection function from the RANDU animation. Video encoding makes a real mess of this one, and I couldn’t work out encoding options to make it look nice, so this one looks a lot better “in person.”

Lorenz system

Source: lorenz.c

A 3D animation I adapted from the 3D random walk above, meaning it uses the same orthographic projection. I have a WebGL version of this one, but I like that I could do this in such a small amount of code and without an existing rendering engine. Like before, this is really damaged by video encoding and is best seen live.

Bonus: I made an obfuscated version just to show how small this can get!

Have a comment on this article? Start a discussion in my public inbox by sending an email to ~skeeto/ [mailing list etiquette] , or see existing discussions.

null program

Chris Wellons (PGP)
~skeeto/ (view)