Уровень 1. Чёрно-белое.
R, G, B = round((x−min)·255 / (max − min))
Уровень 2. Градиент между цветом X и цветом Y.
t = (x−min) / (max − min)
R = round(R1·t + R2·(1−t))
G и B аналогично.
Уровень 3. Учёт гамма-кривой монитора. Тут работаем сразу в двух цветовых пространствах: линейном от 0 до 1, и sRGB от 0 до 255.
gamma = 2,2 — sRGB состоит из линейного и степенного участка, но неплохо приближается real_brightness = channel_%^gamma
invGamma = 1/gamma
функция toLinear(v) := (v/255)^gamma
функция toSrgb(q) := (q^invGamma)·255 — в общем, обратная
linR1 = toLinear(R1)
linR2 = toLinear(R2)
t = (x−min) / (max − min)
R = round(toSrgb(linR1·t + linR2·(1−t)))
Уровень 3.1. 16-битная аппроксимация (если важна скорость). В общем, линейное цветовое пространство — не дробные от 0 до 1, а целые от 0 до 65535.
функция toLinear(i) := round(((i/255)^gamma)·65535)
массив toSrgb(q) := ((q/65535)^invGamma)·255 — записывается в виде массива на 65536 величин
linR1 = toLinear(R1)
linR2 = toLinear(R2)
K = (65535 / (max − min)
t = round((x−min) * K)
R = toSrgb(((linR1·t) + linR2·(65535−t) + 127) >> 16)
Уровень 4. Сложный градиент из нескольких цветов.
Для этого например, t=0 — синий, t=⅓ — зелёный, t=⅔ — жёлтый, t=1 — красный.
Тогда прикидываем, в какой промежуток попадает t, получаем, например, t1=(t−⅓)·3, и дальше по уровню 3.