RGB values of visible spectrum

sorush-r picture sorush-r · Aug 4, 2010 · Viewed 45.3k times · Source

I need an algorithm or function to map each wavelength of visible range of spectrum to its equivalent RGB values. Is there any structural relation between the RGB System and wavelength of a light? like this image: alt text
(source: kms at www1.appstate.edu)

sorry if this was irrelevant :-]

Answer

Spektre picture Spektre · Mar 27, 2014

I recently found out that my spectral colors don't work properly because they were based on nonlinear and shifted data. So I did little research and data compilation and found out that most spectrum images out there are incorrect. Also, the color ranges do not match to each other, so I used from this point only linearized real spectroscopy data like this

Here is the rectified output of mine:

spectral colors

  • the first spectrum is the best rendered spectrum I found but still way off the real thing
  • the second one is linearized Spectrum of our Sun taken from Earth
  • the last one is my current color output

Below are the RGB graphs:

This is the merge of both graphs:

graph merge

Now the code:

void spectral_color(double &r,double &g,double &b,double l) // RGB <0,1> <- lambda l <400,700> [nm]
    {
    double t;  r=0.0; g=0.0; b=0.0;
         if ((l>=400.0)&&(l<410.0)) { t=(l-400.0)/(410.0-400.0); r=    +(0.33*t)-(0.20*t*t); }
    else if ((l>=410.0)&&(l<475.0)) { t=(l-410.0)/(475.0-410.0); r=0.14         -(0.13*t*t); }
    else if ((l>=545.0)&&(l<595.0)) { t=(l-545.0)/(595.0-545.0); r=    +(1.98*t)-(     t*t); }
    else if ((l>=595.0)&&(l<650.0)) { t=(l-595.0)/(650.0-595.0); r=0.98+(0.06*t)-(0.40*t*t); }
    else if ((l>=650.0)&&(l<700.0)) { t=(l-650.0)/(700.0-650.0); r=0.65-(0.84*t)+(0.20*t*t); }
         if ((l>=415.0)&&(l<475.0)) { t=(l-415.0)/(475.0-415.0); g=             +(0.80*t*t); }
    else if ((l>=475.0)&&(l<590.0)) { t=(l-475.0)/(590.0-475.0); g=0.8 +(0.76*t)-(0.80*t*t); }
    else if ((l>=585.0)&&(l<639.0)) { t=(l-585.0)/(639.0-585.0); g=0.84-(0.84*t)           ; }
         if ((l>=400.0)&&(l<475.0)) { t=(l-400.0)/(475.0-400.0); b=    +(2.20*t)-(1.50*t*t); }
    else if ((l>=475.0)&&(l<560.0)) { t=(l-475.0)/(560.0-475.0); b=0.7 -(     t)+(0.30*t*t); }
    }
//--------------------------------------------------------------------------

Where

  • l is the wavelength in [nm] usable valueas are l = < 400.0 , 700.0 >
  • r,g,b are returning color components in range < 0.0 , 1.0 >