sharper earth map

This commit is contained in:
connor committed 2026-10-18 00:05:42 -04:00
1 parent 4b1198a351
commit 8c0a1439d7
18 files changed
+1426 -46

No files matched your search

+40 -6
View File
@@ -1033,21 +1033,53 @@ point's geodetic latitude and longitude from the ellipsoid's normal there, in
Earth-fixed axes, and reads the image at that place. Earth's orientation from
the scene turns the continents with the epoch.
The full image is 500 m per pixel at the equator, resized to 660 m to fit the
largest texture lavapipe allows (16384 x 8192). Whether that is fine or coarse
depends on the view:
The image comes in two sizes:
- The global map, always there: NASA's 21600 x 10800 image (1 arcminute,
1.85 km per pixel at the equator), resized to 16384 x 8192 (2.45 km), the
largest texture lavapipe allows.
- A sharp map, optional: NASA's 86400 x 43200 image (15 arcseconds, 460 m),
made once per month by `scripts/fetch-earth.sh --sharp` (below).
Whether a map is fine or coarse depends on the view:
- From low orbit looking straight down, a camera pixel of the example camera
covers 77 m of ground, so each texture pixel spans about 8 image pixels and
looks soft.
covers 77 m of ground. A texel of the global map spans 32 image pixels and
looks blurred; one of the sharp map, 6.
- From geostationary orbit, a camera pixel covers about 4 km, so each image
pixel averages about 35 texture pixels (6 x 6).
pixel averages about 2 x 2 texels of the global map.
For the second case the texture is stored with mipmaps: copies at half, a
quarter, an eighth of the size, and so on. The GPU reads from the copy whose
pixels best match the image pixel, so a far view shows the true average color
of a region rather than a shimmering sample of individual texture pixels.
The sharp map is too large for one texture on either device (lavapipe's limit
is 16384 on a side) and for one allocation on lavapipe (2 GB), and 30 GB as
16-bit floating point. So it is cut into 8 x 4 square tiles of 10800 texels,
each stored with a border of 4 texels copied from its neighbors, so that
blending near a tile's edge reads the right texels without a second tile, and
compressed to BC6H: blocks of 4 x 4 texels in 16 bytes, which the GPU decodes
as it reads them. BC6H keeps linear values with about the precision of 16-bit
floating point; on Blue Marble's July map around Sinai, 99 % of pixels are
within 1 to 2.5 % of the uncompressed value and the mean within 0.1 %. Three
mipmap levels are stored (460 m, 930 m, 1.85 km), 4.9 GB in all, in four
texture arrays of 8 tiles. A pixel reads the sharp map where it covers less
ground than the coarsest level's texels, the global map beyond, and the two
blended across half a level so the change does not show.
Its cost on the RTX 3060: 0.1 to 0.2 ms more in the bodies pass where it is
read, and 1.6 s more setup to upload it. On lavapipe, which decodes BC6H in
software, about 100 ms more in the bodies pass where it is read and 5 s more
setup, with 8 GB of memory at its peak. From geostationary orbit it is not
read, and costs nothing per frame.
The GPU and lavapipe choose mipmap levels and blend texels slightly
differently, so a textured Earth differs between them by about 1 DN on
average at lighting L1 and camera C1 (0.8 DN with the global map alone,
1.3 DN with the sharp map; 2.7 DN before the atmosphere, which lowers the
contrast). The tests of the maps compare each device with itself.
Two details matter for brightness:
- Averaging has to happen on reflectance, not on the encoded values image files
@@ -1896,6 +1928,8 @@ 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 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
- 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