【问题标题】:From RGB to HSV in OpenGL GLSL在 OpenGL GLSL 中从 RGB 到 HSV
【发布时间】:2013-02-26 17:53:21
【问题描述】:

我需要从 RGB 颜色空间传递到 HSV .. 我在互联网上搜索并找到了两种不同的实现,但它们给了我不同的结果:

答:

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

乙:

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

你知道哪个是正确的实现吗?

【问题讨论】:

    标签: opengl glsl rgb hsv


    【解决方案1】:

    我是第二个实现的作者。它对我来说一直表现正确,但您写的是 2.9 / 6.9 而不是 2.0 / 6.0

    由于您以 GLSL 为目标,因此您应该使用为 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);
    }
    

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

    编辑:代码在WTFPL 下获得许可。

    【讨论】:

    • 我在shadertoy网站上试过这个,它说没有找到匹配的重载函数,无法从mediump转换为Vector3
    • 不错!您是否碰巧已经为 HSL 颜色空间提供了相同类型的功能?
    • I just implemented hsv2rgb() with hardware blending。完全愚蠢,但我仍然为自己感到自豪。
    • 任何使用此代码的人都应该知道色调角度表示为 0.0-1.0 之间的值(而不是弧度或度数)...希望这可以为某人节省 90 分钟的挫败感... :-)
    • @WaveformDelta 很抱歉没有让这一点更明显;我在这些函数中添加了 cmets,以便其他人不会浪费时间……
    【解决方案2】:

    我没有要检查的开发环境,但您可以使用 wolframAlpha 构建一些断言。

    For Instance:rgb(1,0,0)(纯红色)到hsv是0, 100%, 100% in hsv。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      相关资源
      最近更新 更多