Atmosphere
This commit is contained in:
1 parent
a3f62301f4
commit
4b1198a351
21 files changed
+2253
-204
No files matched your search
+147
-12
@@ -1012,8 +1012,9 @@ lit) right. It misses some things that are visible in real images:
|
||||
old basalt lava, the "seas" seen with the naked eye) and its bright
|
||||
highlands also differ in albedo by about a factor of two, which from
|
||||
lighting L1 the Moon's map shows.
|
||||
- Earth's atmosphere softens the limb and adds a thin bright band around it
|
||||
(not modeled yet). Here Earth's edge is a sharp line.
|
||||
- Earth's atmosphere softens the limb and adds a thin glowing band around it.
|
||||
At lighting L0 Earth's edge is a sharp line; from L1 the atmosphere is drawn
|
||||
("Earth's atmosphere").
|
||||
|
||||
### Earth's surface
|
||||
|
||||
@@ -1057,12 +1058,8 @@ Two details matter for brightness:
|
||||
those values. A coastline seen up close blends correctly from sea to land.
|
||||
- Blue Marble is surface reflectance with no atmosphere, and open ocean is
|
||||
dark, a few percent. From orbit the ocean looks bright blue because the air
|
||||
above it scatters sunlight toward the camera: Rayleigh scattering, which
|
||||
grows as 1 / wavelength^4, which is also why the sky is blue. Until the
|
||||
atmosphere is modeled, a stand-in adds a reflectance of that shape,
|
||||
0.07 at 450 nm falling to 0.017 at 650 nm (`Appearance::earth_haze`). It
|
||||
brightens and blues the whole lit disk evenly, where the real effect grows
|
||||
toward the limb, where the line of sight crosses more air.
|
||||
above it scatters sunlight toward the camera. The renderer adds that air
|
||||
itself, next.
|
||||
|
||||
The texture's red, green and blue are reflectances in the same three bands a
|
||||
glTF base color uses (see the target model section), folded into the camera's
|
||||
@@ -1073,6 +1070,143 @@ calibrated reflectance product itself, so its values are close but not exact
|
||||
reflectances. A calibrated alternative (MODIS's albedo product) is a possible
|
||||
later refinement.
|
||||
|
||||
### Earth's atmosphere
|
||||
|
||||
Code: `atmosphere.rs`, `shaders/atmosphere.wgsl`, `shaders/bodies.wgsl`.
|
||||
|
||||
At lighting L1 Earth is seen through its atmosphere
|
||||
(`Appearance::earth_atmosphere`, on by default). Air does three things to
|
||||
light passing through it:
|
||||
|
||||
- **Molecules scatter it**, much more at short wavelengths: Rayleigh
|
||||
scattering grows as 1 / wavelength^4, so blue light at 450 nm scatters 3.6
|
||||
times as much as red at 620 nm. Straight up from the ground, air scatters
|
||||
about 10 % of green light (an optical depth of 0.11 at 550 nm) and 21 % of
|
||||
blue (0.24 at 450 nm). That is why the sky is blue and the setting Sun red.
|
||||
- **Aerosols** (dust, sea salt, smoke droplets) scatter colors far more
|
||||
evenly than air does, so they make haze white rather than blue, and mostly
|
||||
forward, within a few tens of degrees of the light's direction. They sit
|
||||
low: half of them in the lowest 0.8 km. Straight up they scatter or absorb
|
||||
about as much light as the air does, an optical depth of 0.12 at 550 nm on
|
||||
average over Earth, and far more over deserts and fires.
|
||||
- **Ozone absorbs** light in a broad band centered near 600 nm (the Chappuis
|
||||
band). From space it matters mainly at the limb, where the line of sight
|
||||
crosses the ozone layer edge on, and tints the glow there.
|
||||
|
||||
What leaves the ground is reduced by the light scattered or absorbed out of
|
||||
it on the way to the camera: the **transmittance**, between 0 and 1. And the
|
||||
air along the line of sight sends sunlight it scatters toward the camera: the
|
||||
**path radiance**, which adds to whatever is behind it. Both grow with the
|
||||
amount of air the line of sight crosses, so the ground looks hazier and bluer
|
||||
toward Earth's edge, where the line of sight is long and slanting. Past the
|
||||
edge the line of sight crosses only air, which glows: the **limb**. There the
|
||||
air is thin enough that the glow is in proportion to the density at the
|
||||
lowest point of the line of sight, so it fades by a factor of e (2.7) for
|
||||
every 8 km of height.
|
||||
|
||||
The ground itself is lit by the sunlight that reaches it, which the air has
|
||||
also dimmed (more at a low Sun, and more in blue, so ground near sunset is lit
|
||||
redder), and by **skylight**: the light the whole sky scatters down, about a
|
||||
tenth of the Sun's in blue with the Sun overhead and less in red. Past the
|
||||
terminator the sky still lights the ground for a while: twilight.
|
||||
|
||||
Light can also scatter more than once, from air to air or off the ground and
|
||||
back. With the Sun high that adds a few tens of percent to the sky's
|
||||
brightness.
|
||||
|
||||
Adding up the scattered light along every line of sight for every pixel would
|
||||
be far too slow. Instead the renderer precomputes tables once, at setup, with
|
||||
the method of Bruneton and Neyret (2008), in the form of Bruneton's 2017
|
||||
implementation and with its atmosphere: what a point at a given height sees
|
||||
looking in a given direction, with the Sun at a given angle, is a function of
|
||||
four numbers (height, view angle from the zenith, Sun angle from the zenith,
|
||||
and the angle between the view and the Sun), so it fits a table. Three tables:
|
||||
|
||||
- the scattered light (4D, stored as a 3D texture of 256 x 128 x 16 texels,
|
||||
Rayleigh and aerosols separately);
|
||||
- the transmittance from any point to the top of the atmosphere (256 x 64),
|
||||
from which the transmittance between any two points follows;
|
||||
- the skylight on the ground (64 x 16).
|
||||
|
||||
Each pixel that sees Earth then reads them about a dozen times: the
|
||||
transmittance to the ground and the light scattered along the way (the light
|
||||
scattered along the whole line of sight, less what lies beyond the ground),
|
||||
and the sunlight and skylight on the ground there.
|
||||
|
||||
Light scattered more than once is approximated as Hillaire (2020) does:
|
||||
assume the light arriving at a point after one scattering comes equally from
|
||||
every direction and is the same at nearby points. Then all the higher orders
|
||||
together follow from a small table per height and Sun angle, instead of being
|
||||
computed order by order.
|
||||
|
||||
The air is Bruneton's, with more aerosols: Rayleigh scattering falling with
|
||||
an 8 km scale height; aerosols with a 1.2 km scale height, an optical depth of
|
||||
0.12 at 550 nm (the global annual mean of Kinne et al.'s 2013 climatology)
|
||||
falling as wavelength^-1.3, 90 % of it scattering, with Bruneton's forward
|
||||
phase function (asymmetry 0.8); and 300 Dobson units of ozone between 10 and
|
||||
40 km. Bruneton's aerosol depth of 0.0053 is air cleaner than almost anywhere
|
||||
on Earth: with it the ground looked bluer and sharper toward the limb than it
|
||||
should. The top of the atmosphere is set
|
||||
100 km up. Earth is the sphere of its equatorial radius, in axes stretched
|
||||
along the polar axis, where its ellipsoid is that sphere (heights are off by
|
||||
at most 0.3 % near the poles).
|
||||
|
||||
The tables are computed every 20 nm and folded into the camera's channels
|
||||
with sunlight and each channel's QE, like every other spectrum
|
||||
("Folding spectra into per-channel constants"). The scattered light folds
|
||||
exactly. Transmittance does not: a channel whose band spans very different
|
||||
transmittances gets their average weighted by sunlight, which is wrong when
|
||||
the light passing through is a different color from sunlight. It matters most
|
||||
for blue light along long, grazing paths. Setup takes 0.25 s on the 24-core
|
||||
desktop CPU these numbers come from, and 1.1 s on four of its cores.
|
||||
|
||||
Tests: the tables against direct integrals, in `atmosphere.rs` (the amount of
|
||||
air from the ground straight up within 1e-4 of the scale height, Rayleigh
|
||||
scattered light within 3.4e-4, aerosols within 0.31 %); the shaders against
|
||||
the tables, on the GPU and lavapipe (`tests/gpu/atmosphere.rs`): the ground
|
||||
seen at 60 degrees from its zenith and the limb at 40 and 50 km, within
|
||||
2.5e-4. The limb fades by 3.38 over those 10 km, against 3.49 for the density
|
||||
alone; the air between takes the rest.
|
||||
|
||||
Checked against a real satellite: GOES-16's full disk of 2024-07-01 at
|
||||
15:00 UTC, in its blue (470 nm) and red (640 nm) bands, over 640,000 cloud-free
|
||||
ocean pixels (NOAA's cloud mask), away from the Sun's glint. Over ocean,
|
||||
which is dark, most of the light the satellite measures comes from the air,
|
||||
and GOES sees the sea from straight above out to its limb: the same slanting
|
||||
paths through the air as a camera in low orbit looking toward the horizon.
|
||||
The tables, evaluated at each pixel's angles with Blue Marble's ocean color
|
||||
and channels shaped like GOES's bands, against the measured reflectance
|
||||
(the median in each band of viewing angle from the zenith):
|
||||
|
||||
| Viewing angle | GOES blue | Model | Clean air | GOES red | Model | Clean air |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 20-40 degrees | 0.097 | 0.090 | 0.077 | 0.029 | 0.030 | 0.023 |
|
||||
| 55-65 | 0.146 | 0.145 | 0.123 | 0.044 | 0.051 | 0.037 |
|
||||
| 70-75 | 0.205 | 0.191 | 0.169 | 0.076 | 0.071 | 0.056 |
|
||||
| 78-81 | 0.249 | 0.239 | 0.219 | 0.093 | 0.095 | 0.078 |
|
||||
| 81-84 | 0.267 | 0.266 | 0.246 | 0.104 | 0.110 | 0.092 |
|
||||
|
||||
The model is within 7 % in blue (low: Blue Marble's ocean is darker in blue
|
||||
than real open ocean) and 15 % in red out to 84 degrees, and the haze grows
|
||||
toward the limb as measured. With Bruneton's clean air ("Clean air") it is 8
|
||||
to 29 % too dark. NOAA's own retrieval put the aerosols' optical depth over
|
||||
these pixels at 0.13 (median), close to the 0.12 the model assumes.
|
||||
|
||||
On the RTX 3060 the atmosphere adds 0.8 to 1.0 ms to the bodies pass at
|
||||
1920 x 1080 with camera C1's 2 x 2 supersampling, and 14 to 27 ms on lavapipe.
|
||||
|
||||
Limitations:
|
||||
|
||||
- **The camera must be above the atmosphere**, over 100 km up; below that a
|
||||
frame is refused.
|
||||
- **Sunlight reaching the target** through the atmosphere, and the Sun and
|
||||
Moon seen through it at the limb, are not dimmed or reddened yet.
|
||||
- **Clouds** are not drawn: Blue Marble is a cloud-free mosaic.
|
||||
- **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.
|
||||
|
||||
### The Moon's surface
|
||||
|
||||
Code: `moon.rs`, `shaders/bodies.wgsl`; data from `scripts/fetch-moon.py`. From
|
||||
@@ -1531,7 +1665,8 @@ arrives from Earth and the Moon on a surface facing any direction:
|
||||
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
|
||||
the cosine of the Sun's angle there, dark on the night side, and at
|
||||
lighting L1 seen through the atmosphere. 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
|
||||
@@ -1588,8 +1723,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 or atmosphere yet
|
||||
beyond the stand-in haze.
|
||||
phase curve as seen from the target. Earth has no clouds yet.
|
||||
|
||||
## Where the Sun and Moon appear
|
||||
|
||||
@@ -1762,5 +1896,6 @@ is a run of the script with `--gaia 16`, at twice the size.
|
||||
- Non-Lambertian materials (BRDFs), glints, and the full Moon's edge as bright
|
||||
as its center
|
||||
- Clouds on Earth
|
||||
- Earth's atmosphere: scattering, the bright limb
|
||||
- Sunlight through Earth's atmosphere onto targets, and the Sun and Moon seen
|
||||
through it; the atmosphere seen from inside it (a camera below 100 km)
|
||||
- Motion blur, rolling shutter, stray light
|
||||
Reference in new issue
Block a user