Color chunks can be spectral,
rgb , or scalar.
When an rgb needs to be converted to a spectrum or vice-versa,
the following convention is suggested:
an rgb can be interpreted as a wighted sum of piecewise constant spectra.
So the spectrum associated with (r, g, b) is:
S(n) = rR(n) + gG(n) + bB(n)
where R(n) is 1.0 between 600 and 700 nm and 0.0 elsewhere,
G(n) is 1.0 between 500 and 600 nm and 0.0 elsewhere,
and B(n) is 1.0 between 400 and 500 nm and 0.0 elsewhere.
This has the following implications for coverting
from (r, g, b) to (X, Y, Z) and vice-versa:
r = 1e-6*48.775833*X - 1e-6*28.546449*Y - 1e-6* 6.444295*Z
g = -1e-6*11.248997*X + 1e-6*24.748338*Y + 1e-6* 0.188623*Z;
b = 1e-6* 0.486631*X - 1e-6* 1.077566*Y + 1e-6*14.353197*Z;
X = 27933.7*r + 32748.0*g + 12111.3*b
Y = 12696.8*r + 55268.7*g + 4974.29*b
Z = 6.147*r + 3039.01*g + 69633.7*b
A few caveats:
- Colors is a slight misnomer;
these chunks are used to specify several types of data
such as reflectance, radiant exitance, and index of refraction.
In general, you should think of these chunks as specifing spectra
(i.e. functions of wavelength).
Thus sclr and rgb are merely shorthands for particular types of spectra.
Namely a constant spectrum and a sum of the box functions given above.
If you are actually storing a perceptual color
(which is not a spectrum) in one of these chunks,
you should store it as an rgb chunk
using the transform from XYZ to rgb given above.
XYZ values are defined by the 1931 CIE Standard Color Observer.
- The box functions above define the rgb space used in mdl files.
These are an approximation to the rgb values used by many monitors.
For calibrated systems, you should
directly convert the mdl color data to XYZ values and then
convert these to the appropiate color space for your display.
- A scalar represents a spectrum which has constant value everywhere,
but an rgb spectrum is zero below 400 nm and above 700 nm.
Hence a scalar spectrum with value 1
is not identical to an rgb spectrum with r=g=b=1.
- The standard way to reduce a spectrum to rgb
is to integrate against the box functions and divide by 100.
Note this is reasonable for spectra,
but is not correct for perceptual colors.
For perceptual colors you should always convert to XYZ instead.
- The standard way to reduce a color to a single value
is to point sample it at some reasonable wavelength value
(typically 550 nm when working with visible wavelengths).
For perceptual colors, you should transform to XYZ
and then use the Y (luminance) channel.
- Texture map chunks (txtrMp) are also color chunks
which represent varying color values (e.g. an image)
and can appear anywhere a color chunk does.
They require some additional indices
(typically uv values) when accessing.