This notebook renders Earth’s solar terminator on a Mapbox map. It fetches Black Marble tiles and uses a WebGL shader to composite the terminator into the alpha channel of the tiles, outputting the result to a custom raster source.
The astronomical calculations are based on Vladimir Agafonkin’s SunCalc library.
How it works
Custom raster source
Mapbox GL JS supports custom raster sources that allow you to programmatically generate tile imagery. By implementing a source with type: "custom" and an async loadTile({ x, y, z }) method, you can intercept tile requests and return custom ImageBitmap data.
This notebook uses a custom source to overlay NASA’s Black Marble imagery on top of a standard base map. For each tile request:
- Fetch the corresponding Black Marble tile from the rsreusser.blackmarble tileset
- Render the terminator mask for that tile’s geographic extent using a WebGL shader
- Composite the night imagery with the terminator, fading pixels to transparent on the day side
- Return the result as an
ImageBitmapto the map renderer
An LRU cache stores fetched tile bitmaps to avoid re-downloading when only the terminator position changes.
CPU/GPU split for sun position
The astronomical calculations are adapted from Vladimir Agafonkin’s SunCalc library. Numerical precision presents a challenge. Computing Julian dates and trigonometric values in 32-bit GPU floats introduces visible errors in terminator placement.
This visualization splits SunCalc between the CPU and GPU, moving as much computation as possible to the GPU. By moving date-dependent calculations to the CPU, the shader only needs to evaluate the spatially-varying parts (coordinate transforms and the final altitude formula), minimizing precision loss.
Controls
Dawn altitude controls where the bright-to-dark transition begins (above the horizon). Twilight altitude controls where it ends (below the horizon). The standard twilight phases are:
- Civil twilight: 0° to -6°
- Nautical twilight: -6° to -12°
- Astronomical twilight: -12° to -18°
Step strength blends between smooth shading and discrete 6° steps corresponding to these twilight phases.