opengl glsl rgb hsv

De RGB a HSV en OpenGL GLSL



(2)

Necesito pasar del espacio de color RGB al HSV. Busqué en Internet y encontré dos implementaciones diferentes, pero esas me dan resultados diferentes

UNA:

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); }

SEGUNDO:

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); }

¿Sabes cual es la implementación correcta?


No tengo un entorno de desarrollo para verificar, pero puedes usar wolframAlpha para crear algunas afirmaciones.

Para Instancia: rgb (1,0,0) (rojo puro) a hsv es 0, 100%, 100% en hsv.


Soy el autor de la segunda implementación. Siempre se ha comportado correctamente para mí, pero escribiste 2.9 / 6.9 lugar de 2.0 / 6.0 .

Como apunta a GLSL, debe usar las rutinas de conversión que están escritas teniendo en cuenta la GPU:

// 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); }

Tomado de http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl .