Другие решения требуют довольно большого количества кода и условного ветвления, что делает их непригодными для графических процессоров. Недавно я пришел к следующей магически простой формуле в GLSL. По сути, в OpenCL то же самое:
vec3 HueToRGB(float hue) {
vec3 h = vec3(hue, hue + 1.0/3.0, hue + 2.0/3.0);
return clamp(6.0 * abs(h - floor(h) - 0.5) - 1.0, 0.0, 1.0);
}
Это даст вам цвет радуги, который соответствует заданному значению оттенка в линейном RGB. Чтобы использовать изображение, конвертируйте его в sRGB, а затем умножьте на 255.
Вот версия C ++:
float clamp(float value, float low, float high) {
return value < low ? low : (value > high ? high : value);
}
void HueToRGB(float hue, float *rgb) {
rgb[0] = hue;
rgb[1] = hue + 1.f/3.f;
rgb[2] = hue + 2.f/3.f;
for (unsigned i = 0; i < 3; ++i) {
rgb[i] = clamp(6.0f * fabsf(rgb[i] - floorf(rgb[i]) - 0.5f) - 1.f, 0.f, 1.f);
}
}
Ключевым моментом здесь является осознание того, что график каждой из координат R, G, B в зависимости от значения оттенка является фиксированным значением периодической функции треугольника, и его можно получить как абсолютное значение пилообразной величины. функция, x - floor(x)
.