Got actual solar spectrum data and incorporated it. Plus radiometry
This commit is contained in:
1 parent
3eb7ec4808
commit
cefcfe7e4e
7 files changed
+1281
-20
No files matched your search
+76
-14
@@ -95,7 +95,7 @@ far plane.
|
||||
|
||||
## Radiometric quantities
|
||||
|
||||
Code: `spectrum.rs` now; `radiometry.rs` in #4.
|
||||
Code: `spectrum.rs`, `radiometry.rs`.
|
||||
|
||||
Light has a few distinct measures, and the camera measures a specific one.
|
||||
|
||||
@@ -171,22 +171,78 @@ energy h c / lambda (h is Planck's constant, c the speed of light). So one
|
||||
watt of red light delivers more photons than one watt of blue. The
|
||||
renderer converts power to photons per wavelength before applying QE.
|
||||
|
||||
### The solar spectrum
|
||||
|
||||
Code: `radiometry.rs` (`solar_spectrum`), generated into `solar_data.rs` by
|
||||
`scripts/fetch-solar-spectrum.sh`.
|
||||
|
||||
The renderer uses a measured solar spectrum, the TSIS-1 Hybrid Solar
|
||||
Reference Spectrum (Coddington et al. 2021). It is the current
|
||||
international reference, built mainly from the TSIS-1 instruments on the
|
||||
International Space Station and filled in with a high-resolution model of
|
||||
the solar absorption lines. It gives the irradiance at 1 AU, outside the atmosphere,
|
||||
every 1 nm from 202 to 2730 nm. Its uncertainty is 0.3 % from 460 to
|
||||
2365 nm. Over that range it sums to 1325.8 W/m^2. The other 35 W/m^2 of the
|
||||
1361 W/m^2 total is at wavelengths silicon detectors do not see.
|
||||
|
||||
The Sun is often approximated as a 5772 K blackbody: a smooth curve with
|
||||
the right total power. The real spectrum has thousands of absorption lines
|
||||
from the Sun's outer layers, and its shape differs from the smooth curve.
|
||||
For the example camera's channels, the blackbody gives 4.6 % (red), 7.5 %
|
||||
(green) and 9.7 % (blue) fewer electrons than the measured spectrum. That
|
||||
is far outside what absolute radiometry can tolerate.
|
||||
|
||||
### Folding spectra into per-channel constants
|
||||
|
||||
Code: `radiometry.rs` (`Radiometry`).
|
||||
|
||||
Doing all of this wavelength by wavelength for every pixel would be slow.
|
||||
Most factors do not depend on the pixel: the solar spectrum, the optics,
|
||||
and the QE curves. The renderer multiplies and integrates those over
|
||||
wavelength once, when the camera is set up. That yields a few numbers per
|
||||
channel, and the GPU only multiplies by them.
|
||||
|
||||
The cost is a small error where two spectra both vary inside one channel's
|
||||
band. An example is a surface whose reflectance changes steeply across
|
||||
green. Rendering more, narrower channels reduces that error, and the code
|
||||
keeps the channel count generic for that reason. (#4)
|
||||
The central number is the solar flux of each channel k:
|
||||
|
||||
```text
|
||||
S_k = integral of E_sun(lambda) * tau(lambda) * QE_k(lambda) * lambda / (h c) d lambda
|
||||
```
|
||||
|
||||
It is the rate of electrons per square meter that sunlight at 1 AU would
|
||||
produce if it fell straight onto the detector through the optics. For the
|
||||
example camera, S_k is about 2.4e20 electrons per second per m^2 in red and
|
||||
green, and 2.0e20 in blue.
|
||||
|
||||
The renderer then works in channel radiance: scene radiance weighted the
|
||||
same way (transmission, QE, photons per joule), in electrons per second
|
||||
per m^2 per steradian. A Lambertian surface with albedo rho, lit at angle i
|
||||
from its normal, at distance d from the Sun in AU, has channel radiance:
|
||||
|
||||
```text
|
||||
L_k = rho * cos(i) * S_k / (pi * d^2)
|
||||
```
|
||||
|
||||
The solar disk has channel radiance S_k / Omega_sun, where Omega_sun is the
|
||||
Sun's solid angle at 1 AU, 6.79e-5 sr (it is 0.53 degrees across). Seen
|
||||
from anywhere, the Sun's surface has that same radiance, about 2.0e7
|
||||
W/m^2/sr in total. Looked at directly, it puts about 5e8 electrons into a
|
||||
pixel of the example camera's green channel in 0.1 ms, 26,000 times the
|
||||
full well.
|
||||
|
||||
A surface whose reflectance varies with wavelength is reduced to an
|
||||
effective albedo per channel. That is the albedo of a flat-spectrum surface
|
||||
that would give the same signal under sunlight
|
||||
(`Radiometry::effective_albedo`). This step is where the error of the
|
||||
shortcut comes in. Two spectra that both vary inside one channel's band
|
||||
interact in ways a single number per channel cannot capture. One example is
|
||||
a surface whose reflectance changes steeply across green, lit partly by
|
||||
sunlight and partly by bluish light scattered from Earth's atmosphere.
|
||||
Rendering more, narrower channels reduces that error, and the code keeps
|
||||
the channel count generic for that reason.
|
||||
|
||||
## From radiance to electrons: the camera equation
|
||||
|
||||
Code: the sensor pass, #9.
|
||||
Code: `radiometry.rs` (`Radiometry::electrons`); the sensor pass, #9.
|
||||
|
||||
A lens with focal length f and aperture diameter D has f-number
|
||||
N = f / D. The example camera is f/4: a 50 mm lens with a 12.5 mm aperture.
|
||||
@@ -215,8 +271,14 @@ The electrons a pixel collects in one channel are then:
|
||||
electrons = E_image * (pixel area) * (exposure time) * (photons per joule) * QE
|
||||
```
|
||||
|
||||
The last two factors are wavelength-dependent and are folded together per
|
||||
channel, as described above.
|
||||
The last two factors are wavelength-dependent. In channel radiance they are
|
||||
already folded in, so the camera equation reduces to
|
||||
|
||||
```text
|
||||
electrons = L_k * pi * (pixel area) * (exposure time) / (4 N^2) * cos^4(theta)
|
||||
```
|
||||
|
||||
For the example camera, pi * A * t / (4 N^2) is 1.48e-16 m^2 sr s.
|
||||
|
||||
## From electrons to DN: the detector
|
||||
|
||||
@@ -238,14 +300,14 @@ So DN = bias + electrons / gain, rounded and clipped to the ADC range.
|
||||
|
||||
Take a white Lambertian surface facing the Sun at 1 AU, seen by the example
|
||||
camera's green channel. Integrating the solar spectrum through the green QE
|
||||
curve, f/4 optics, 5.5 um pixels and a 0.1 ms exposure gives about 10,300
|
||||
electrons. That figure came from a blackbody approximation of the Sun; #4
|
||||
replaces it with the measured solar spectrum.
|
||||
curve, f/4 optics, 5.5 um pixels and a 0.1 ms exposure gives 11,139
|
||||
electrons. Red gets 11,408 and blue 9,626. (A test in `radiometry.rs`
|
||||
checks the green figure.)
|
||||
|
||||
- DN = 64 + 10,300 / 5, about 2125, roughly half the 12-bit range.
|
||||
- The full well is 20,000 electrons, so this surface is at about half of
|
||||
- DN = 64 + 11,139 / 5, about 2292, a little over half the 12-bit range.
|
||||
- The full well is 20,000 electrons, so this surface is at 56 % of
|
||||
saturation.
|
||||
- Earth, with albedo near 0.3, reads about 64 + 3,100 / 5, about 682 DN.
|
||||
- Earth, with albedo near 0.3, reads about 64 + 3,342 / 5, about 732 DN.
|
||||
|
||||
Picking the exposure time is the same trade a photographer makes. A longer
|
||||
exposure saturates the sunlit target. A shorter one leaves the side of the
|
||||
|
||||
Reference in new issue
Block a user