dated clouds and lighting L2

This commit is contained in:
connor committed 2026-10-18 15:21:05 -04:00
1 parent b3c6a59e46
commit c7b890f3db
28 files changed
+621 -34

No files matched your search

+81 -1
View File
@@ -1346,13 +1346,93 @@ Limitations:
back down by the cloud's base is left out. It matters over snow and ice.
- **The sky light under a cloud** is dimmed by the cloud toward the Sun, not by
the clouds over the whole sky.
- **One day's clouds**, whatever the scene's date. Maps by date are planned.
- **At lighting L1, one day's clouds**, whatever the scene's date. Lighting L2
draws the scene's day's (next section).
- **The map** is 2.45 km per pixel. Small cumulus are blurred into a gray
veil. The composite also has straight seams where its pieces meet, at
high latitudes, which show as clouds that end on a straight line (east of
Greenland in the solar eclipse example).
- **Without the atmosphere** (`Appearance::earth_atmosphere` off), no clouds.
### Clouds of the day (lighting L2)
Code: `scripts/fetch-dated-clouds.py`, the command line's choice of map. Lighting
L2.
At lighting L1 the clouds are always those of 2001 July 29. Lighting L2 draws the
clouds of the scene's day, from MODIS on Terra and Aqua, with the same layer and
shading as above. Only the map differs.
**Making a day's map.** NASA's Global Imagery Browse Services (GIBS) serve the
MODIS cloud products as images, one global composite per day. The cloud optical
thickness comes as colors that stand for values, in steps of about 4 % from 0.01
to 150 (GIBS's color map). `scripts/fetch-dated-clouds.py FIRST [LAST]` fetches
each day's layers as two hemispheres of 8192 x 8192 pixels (GIBS times out on the
whole map at once) and turns the colors back into numbers. All 252 colors in the
images are in the color map, so none were blended in the resampling. For each
pixel it takes the first optical thickness of:
1. Terra's standard retrieval;
2. Aqua's;
3. Terra's partly cloudy retrieval (PCL);
4. Aqua's PCL.
That thickness becomes reflectance by the formula above. A pixel with none of them
but a cloud fraction from either satellite is clear, because MODIS retrieves
thickness wherever its cloud mask finds cloud in daylight. A pixel with no data at
all, between passes or in polar night, takes the static map's value. The map is
written at the static map's size, 16384 x 8192, as `data/clouds/YYYY-MM-DD.png`.
Each day takes about two minutes and 0.3 GB of downloads, and keeps 20 MB.
For 2024 July 15 that gives:
- thickness over 56 % of Earth's area;
- clear over 43 %, including the dark Antarctic winter, where only the infrared
cloud fraction has data;
- no data over 1.3 %.
The mean reflectance is 0.247, against 0.207 for the static map. Fewer pixels are
cloudy, 55 % against 65 % north of 60 S, but those that are are brighter.
**Checking it.** Earth rendered at phase angles from 0 to 180 degrees, as for the
static map, reflects 0.31 to 0.33 of the sunlight in green (Bond albedo) with the
day's clouds, against 0.27 to 0.29 with the static map and about 0.30 measured.
Seen from 80,000 km over Africa, the day's clouds lie where MODIS's true-color
image of that day shows them: the storms over the North Atlantic, the band over
the Sahel, and the clouds over Europe. The Saharan dust in that image is aerosol,
not cloud, and is not drawn.
**Choosing the day.** The command line takes the day of the scene's epoch in UTC,
or `[appearance] cloud_date` in a scene without an epoch. The July example scenes
give 2024-07-15. A day whose map is missing is an error that names the command to
fetch it, and a scene with no day at all is an error too. Lighting L2 needs a
cloud map and Earth's atmosphere, and the renderer refuses it without them.
`Renderer::set_cloud_map` swaps one map for another between frames, for a run that
crosses days. It takes about 175 ms on the RTX 3060 and 240 ms on lavapipe, mostly
building the mip chain and uploading it, and the frames after it are those of a
renderer made with the new map. Rendering costs what it does at L1.
Tests: the day's choice from `cloud_date`, from the epoch on either side of UTC
midnight, and from a TT epoch half a minute after midnight, which is still the day
before in UTC; the errors for a missing map and for a scene with no day; L2's
refusal without clouds or without the atmosphere; and a swap that draws what a
fresh renderer draws, to the bit, on the GPU and lavapipe.
Limitations:
- **Seams.** Terra crosses the equator at 10:30 local time and Aqua at 13:30, so
where one satellite's data gives way to the other's, clouds that moved in three
hours end on a line. So do the edges of a single satellite's passes, made at
different times of the day.
- **One map per day.** The clouds of a whole UTC day are drawn at any time of it,
though each place is seen by MODIS only around late morning and early afternoon.
- **Thickness at 1 km, map at 2.45 km.** Broken clouds below that blur, as in the
static map.
- **Clear where MODIS saw no cloud,** including where its retrieval failed for
other reasons, such as sun glint; there the map has no cloud that may have been
there.
- **Polar night** takes the static map, which is dark there anyway.
### The Moon's surface
Code: `moon.rs`, `shaders/bodies.wgsl`; data from `scripts/fetch-moon.py`. From