I just couldn't help myself, I loved my Image Melder so much that I decided to completely remake it using C++ and OpenFrameworks. It took some time, but I think it was absolutely worth it. Someday I'd like to integrate it into some sort of art display, e-picture frame, or LED billboard advertisement. I think it would be quite eye-catching!
Here's a comparison between some of the features of the old and new versions:
Version 1
Written in Processing, which uses Java
Analysis was done using my custom "RGB Cube". I later learned that I had accidentally invented spatial hashing. It typically took around 5 seconds.
Animation was done by pre-rendering the animation frames, then flip-booking through them. It typically took around 10 seconds to generate the frames.
A dozen animations that are all hard-coded.
Version 2
Written in OpenFrameworks, which uses C++
Analysis is done using an octree, which uses less memory, has perfectly-accurate color-matching, and is over10x faster. It typically takes less than half a second.
Animation is done using a compute shader. It's instantaneous and uses a fraction of the memory.
Over 20 different animations with endless random variations. Animations are loaded at runtime from a custom file format that gets transpiled into a mixture of GLSL and CPU code. Certain parameters can be randomized when the animation starts, or updated while the animation is playing. Animations can be hot-reloaded while the application is running and the transpiler includes many helpful error messages to make writing the shaders easier.
Includes a dithering function to help the assembled image match the target image even more closely.

A video showcasing some of the new animations and performance improvements

One of the pixel animation files

#uniforms tells the CPU which shader variables need to be set, and how they should be updated. When the animation starts, a random value inside the [square brackets] will be picked.
#variant has some preset combinations of variables that work well together. A random variant will be picked when the animation starts.
#main gets injected into a master shader file as the function that gets run for every pixel, which then gets compiled and saved. The built-in variable 'newPos' must be assigned by the end of the function.

You may also like

Back to Top