2013-02-26 6 views
19

Ich brauche von RGB-Farbraum zu HSV passieren .. ich in Internet gesucht und zwei verschiedene Implementierungen gefunden, aber die geben mir andere Ergebnisse:von RGB nach HSV in OpenGL GLSL

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

Sie wissen Sie, welche die korrekte Umsetzung ist?

Antwort

65

Ich bin der Autor der zweiten Implementierung. Es hat sich immer korrekt für mich verhalten, aber Sie haben 2.9/6.9 anstelle von 2.0/6.0 geschrieben.

Da Sie GLSL Ziel, sollten Sie Konvertierungsroutinen verwenden, die mit der GPU im Kopf geschrieben werden:

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

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

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

+0

Ich versuchte dies auf Shadowerto Website und es sagte keine übereinstimmende überladene Funktion gefunden, kann nicht von Mediump zu Vector3 konvertieren –

+0

Nizza! Haben Sie bereits die gleichen Funktionen für den HSL-Farbraum? – wil

+1

[Ich habe gerade 'hsv2rgb()' mit Hardware Blending implementiert] (http://stackoverflow.com/a/28897272/1888983). Völlig dumm, aber ich bin immer noch ein bisschen stolz auf mich. – jozxyqk

2

Ich habe keine Entwicklungsumgebung zu überprüfen, aber Sie können WolframAlpha verwenden, um einige Behauptungen aufzubauen.

For Instance: rgb (1,0,0) (rein rot) nach hsv ist 0, 100%, 100% in hsv.