· · learn more

◌  The Kimbrel rainbow function

19 January 2011

When I was doing Julia sets in CUDA I had trouble finding a rainbow color map that looked right. The normal HSV→RGB function gives you outputs of inconsistent luminance: for example, blue has the B channel maxed out but the others at nil, while cyan has the B and G channels maxed out but R at nil, so it’s twice as bright. (Actually no. This depends on all sorts of things to do with monitor response and color perception, but it’s a fair approximation.)

Sam and I realized that you can create a function that has a constant luminance over H by making the R, G, B responses offset sine waves, instead of the gapped trapezoids of the canonical HSV→RGB. I find this makes noticeably more pleasing, natural-looking rainbow color maps. Here it is in moderately optimized CUDA C:

__device__ uchar3 colorize(uchar v) {
  float val = (float)v/255.0f * pi;
  float r = __sinf(val);
  float g = __sinf(fmaf(pi, 2.0/3.0, val));
  float b = __sinf(fmaf(pi, 4.0/3.0, val));
  return make_uchar3(r*r*255, g*g*255, b*b*255);