2013-02-26 208 views
19

我需要從RGB色彩空間到HSV傳..我搜索互聯網,發現兩種不同的實現,但那些給我不同的結果:從RGB到HSV在OpenGL GLSL

答:

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

你知道哪個是正確的實現?

回答

65

我是第二個實現的作者。它一直對我來說是正確的,但你寫了2.9/6.9而不是2.0/6.0

因爲你的目標GLSL,你應該使用在腦海書面與GPU轉換例程:

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

http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl服用。

+0

我在shadertoy網站上試過這個,它表示找不到匹配的重載函數,無法從中轉換到Vector3 – 2013-11-03 01:52:52

+0

好!你碰巧已經有了和HSL色彩空間相同的功能嗎? – wil 2014-02-20 07:10:42

+1

[我剛剛實現'hsv2rgb()'與硬件混合](http://stackoverflow.com/a/28897272/1888983)。完全愚蠢的,但我仍然溫和地爲自己感到驕傲。 – jozxyqk 2015-03-06 11:26:25

2

我沒有開發環境來檢查,但你可以使用wolframAlpha來建立一些斷言。

For Instance: rgb(1,0,0)(純紅色)至hsv在hsv中爲0,100%,100%。