在HSV / HSB中淡出更多更自然的彩虹光谱

我正试图控制一些RGB LED并从红色变为紫色。我正在使用HSV到RGB的转换,这样我就可以从色调0扫到色调300(除此之外它会向红色移动)。我注意到的问题是它似乎在光谱的青色和蓝色部分花了很长时间。所以我查看了HSV频谱应该是什么样的,并找到了这个 我没有意识到超过一半的光谱花费在绿色和蓝色之间。 但我真的希望它看起来更像这样: 与“标准”彩虹色完美融合。 我想这会最终成为正常色调值的某种s曲线,但我不确定如何计算该曲线。 在内部处理这种情况的实际HSV到RGB算法会很棒(任何代码都是真的,虽然它适用于Arduino)但是即使只是解释我如何计算该色调曲线也会非常感激。     
已邀请:
http://www.fourmilab.ch/documents/specrend/对如何将波长转换为CIE组件(大致对应于您眼中三种锥形传感器的输出)进行了相当详细的描述,然后如何将它们转换为RGB值(警告某些波长在典型的RGB色域中没有RGB等效物)。 或者:存在各种“感知上均匀的颜色空间”,如CIE L * a * b *(参见例如http://en.wikipedia.org/wiki/Lab_color_space);您可以选择其中一个,沿着直线连接相同的步骤,连接该空间中的起始和结束颜色,然后转换为RGB。 但是,对于你的应用程序来说,这些中的任何一个都可能是过度的,并且没有明显的理由说明为什么它们应该比简单和纯粹的经验更好 - 或者更好 - 更好。那么为什么不这样做呢: 选择开始和结束颜色。为简单起见,我们假设它们在HSV空间中具有S = 1和V = 1。记下来。 沿着您发布的色调“光谱”查看并找到一个颜色,在您的起点和终点之间找到一半。请注意这一点。 现在再次平分:在开始和中间之间找到颜色,在中间和结束之间找到颜色。 重复一次或两次,以便将色调比例分为8或16“感知上相等”的部分。 转换为RGB,将它们粘贴在查找表中,并在它们之间进行线性插值。 稍微调整RGB值,直到看起来很好。 这完全是临时的,并没有任何关于它的原则,但它可能工作得很好,最终的代码基本上是微不足道的:
void compute_rgb(int * rp, int * gp, int * bp, int t) {
  // t in the range 0..255 (for convenience)
  int segment = t>>5; // 0..7
  int delta = t&31;
  int a=rgb_table[segment].r, b=rgb_table[segment+1].r;
  *rp = a + ((delta*(b-a))>>5);
  a=rgb_table[segment].g; b=rgb_table[segment+1].g;
  *gp = a + ((delta*(b-a))>>5);
  a=rgb_table[segment].b; b=rgb_table[segment+1].b;
  *bp = a + ((delta*(b-a))>>5);
}
(如果不关心保存每个可用周期,可以使代码更清晰一些)。 对于它的价值,我的眼睛将分割点的色调值设置为大约(0),40,60,90,150,180,240,270,(300)。你的旅费可能会改变。     
FastLED做了一个版本:https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors HSLUV是另一种选择:http://www.hsluv.org/。他们有一堆不同语言的图书馆。 此外,这是一项有趣的技术:https://www.shadertoy.com/view/4l2cDm
const float tau = acos(-1.)*2.;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy;

    vec3 rainbow = sqrt( //gamma
        sin( (uv.x+vec3(0,2,1)/3.)*tau ) * .5 + .5
    );

    fragColor.rgb = rainbow;
}
另见: https://en.wikipedia.org/wiki/Rainbow#Number_of_colours_in_spectrum_or_rainbow了解更多信息。     

要回复问题请先登录注册