<p>Consider these facts:</p>
<ul>
<li>Monitors and TVs cannot reproduce the full brightness of the sun, or even many other light sources.</li>
<li>Both eyes and cameras react to the overall brightness they perceive (“adaptation” in the first case, and “automatic exposure” in the second) to capture an image which is in a <em>usable range</em>.</li>
</ul>
<p>Thus, <em>at least one</em>, and often several, of the steps in the path from physical reality (or simulation thereof) to what we perceive in our brains, largely discard the absolute intensity of light in favor of preserving <em>differences between parts of the scene.</em> Most color and image data on computers represents <a href="https://en.wikipedia.org/wiki/Relative_luminance" rel="nofollow noreferrer">relative luminance</a>, not absolute.</p>
<p>You're attempting to skip that step, and it's not working, because the practice of storing 8 bits per color component (as most image file formats typically do) rests on the premise that the image represents a “reasonable” range of luminance. (High-dynamic-range image formats store more bits per component.)</p>
<p>What you can do instead:</p>
<ol>
<li>Scale your pixel values (“set the exposure”) differently for day and night. You can do this arbitrarily as an artistic choice, or you can render your scene, make a histogram of the pixels' luminance, and then choose a scale value which ensures that no more than some chosen fraction of the pixels are “overexposed” (greater than 255 after scaling).</li>
<li>Use a HDR output format.</li>
</ol>
<hr />
<p>I also notice that you mention pixels that are “blacker than black”. That shouldn't happen in a realistic model, since there's no such thing as negative light. This might mean that small floating-point rounding errors produced numbers slightly less than zero (harmless), or that the color-space conversion math produced a slightly <a href="https://en.wikipedia.org/wiki/Impossible_color#Imaginary_colors_in_color_spaces" rel="nofollow noreferrer">impossible color</a>, or that you have some other more significant arithmetic error.</p>

CC BY-SA 4.0
2022-02-12T05:21:00.983Z
2022-02-12T05:21:00.983Z
Kevin Reid
<p>I have implemented <a href="https://courses.cs.duke.edu/cps124/spring08/assign/07_papers/p91-preetham.pdf" rel="nofollow noreferrer">Preetham, Shirley, and Smits’s daylight model</a> using <a href="https://github.com/taktoa/slib/blob/master/daylight.scm" rel="nofollow noreferrer">Aubrey Jaffer’s Scheme implementation</a> as a reference and confirmed that my implementation produces the same results in the xyY coordinate space for the same input on all my test cases as Jaffer’s.</p>
<p>However, when I try to convert this output to sRGB using the <a href="https://www.w3.org/Graphics/Color/sRGB.html" rel="nofollow noreferrer">standard formulae</a>, almost all inputs except for those around sunrise and sunset map to colours ‘darker than black’ (all coordinates less than 0) at night, or ‘lighter than white’ (all coordinates greater than 1.0/255) during the day.</p>
<p>An example: for solar day 38 (declination -15.7117) at solar hour 14 at latitude 52.52 (θ<sub>s</sub> = 72.9996°, φ<sub>s</sub> = 44.0935°) with turbidity 6, Jaffer’s implementation and mine both give xyY values for θ = 30, φ = 0: (0.3576953919457298, 0.3065955987210767, 5.907977352059564). This is the procedure <code>clear-sky-color-xyY</code> in Jaffer’s Scheme implementation. However, using Jaffer’s <a href="https://github.com/taktoa/slib/blob/master/colorspc.scm" rel="nofollow noreferrer"><code>xyY-&gt;XYZ</code> and <code>CIEXYZ-&gt;sRGB</code> procedures</a> (which likewise apply the same formulae as my code) on this result yields sRGB octets 255, 255, and 255.</p>
<p>For solar hours around 7 and 17 (sunset and sunrise), the results appear somewhat reasonable, but broad daylight and dark night are both too light and too dark.</p>
<p>What corrections are necessary to make the model practical for rendering in sRGB and similar colour spaces?</p>

<lighting><color>
Using the Preetham/Shirley/Smits daylight model to get practical (s)RGB values
Daphne Preston-Kendal
# Using the Preetham/Shirley/Smits daylight model to get practical (s)RGB values

(Asked by: username_0 on 2022-02-09)

I have implemented [Preetham, Shirley, and Smits’s daylight model](https://courses.cs.duke.edu/cps124/spring08/assign/07_papers/p91-preetham.pdf) using [Aubrey Jaffer’s Scheme implementation](https://github.com/taktoa/slib/blob/master/daylight.scm) as a reference and confirmed that my implementation produces the same results in the xyY coordinate space for the same input on all my test cases as Jaffer’s.

However, when I try to convert this output to sRGB using the [standard formulae](https://www.w3.org/Graphics/Color/sRGB.html), almost all inputs except for those around sunrise and sunset map to colours ‘darker than black’ (all coordinates less than 0) at night, or ‘lighter than white’ (all coordinates greater than 1.0/255) during the day.

An example: for solar day 38 (declination -15.7117) at solar hour 14 at latitude 52.52 (θs = 72.9996°, φs = 44.0935°) with turbidity 6, Jaffer’s implementation and mine both give xyY values for θ = 30, φ = 0: (0.3576953919457298, 0.3065955987210767, 5.907977352059564). This is the procedure `clear-sky-color-xyY` in Jaffer’s Scheme implementation. However, using Jaffer’s [`xyY->XYZ` and `CIEXYZ->sRGB` procedures](https://github.com/taktoa/slib/blob/master/colorspc.scm) (which likewise apply the same formulae as my code) on this result yields sRGB octets 255, 255, and 255.

For solar hours around 7 and 17 (sunset and sunrise), the results appear somewhat reasonable, but broad daylight and dark night are both too light and too dark.

What corrections are necessary to make the model practical for rendering in sRGB and similar colour spaces?

**Tags:** lighting, color


---

## 1 answers

### Answer by username_1 on 2022-02-12. Score: 2 | Accepted answer

Consider these facts:

* Monitors and TVs cannot reproduce the full brightness of the sun, or even many other light sources.
* Both eyes and cameras react to the overall brightness they perceive (“adaptation” in the first case, and “automatic exposure” in the second) to capture an image which is in a *usable range*.

Thus, *at least one*, and often several, of the steps in the path from physical reality (or simulation thereof) to what we perceive in our brains, largely discard the absolute intensity of light in favor of preserving *differences between parts of the scene.* Most color and image data on computers represents [relative luminance](https://en.wikipedia.org/wiki/Relative_luminance), not absolute.

You're attempting to skip that step, and it's not working, because the practice of storing 8 bits per color component (as most image file formats typically do) rests on the premise that the image represents a “reasonable” range of luminance. (High-dynamic-range image formats store more bits per component.)

What you can do instead:

1. Scale your pixel values (“set the exposure”) differently for day and night. You can do this arbitrarily as an artistic choice, or you can render your scene, make a histogram of the pixels' luminance, and then choose a scale value which ensures that no more than some chosen fraction of the pixels are “overexposed” (greater than 255 after scaling).
2. Use a HDR output format.

---

I also notice that you mention pixels that are “blacker than black”. That shouldn't happen in a realistic model, since there's no such thing as negative light. This might mean that small floating-point rounding errors produced numbers slightly less than zero (harmless), or that the color-space conversion math produced a slightly [impossible color](https://en.wikipedia.org/wiki/Impossible_color#Imaginary_colors_in_color_spaces), or that you have some other more significant arithmetic error.


---

