Gamma function comparison (corrected)
Much has been written about gamma correction; here I took a look at various correction functions for speed and accuracy. For newer folk: gamma correction is a way to make the numeric values for a given color render so that they look right on different devices (e.g. an LCD screen vs an LED strip). Recently I was doing some experiments, the results of which I will (eventually! really!) share converting colors from on-screen colors to LED strip colors, and it turns out that you need to apply a gamma correction to get the colors to match even remotely. But what gamma function to use?
The mathematically correct formula is to convert brightness to a fractional value, raise it to an exponent, and then convert it back. This involves floating point math, which on Arduino can be slow and bulky … and slow.
I’ve been using FastLED’s dim8_video(…) function as a proxy for floating point gamma correction, but now I wanted to see how close it was to the traditional exponential floating point gamma corrections. Typical popular exponent values (“pow(…)”) for gamma correction are 2.2 and 2.5. Here’s how applying dim8_video compares to pow(2.2) and pow(2.5).
As you can see, dim8_video( input ) is relatively close to pow( input, 2.2) – and it’s much much faster to execute (also smaller code). It works out that dim8_video is basically the same as an exponential gamma of 2.0, not 2.2, but often this is a good, fast, approximation.
Accordingly, applying dim8_video( dim8_video( input )) is very similar to pow( input, 4.0).
I had often wondered ‘how good’ an approximation dim8_video is to an exponential floating point gamma correction of 2.2, and now we know: it’s a reasonably good approximation (gamma=2.0) given the big speed advantage. Applying dim8_video twice gives a gamma of 4.0.
One even faster technique and more accurate technique you can use is to define a 256-byte lookup table in PROGMEM (flash) that has precomputed gamma values in it. If you do that, you can precalculate any gamma correction you like, e.g. 2.45, and it’ll all run just as fast – at the cost of 256 bytes of program space. We don’t provide a gamma table like that in FastLED, but the ever-awesome Adafruit folks have one you can cut-and-paste, here https://learn.adafruit.com/led-tricks-gamma-correction/the-issue
