Monday, July 26th, 2010

Canvas Color Cycling

Category: Canvas, Games, Graphics, Performance

<p>

Interest in Canvas, as well as mobile apps, has led to a renaissance of old-school 8-bit graphics. Joe Huckaby of Effect Games has been playing around with color cycling, leading to some stunning effects.

Anyone remember Color cycling from the 90s? This was a technology often used in 8-bit video games of the era, to achieve interesting visual effects by cycling (shifting) the color palette. Back then video cards could only render 256 colors at a time, so a palette of selected colors was used. But the programmer could change this palette at will, and all the onscreen colors would instantly change to match. It was fast, and took virtually no memory.

There’s a neat optimization going on here too: instead of clearing and redrawing the entire scene with each frame, he only updates the pixels that change:

In order to achieve fast frame rates in the browser, I had to get a little crazy in the engine implementation. Rendering a 640×480 indexed image on a 32-bit RGB canvas means walking through and drawing 307,200 pixels per frame, in JavaScript. That’s a very big array to traverse, and some browsers just couldn’t keep up. To overcome this, I pre-process the images when they are first loaded, and grab the pixels that reference colors which are animated (i.e. are part of cycling sets in the palette). Those pixel X/Y offsets are stored in a separate, smaller array, and thus only the pixels that change are refreshed onscreen. This optimization trick works so well, that the thing actually runs at a pretty decent speed on my iPhone 3GS and iPad!

Related Content:

Posted by Michael Mahemoff at 7:21 pm
13 Comments

++---
2.6 rating from 7 votes

13 Comments »

Comments feed TrackBack URI

I’m impressed that this works as well as it does, and definitely nostalgic for the art style. But palette cycling was an optimization trick, not an end to itself. Am I the only one who finds it rather odd that we’re reproducing a technique like this in a way that is probably orders of magnitude less efficient than in its original form?!

Comment by jgw — July 26, 2010

Interesting… brought back some memories. Color Cycling, aka color map manipulation, along with bit-plane operations, was pretty standard even in the 80′s. It wasn’t just a cute optimization then, it was the ONLY way to render some complex graphics in near-time – because you could change the display with NO PIXEL writes, just a color map flip or bit-plane write to the framebuffer. Ahhh, Good Times.

Comment by DeanSJones — July 26, 2010

Actually, we can make it as efficient as it was back then :) Browsers support any number of image formats with palettes, we just have to alter them and let the browser do the rest.
Here’s a simple example that works in Firefox, Safari and Chrome (not Opera yet… it’s either atob or the fact that I’m using BMPs).
It loads a little slow since I’m directly loading the BMP with a binary XMLHttpRequest and that means going through each byte and checking the range, but that could quickly be replaced.
Once it loads, it just changes the bytes in the BMP header that represent the palette and lets the browser (which is A LOT faster at doing this kind of stuff) worry about how to display a paletted image.
I don’t have a nice image like Joe, so you better not have epilepsy if you intend to watch this :)

http://www.tapper-ware.net/data/devel/web/apps/JS.ColorCycle/

Comment by hansschmucker — July 27, 2010

Changed it a bit (the image is now delivered base64 encoded) and now it works in Opera as well (which means that it now works on all modern browsers)…. I’ve also added a big 512×1024 image to show the speed. Doesn’t look any better, though. Joe, where did you get that image?

Comment by hansschmucker — July 27, 2010

The artist, Mark Ferrari, is brilliant.

Comment by crock — July 27, 2010

@igw – Are you saying if someone’s first attempt at recreating an optimization method for a new platform is not more efficient than the original implementation then that person shouldn’t bother? Should we just immediately dismiss all research efforts then?

Comment by travisalmand — July 27, 2010

The iphone’s application cache can only hold 5mb per “app”. Even if this technique is not computationally efficient, it is still efficient in terms of space. Look at how the same image data can be reused to show different times of day, and different weather conditions, simply by changing the palette. Look also at the fact that such animations can be achieved without storing multiple frames. We’re talking 5mb, including graphics, sounds, text, and javascript. Yeah, of course let’s revisit old techniques!

Comment by Breton — July 27, 2010

and also, thanks for pointing out these images by Mark Ferrari. It will take me some time to figure out what’s going on in these images! how does it work!?

Comment by Breton — July 27, 2010

@hansschmucker – I am impressed at how well your technique works, especially considering it isn’t affected by the number of pixels that have to be updated. I honestly considered that when I first started working on this demo (I was thinking GIF images, but same basic idea, manipulate the binary palette in memory and have the browser reload it), but totally dismissed it thinking it would be far too slow for the browser to “reinterpret” a binary image for every frame. I was very wrong. Nice work!

Comment by jhuckaby — July 27, 2010

I recently made (erm, ported) a pure JS canvas -> animated GIF converter (http://github.com/antimatter15/jsgif) so I just did a few changes to canvascycle and tried making it into an animated gif: http://github.com/antimatter15/jsgif/blob/master/Demos/canvascycle/gif.gif

The palettes doesn’t seem right, but it’s still interesting.

Comment by antimatter15 — July 27, 2010

This is absolutely brilliant. A nice recreation of the technique augmented by the quality of those astounding illustrations.
I used a similar technique in Flash a couple years ago (modifying the PLTE chunk in a PNG) but never reached production as the set of images I was handling was immense and unpredictable (something along the lines of hundreds of animations at 15-30 frames each that were 3D renders), which meant generating each palette was not a simple task.

Comment by gonchuki — July 27, 2010

@travisalmand – The optimisation has not been “recreated”. Palette cycling allowed graphics on the screen to be updated without being redrawn. This was from back in the day when blitting graphics onto the screen was computationally expensive & memory for storing animations was a preciously hoarded commodity (and computers stored a lookup table for colours, rather than supporting “high colour” modes).
This has no relation to that any more.
Now we are emulating the rotation in software, on a javascript virtual machine, no-less – It’s humorously highlevel & abstract (which was what @jgw was referring to)
It is, however, wonderfully nostalgic & excellently executed.
And damn! Mark Ferrari’s art is niiiice!
@hansschmucker gets a step further by making the browser perform the rotation, instead (neat idea!). It’s still not /quite/ the same mind-you, but it’s closer :]

Comment by ProPuke — July 27, 2010

Cool, but not very practical. Zoom in on the graphics and they run like molasis in winter. Crashed Safari on my iPad after about 20 seconds. :-(

Comment by RobG — July 29, 2010

Leave a comment

You must be logged in to post a comment.