cloud layer

This commit is contained in:
connor committed 2026-10-18 12:59:52 -04:00
1 parent 8e57375059
commit b3c6a59e46
20 files changed
+972 -58

No files matched your search

+119 -5
View File
@@ -999,8 +999,8 @@ This gets the overall brightness and the phase (how much of the disk is
lit) right. It misses some things that are visible in real images:
- Earth's oceans, land and clouds differ in brightness by a factor of
several. From lighting L1, Earth's surface comes from an image (next
section); clouds are not modeled yet.
several. From lighting L1, Earth's surface comes from an image and its
clouds from another (next sections).
- The full Moon looks almost uniformly bright out to its edge. A Lambertian
sphere instead darkens toward the edge, because the light there arrives
and leaves at grazing angles. Lunar soil scatters light back toward its
@@ -1234,12 +1234,125 @@ Limitations:
- **Sunlight reaching the target**, and the Sun and Moon seen past the limb,
pass through the atmosphere as "Sunset through the atmosphere" describes;
targets, stars and Earth's own surface seen past the limb do not.
- **Clouds** are not drawn: Blue Marble is a cloud-free mosaic.
- **Clouds** are a separate layer, the next section.
- **The Moon's shadow** in a solar eclipse dims the air along the line of
sight as it dims the ground point behind it.
- **Light from Earth onto targets** (Earthshine) includes the atmosphere
over the ground, but not the glow beyond Earth's edge.
### Clouds
Code: `clouds.rs`, `shaders/clouds.wgsl`, `shaders/cloudy.wgsl`,
`shaders/earthshine.wgsl`. From lighting L1, with the atmosphere.
Blue Marble's surface is a cloud-free mosaic, but at any moment about two
thirds of Earth is under cloud, and clouds are the brightest thing on it.
Without them Earth looks too dark and too clear, and Earthshine on a target is
too low.
The renderer draws clouds as a thin layer 5 km above the ground. Real cloud
tops run from about 1 to 15 km; one height stands for them all. The layer's map
is the cloud layer of NASA's original Blue Marble (2002): Terra MODIS clouds
of 2001 July 29, with thermal infrared over the poles, 1 km per pixel, resized
to 16384 x 8192 like the Earth maps (`scripts/fetch-clouds.sh`). The same
clouds show whatever the date.
Each pixel's value is read as the cloud's reflectance there, from 0 for clear
sky to 1. Clouds absorb almost no visible light, so what a cloud does not
reflect it passes on: 1 minus its reflectance. A thick cloud is bright and
hides the ground. A thin one is dim and lets the ground show through. How
reflectance goes with a cloud's optical thickness tau (how many times light
would be scattered crossing it straight) is the two-stream result of Lacis and
Hansen (1974):
R = 0.13 tau / (1 + 0.13 tau)
The 0.13 is sqrt(3) / 2 times (1 - g), with g = 0.85 the cloud droplets' strong
forward scattering. So tau = 5 reflects 39 %, tau = 20 reflects 72 %, and tau =
50 reflects 87 %. Over Earth's area the map's mean reflectance is 0.21, and 62 %
of the area has more than 0.05. The map stores reflectance, so its mip levels
average reflectance, which keeps a far view of Earth as bright as a near one.
For each pixel that sees the ground, the shader:
1. finds where the line of sight crosses the layer, and reads the cloud there.
In an oblique view that is not the cloud straight above the ground point,
so clouds show parallax against the ground;
2. finds where the sunlight reaching the ground point crossed the layer, and
dims the ground's sunlight and sky light by that cloud. That is the cloud's
shadow, offset from the cloud away from the Sun: 5 km times the cotangent of
the Sun's elevation, 29 km with the Sun 10 degrees up;
3. adds the cloud's own light: sunlight and sky light at 5 km, which pass
through less air than at the ground, times the cloud's reflectance;
4. adds what is below the cloud, the ground and the air between it and the
layer, times 1 minus the cloud's reflectance. Then it applies the air above
the layer: its glow added, and its transmittance on what is under it.
So high clouds are less hazed than the ground, the way they look from orbit.
The ray's entry into the atmosphere is looked up once and shared by the cloud
and the ground below it.
The Earthshine pass samples the same layer, so a target over cloud receives
more light. A plate 700 km up facing straight down, the Sun overhead, under
clouds of reflectance 0.5 everywhere, receives 2.6, 2.4 and 2.1 times its
cloud-free Earthshine in red, green and blue.
How bright Earth is as a whole tests the reading of the map's values as
reflectance. With clouds, rendered at phase angles from 0 to 180 degrees and
integrated over them, Earth reflects 0.27 to 0.29 of the sunlight in green
(the Bond albedo), from four sides in July. Without clouds it reflects 0.13 to
0.16. Measured, Earth's Bond albedo is about 0.30 (CERES, over the whole solar
spectrum). The geometric albedo, the full disk's brightness seen from the
Sun's direction, is 0.19 to 0.21 in green here, against 0.43 for the real
Earth, because clouds and the ocean send back toward the Sun more light than a
Lambertian surface does.
Tests (`tests/gpu/clouds.rs`), on the GPU and lavapipe:
- A uniform layer over gray ground, for four reflectances from clear to opaque,
against the atmosphere's tables in f64 at the cloud's height and the
ground's (within 3.3e-4).
- A clear map against no map. Lavapipe agrees to 2.4e-7. The RTX 3060 differs
by up to 6.7e-3 in 0.3 % of pixels, 1.8e-6 on average: its texture filtering
steps by 1/256 between texels, and a coordinate that differs in its last bit
between the two pipelines can land on the next step.
- One opaque cloud with the Sun 10 degrees up, seen from 1000 km straight
above: the cloud and its shadow 28.7 km to the west land within 0.41 and
0.12 px of where they project, 261 px apart.
- The Earthshine above, against the ratio for Earth seen straight down (within
8 %; less in blue, where more of the light from the slant views is the
air's).
Unit tests in `clouds.rs` check the reflectance formula and the mip averaging.
The command-line tests check that a missing map names `scripts/fetch-clouds.sh`,
and that `[appearance] clouds = false` renders without one.
Cost: the map takes 360 MB of GPU memory. It is compiled into the bodies pass
only once set, so frames without clouds cost what they did. With Earth filling
1920 x 1080 at camera C1, the bodies pass on the RTX 3060 goes from 2.4 to 3.1 ms
over mostly clear Egypt, and from 2.5 to 3.7 ms over the cloudy Pacific,
7.2 ms a frame end to end. On lavapipe, the Pacific view goes from 49 to 64 ms.
Earthshine: unchanged (0.045 ms).
Limitations:
- **One height**, and no thickness. Clouds stand neither above the limb nor
above one another, and cast no shadows on each other. Volumetric clouds are
planned for lighting L2.
- **Gray, Lambertian, and not absorbing.** Real clouds reflect more back toward
the Sun and forward along the light, and show a glory and a bright rim at the
terminator that a Lambertian layer does not.
- **No light between the cloud and the ground**: the ground's light reflected
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.
- **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.
### The Moon's surface
Code: `moon.rs`, `shaders/bodies.wgsl`; data from `scripts/fetch-moon.py`. From
@@ -1931,7 +2044,7 @@ Limitations:
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, with the Moon's map scaled by its
phase curve as seen from the target. Earth has no clouds yet.
phase curve as seen from the target. Clouds are Lambertian too.
## Where the Sun and Moon appear
@@ -2103,7 +2216,8 @@ is a run of the script with `--gaia 16`, at twice the size.
past the reach of camera C2's grid
- Non-Lambertian materials (BRDFs), glints, and the full Moon's edge as bright
as its center
- Clouds on Earth
- Clouds as volumes (lighting L2): thickness, the shadows they cast on each
other, and clouds standing above the limb
- Earth's surface finer than Blue Marble's 460 m: mosaics of tens of meters
(Landsat, Sentinel-2) need tiles streamed in as a view needs them
- The atmosphere seen from inside it (a camera below 100 km)