Earthshine and moonshine

This commit is contained in:
connor committed 2026-10-14 21:31:22 -04:00
1 parent 768a4e9c53
commit ff2ef10804
19 files changed
+1665 -138

No files matched your search

+96 -3
View File
@@ -662,6 +662,7 @@ Limitations:
everything else, until M3's pixel-area sampling.
- **Bodies.** Earth and the Moon do not use shadow maps. Their shadows on
the target are the eclipse factor below, applied to the whole target.
Light from Earth and the Moon (below) is not shadowed at all.
### Eclipses
@@ -688,8 +689,101 @@ the solar disk.
The renderer counts both Earth and the Moon as occulters. The fraction is
computed once per target, at its center. The whole target
dims together, which is accurate unless the target is a sizable fraction of
the penumbra's width. Light reaching the target from Earth itself
(Earthshine), which matters most when the target is in shadow, comes in M2.
the penumbra's width. Light reaching the target from Earth itself is the
next section.
### Light from Earth and the Moon
Code: `gpu/earthshine.rs`, `shaders/earthshine.wgsl`, `shaders/mesh.wgsl`.
From lighting L1.
Earth reflects about a third of the sunlight that reaches it, and some of
that lands on the target: Earthshine. From low orbit it is large. At 500 km,
Earth fills a circle 68 degrees in radius around the point straight down,
3.9 of the sky's 12.6 steradians. A plate facing straight down over the
sunlit Earth receives up to about a quarter as much light from Earth as a
plate facing the Sun receives from the Sun. A white Earth would give 0.85
(the test below measures that case). At geostationary distance, Earth is 17
degrees across and a plate facing a full Earth gets about 0.5 % of sunlight.
The Moon does the same, Moonshine, much more weakly: a full Moon seen from
near Earth gives about a millionth of sunlight. From 100 km above the Moon,
though, a plate facing it gets about a tenth of sunlight.
This matters most where the Sun does not reach: the target's night side,
and parts in a shadow of its own. Without it those read as black, the bias in
DN; with it they show their structure, dimly.
The renderer works out, for each target and each frame, how much light
arrives from Earth and the Moon on a surface facing any direction:
1. **What the target sees of each body.** The circle on the sky that the body
fills is cut into 1024 cells of equal solid angle: 32 rings from the
center out to the edge, 32 cells around each. A line from the target
through each cell's center finds the point it meets on the body, and that
point is shaded exactly as the camera's view of the body is shaded:
reflectance from the Blue Marble image (or the stand-in spectrum), lit by
the cosine of the Sun's angle there, dark on the night side. Each texture
read averages the patch of ground the cell covers, about 1000 square
kilometers straight down from 500 km and more toward Earth's edge, so a
cell sees the mean color of that patch rather than one point. A line
that meets the other body first counts nothing, so the Moon can hide part
of Earth and Earth part of the Moon.
2. **Light for every direction a surface can face.** For a surface facing
direction n, the light it receives is the sum over all cells of the cell's
brightness, times its solid angle, times the cosine between n and the
cell's direction (zero for cells behind the surface). The renderer adds
this up for a grid of directions, a cube map 16 texels across on each of
its six faces.
Drawing the target, each point reads that cube at its surface normal and
adds albedo / pi times the result to the direct sunlight. The cube is computed
at the center of each target's bounding sphere and used for the whole target;
across a spacecraft the view of Earth barely changes.
Earthshine is not dimmed by the target's eclipse factor, because the two
are different views of Earth. From anywhere in Earth's umbra only the night
side is in view, so Earthshine is zero there without being told. In the
penumbra the Sun is partly hidden but a crescent of lit ground is still in
view, and that light still arrives.
Tests (`tests/earthshine.rs`) compare a plate's brightness on the GPU and
lavapipe against the same sum done in 64-bit floating point with 90 times as
many cells: over the subsolar point at 500 km facing down, sideways and up;
toward the terminator; in Earth's shadow; at GEO; 100 km above the Moon at
full and quarter phase; with each body hiding the other; with the plate seen
from several sides, so each cube face a camera-facing surface reads is checked. Every
case where the bodies send more than a thousandth of sunlight agrees to
within 0.5 %. The largest differences come from the cube: between texels
5.6 degrees apart its interpolation rounds off the peak of a surface facing
a full Earth or Moon, by 0.4 %. A cube 32 texels across cuts that to 0.13 %
but costs four times as much, and the cells' own error on a half-lit distant
Earth (0.4 %) stays. A thin crescent of lit ground at Earth's edge, seen from
low orbit near the terminator, is off by 4 % of a small amount, 7e-5 of
sunlight, about 0.1 DN on a gray surface in the example camera. Another test
checks the sum itself against the classical formula for a distant sphere,
(2/3) albedo (R/D)^2 Phi(alpha), to within 0.3 %.
On the RTX 3060 this costs 0.04 ms of GPU time per target (0.28 ms for
eight), and 1.4 ms per target on lavapipe.
Limitations:
- **No shadows.** The target's own parts do not block light from Earth or
the Moon. A panel facing Earth does not shade the bus behind it from
Earthshine, and the inside of a dish facing Earth is lit as if open to the
whole Earth. Earth fills too much of the sky for one shadow map to stand in
for it; the ray tracer (M5) handles this.
- **One spectrum per channel.** Light from Earth is bluer than sunlight, but
the target's albedo in each channel was worked out under sunlight. This is
the shortcut described in "Folding spectra into per-channel constants",
and its error is largest for strongly colored surfaces.
- **Lambertian bodies.** Earth and the Moon reflect as Lambertian surfaces
here, as they do in the camera's view. The Moon's real reflection is
brighter toward the Sun (M4), and Earth has no clouds or atmosphere yet
beyond the stand-in haze.
- **No eclipses on the bodies.** Earth's shadow on the Moon and the Moon's
shadow on Earth are not modeled yet (M2), so a Moon in eclipse still lights
the target.
## Where the Sun and Moon appear
@@ -721,7 +815,6 @@ velocity as an input, which the scene does not carry yet.
| Effect | Where |
|---|---|
| Light from Earth and the Moon illuminating the target (Earthshine, Moonshine) | M2 |
| Eclipses seen on the bodies: Earth's shadow on the Moon, the Moon's on Earth | M2 |
| Earthshine on the Moon's night side | M4 |
| The Sun as a disk that is darker toward its edge (limb darkening) | M2 |