One piece of GLSL code I am constantly coming back to is Sam Hocevar's hsv2rbg
and rgb2hsv
functions posted on stackoverflow: https://stackoverflow.com/a/17897228/418488
// Sam Hovevar has licensed the code under WTFPL.
// All components are in the range [0…1], including hue.
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
// All components are in the range [0…1], including hue.
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
One thing I find myself wishing for is to initialize global const values from hsv2rbg but it doesn't work above because the const global values must be initialize from constexpr
expressions
You can't declare a function constexpr
in GLSL (yet) so I wrote this simple macro which is just hsv2rgb made into a macro
// License WTFPL
const vec4 hsv2rgb_K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
#define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y))
const vec3 grid_color = HSV2RGB(vec3(0.6, 0.6, 1.0));
const vec3 plate_color = HSV2RGB(vec3(0.0, 0.0, 0.125));
const vec3 plane_color = HSV2RGB(vec3(0.7, 0.125, 1.0/32.0));
That's it.
Mårten