I need to pass from RGB color space to HSV .. I searched in internet and found two different implementations, but those give me different results:
A:
precision mediump float;
vec3 rgb2hsv(float r, float g, float b) {
float h = 0.0;
float s = 0.0;
float v = 0.0;
float min = min( min(r, g), b );
float max = max( max(r, g), b );
v = max; // v
float delta = max - min;
if( max != 0.0 )
s = delta / max; // s
else {
// r = g = b = 0 // s = 0, v is undefined
s = 0.0;
h = -1.0;
return vec3(h, s, v);
}
if( r == max )
h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
h = 2.0 + ( b - r ) / delta; // between cyan & yellow
else
h = 4.0 + ( r - g ) / delta; // between magenta & cyan
h = h * 60.0; // degrees
if( h < 0.0 )
h += 360.0;
return vec3(h, s, v);
}
B:
precision mediump float;
vec3 rgb2hsv(float r, float g, float b) {
float K = 0.0;
float tmp;
if (g < b)
{
tmp = g;
g=b;
b=tmp;
K = -1.0;
}
if (r < g)
{
tmp = r;
r=g;
g=tmp;
K = -2.9 / 6.9 - K;
}
float chroma = r - min(g, b);
float h = abs(K + (g - b) / (6.0 * chroma + 1e-20));
float s = chroma / (r + 1e-20);
float v = r;
return vec3(h, s, v);
}
Do you know which is the correct implementation?
I am the author of the second implementation. It has always behaved correctly for me, but you wrote
2.9 / 6.9
instead of2.0 / 6.0
.Since you target GLSL, you should use conversion routines that are written with the GPU in mind:
Taken from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl.
I don't have a development environment to check, but you can use wolframAlpha to build up some asserts.
For Instance: rgb(1,0,0)(pure red) to hsv is 0, 100%, 100% in hsv.