POV-Ray : Newsgroups : povray.pov4.discussion.general : Builtin color spaces, spectral colors? : Re: Builtin color spaces, spectral colors? Server Time
26 Apr 2024 11:48:10 EDT (-0400)
  Re: Builtin color spaces, spectral colors?  
From: Simon Copar
Date: 25 Mar 2013 12:00:02
Message: <web.51507388b3de06a65a03f8f0@news.povray.org>
> It might also make sense to provide a way to specify the frequencies of
> the individual channels; this way, a user could e.g. have POV-Ray use
> more channels in the yellow region for a scene with sodium lamps.

I like this idea, this way you could accurately raytrace even scenes with
monochromatic (laser-like) illumination, or use it to simulate actual display
devices and optics.

> > and of course, a mapping function to get back from spectrum to rgb
> > (nontrivial, there are several different spectral response function models that
> > try to approximate the human eye, or a display device).
>
> Until now I'd have expected that to be the least problem: Just choose
> one of the two CIE standard observers, use the response functions to
> convert to XYZ, and from there to whatever color space is chosen for output.

I have to say that I never really liked XYZ color space. Mapping from XYZ to RGB
is linear, so there is no difference between converting to XYZ and then to a
chosen RGB (+gamma correction after that), or precomputing RGB response
functions and mapping directly to that. There is no additional information in
XYZ color space, it's just defined to avoid negative values in standard (from
year 1931, not very representative) rgb physiological response functions. We
could remove the intermediate step and go directly to the target color space, we
lose nothing.

Sorry for the rant, I got very frustrated recently about the arbitrary
definition of XYZ space and the difference between physiological and
standardized color spaces (CIE rgb, scrgb,...).

I think that it would make the most sense to let the user override the rgb
response functions, because this opens the doors for color profile freaks that
are never satisfied with the default settings. You could use a spectral response
of a specific display device for maximum accuracy (for instance, if you know
exactly what projector will display your movie). And for normal users, you would
just keep scrgb as default.

> I guess this is actually the hardest nut to crack.
>
> The most straightforward approach would of course be to pick a set of of
> real-life or synthesized phosphors with known emission curves; we'd then
> first convert from scRGB to the RGB color space defined by those
> phosphors, and then multiply each color component by the corresponding
> phosphor's spectrum.
>
> However, I don't like this approach, as it would still be strongly
> biased towards red, green and blue hues, in the sense that filters of
> those hues attenuate light of the same hue less than would be the case
> with yellow, cyan or purple hues. I'd rather prefer a spectrum synthesis
> algorithm where the attenuation of a given filter depends only on
> brightness and saturation.

Right, I see it's much worse than I imagined. The main problem is, that standard
rgb responses are not orthogonal. Of you start with <1,0,0>, map to CIE_red and
then project back, you will probably get something like <0.97,0.02,-0.03>
On one hand, this avoids the problem that most "pure" rgb colors look
unrealistic, especially with radiosity and photons turned on, but it also makes
the results behave in an unexpected way. Still, in the spectral model, it's
mostly impossible to find the spectral responses that would give pure colors,
because the target color space response functions overlap.

However, I see one well-defined (and probably mathematically optimal) solution.
What you want is a closest match of rgb colors in the target color space. Let's
say you choose 4 sample wavelengths. You are looking for a vector (a,b,c,d) that
satisfies
(a,b,c,d)*red_response=r
(a,b,c,d)*green_response=g
(a,b,c,d)*blue_response=b
where red,green,blue_response are (in this example 4-component) vectors that
approximate the spectral response functions. This is simply a linear system of
equations (3 equations, N variables for N samples) that can be solved to give a
least-square fit to the desired rgb color (matrix pseudoinverse solves this
trivially).

This approach is
* specifically designed for chosen wavelength samples
* treats all hues equally
* gets mathematically as close as possible to the non-spectral solution with the
same colors

Disadvantages:
* spectral result will depend more on chosen wavelength samples than it would if
you used default response functions
* the resulting (a,b,c,d) may include negative values because it tries to remove
the response overlap. I think for reasonable sample selection it wouldn't be too
bad.

A related solution that also solves these problems, is to take the same set of
linear equations described above, but instead of just taking the pseudo-inverse
(and getting least-square solution), you can minimize
abs(r-r0)+abs(g-g0)+abs(b-b0) and specify constraints a>0,b>0,c>0,d>0. This is a
linear programming problem [algorithm can be taken straight from numerical
recipes], which is also mathematically well-defined an will give you an optimal
and physically meaningful result. This would of course all be done at parse
time.

I vote for the second solution, I think it's as good as you can get :)

> Yup. If you have any additional ideas along these lines, feel free to
> let your thoughts go wild.

Just one thought. Now we have filter & transmit options. This works quite well
for most cases, but is still restrictive. Basically, the light that hits the
surface can be split in into reflected (seen by camera), transmitted and
absorbed components in any possible way. Physically, energy conservation only
requires reflected_color+transmitted_color<1. Right now, "transmit" gives you
transmitted_color=constant and "filter" gives you
transmitted_color=constant*reflected_color, and combination of filter and
transmit gives you something in the middle.
In rgb space, this is not so bad, but when you go spectral, you lose a lot of
options.

Instead of transmit & filter we could have a single color parameter
pigment {
  color rgb [mycolor] transmission [othercolor]
}
and a fallback with old syntax that generates the transmission color according
to above model.

I would suggest this even without the spectral model. It enables you to do with
normal textures what you can already do with media - simulation of materials,
that don't just absorb, but scatter (shadow gets an opposite color as the
material, like
http://nanocomposix.com/sites/default/files/images/technology/plasmonics/_MG_3049_1.jpg).

If the material is thin enough, you could avoid media by using this model on the
surface texture. And that's just the extreme scenario. Most of the paints and
finishes have at least some of this effect.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.