<p>Your way of calculating XYZ functions is probably the most efficient way to go about calculating accurate colors from a spectrum. It is standard practice afaik, for examples the books Physically Based Rendering (3rd) and Real-Time Rendering (3rd) both use this method.</p>

<p>You can add the colors in RGB space, but only if you convert from sRGB to linear RGB first. Otherwise you need to take into account, that sRGB sums will not lead to correct colors. The blogpost <a href="http://renderwonk.com/blog/index.php/archive/adventures-with-gamma-correct-rendering/" rel="noreferrer">Adventures with Gamma-Correct Rendering</a> by Naty Hoffman is a good read regarding this, topc:</p>

<blockquote>
  <p>Computing shading in sRGB space is like doing math in a world where 1+1=3.</p>
</blockquote>

<p>This is the problem you have when adding colors in sRGB.</p>

<p>As to whether $XYZ$ can be summed, I think so. If we look at the definition of the coordinates (for $S$ is the spectral function and $x, y, z$ are the CIE functions):</p>

<p>$X = \frac{1}{\int_\lambda y(\lambda) d\lambda} \int_\lambda S(\lambda) x(\lambda) d\lambda$</p>

<p>Now two $X$ coordinates $X_1, X_2$ would have the same definition, only the spectrals are different ($S_1, S_2$).</p>

<p>Thus you have</p>

<p>$X_1 + X_2 = \frac{1}{\int_\lambda y(\lambda) d\lambda} \int_\lambda S_1(\lambda) x(\lambda) d\lambda + \frac{1}{\int_\lambda y(\lambda) d\lambda} \int_\lambda S_2(\lambda) x(\lambda) d\lambda\\
= \frac{1}{\int_\lambda y(\lambda) d\lambda} \left(\int_\lambda S_1(\lambda) x(\lambda) d\lambda + \int_\lambda S_2(\lambda) x(\lambda) d\lambda\right)\\
= \frac{1}{\int_\lambda y(\lambda) d\lambda}\int_\lambda S_1(\lambda) x(\lambda) + S_2(\lambda) x(\lambda) d\lambda \\
= \frac{1}{\int_\lambda y(\lambda) d\lambda}\int_\lambda (S_1(\lambda)  + S_2(\lambda)) x(\lambda) d\lambda\\
=X$</p>

<p>The same holds for other coordinates.</p>

<p>Therefore, your best option is probably to sum your XYZ coordinates and convert them to sRGB space in the end.</p>

CC BY-SA 3.0
2018-01-16T15:21:31.213Z
2018-01-16T15:21:31.213Z
Tare
<p>I have two somewhat related questions to ask:</p>

<ol>
<li>What is the most accurate way to get the colors of a spectrum, without having to go deep into physics and simulating the universe? ;) Right now, I'm using <a href="http://cvrl.ioo.ucl.ac.uk/cmfs.htm" rel="nofollow noreferrer" title="Color matching functions">these</a> color matching functions, and simply reading off the XYZ color of a particular wavelength and converting it to sRGB. I know sRGB can't represent most spectral colors, but let's ignore that.</li>
<li>If I'm trying to make a color, say white, out of the spectral colors, how should I combine them? Should I add the color in XYZ space, or in RGB space, or is neither sufficient?</li>
</ol>

<p>My plan is to experiment with spectral rendering, so it should be accurate enough to avoid biased renders. It'll most likely be on the GPU, and I need accuracy over speed.</p>

CC BY-SA 3.0
2018-01-15T22:17:36.030Z
What's best depends a lot on your application and what operations you want to do on these spectra. Could you [edit] your question to add some more about that?
Dan Hulme
CC BY-SA 3.0
2018-01-15T22:40:25.303Z
Just edited my question to add a bit of clarification.
Daniel Kareh
<color><color-science><spectral>
Generating and Combining Spectral Colors
Daniel Kareh
# Generating and Combining Spectral Colors

(Asked by: username_0 on 2018-01-15)

I have two somewhat related questions to ask:

1. What is the most accurate way to get the colors of a spectrum, without having to go deep into physics and simulating the universe? ;) Right now, I'm using [these](http://cvrl.ioo.ucl.ac.uk/cmfs.htm "Color matching functions") color matching functions, and simply reading off the XYZ color of a particular wavelength and converting it to sRGB. I know sRGB can't represent most spectral colors, but let's ignore that.
2. If I'm trying to make a color, say white, out of the spectral colors, how should I combine them? Should I add the color in XYZ space, or in RGB space, or is neither sufficient?

My plan is to experiment with spectral rendering, so it should be accurate enough to avoid biased renders. It'll most likely be on the GPU, and I need accuracy over speed.

**Tags:** color, color-science, spectral

> **Comments:**
> **username_1**: What's best depends a lot on your application and what operations you want to do on these spectra. Could you [edit] your question to add some more about that?  
> **username_0**: Just edited my question to add a bit of clarification.  

---

## 1 answers

### Answer by username_2 on 2018-01-16. Score: 5 | Accepted answer

Your way of calculating XYZ functions is probably the most efficient way to go about calculating accurate colors from a spectrum. It is standard practice afaik, for examples the books Physically Based Rendering (3rd) and Real-Time Rendering (3rd) both use this method.

You can add the colors in RGB space, but only if you convert from sRGB to linear RGB first. Otherwise you need to take into account, that sRGB sums will not lead to correct colors. The blogpost [Adventures with Gamma-Correct Rendering](http://renderwonk.com/blog/index.php/archive/adventures-with-gamma-correct-rendering/) by Naty Hoffman is a good read regarding this, topc:

> Computing shading in sRGB space is like doing math in a world where 1+1=3.

This is the problem you have when adding colors in sRGB.

As to whether $XYZ$ can be summed, I think so. If we look at the definition of the coordinates (for $S$ is the spectral function and $x, y, z$ are the CIE functions):

$X = \frac{1}{\int\_\lambda y(\lambda) d\lambda} \int\_\lambda S(\lambda) x(\lambda) d\lambda$

Now two $X$ coordinates $X\_1, X\_2$ would have the same definition, only the spectrals are different ($S\_1, S\_2$).

Thus you have

$X\_1 + X\_2 = \frac{1}{\int\_\lambda y(\lambda) d\lambda} \int\_\lambda S\_1(\lambda) x(\lambda) d\lambda + \frac{1}{\int\_\lambda y(\lambda) d\lambda} \int\_\lambda S\_2(\lambda) x(\lambda) d\lambda\\
= \frac{1}{\int\_\lambda y(\lambda) d\lambda} \left(\int\_\lambda S\_1(\lambda) x(\lambda) d\lambda + \int\_\lambda S\_2(\lambda) x(\lambda) d\lambda\right)\\
= \frac{1}{\int\_\lambda y(\lambda) d\lambda}\int\_\lambda S\_1(\lambda) x(\lambda) + S\_2(\lambda) x(\lambda) d\lambda \\
= \frac{1}{\int\_\lambda y(\lambda) d\lambda}\int\_\lambda (S\_1(\lambda) + S\_2(\lambda)) x(\lambda) d\lambda\\
=X$

The same holds for other coordinates.

Therefore, your best option is probably to sum your XYZ coordinates and convert them to sRGB space in the end.


---

