docs: add render diagrams and complete config examples

This commit is contained in:
Richard Zink committed 2026-10-12 21:15:24 +02:00
1 parent b9a77fbaa4
commit d5fb1f12c4
3 files changed
+246 -139

No files matched your search

+90 -34
View File
@@ -23,18 +23,20 @@
* ground basemap style
* orbit flight path (figure eight or straight line)
* fog distance haze
* clouds cloud deck height + per-weather coverage
* clouds cloud deck height, coverage and wind motion
* flights civil aviation layer (aircraft + contrails)
* terrain 3D ground, car lights, settlement lights
* carLights tuning of the vehicle light layer
* lights twilight switching of artificial lights
* atmosphere physical light model + shadow/haze knobs
* stars star catalogue tint and brightness
* planets Keplerian planet points in the night sky
* curvature round-world curvature for terrain, roads, lights and sky paths
* day simulated day cycle or the real sun
*
* WORLD SCALE
* 1 world unit = 1 zoom-11 tile ~ 12.9 km at 48.6 deg N.
* World axes: +X = west, +Y = up, +Z = north (verified against the
* World axes: +X = east, +Y = up, +Z = north (verified against the
* basemap and the star frame). Camera flies a 15-35 km band (y ~ 1.16-2.70).
*
* TIME FORMAT TOKENS (own mini formatter, Moment.js-like names)
@@ -50,11 +52,19 @@ window.CONFIG = {
// Identity and UI
// ------------------------------------------------------------------
theme: 'ash', // 'ash' | 'nord' | 'gruvbox' (see window.THEMES)
language: 'en', // 'en', 'de' - keys of the i18n.js dictionaries
// theme: 'nord'
// theme: 'gruvbox'
language: 'en', // 'en', 'de', 'it', 'es', 'fr', 'ru'
// language: 'de'
timeFormat: 'DD. MMMM, YYYY ‒ HH:mm:SS',
// timeFormat: 'YYYY-MM-DD HH:mm:ss'
// timeFormat: 'dddd, DD. MMMM YYYY HH:mm'
debug: 0, // 1 = debug panel + progress logs in the console
// debug: 1
credits: true, // false = hide the attribution line
// credits: false
units: { temperature: 'C' }, // 'F' for Fahrenheit
// units: { temperature: 'F' }
// ------------------------------------------------------------------
// Rendering budget
@@ -64,14 +74,14 @@ window.CONFIG = {
// and upscaled with image-rendering: pixelated, so it reads as pixel
// art instead of a blurry rescale. The DOM UI stays crisp at any value.
// 1 = native resolution (sharpest, most expensive).
renderScale: 0.5,
renderScale: 0.5, // 1 native, 0.5 pixel-art 2x, 0.25 4x
// Scene frame cap. All motion is time-based, so this only changes
// smoothness, never speed. 0 = free running (vsync).
maxFps: 30,
maxFps: 30, // 0 = free running
// MSAA on the WebGL framebuffer. Costs fill rate, and with renderScale
// below 1 the pixel blocks dominate anyway - set false if the scene is
// GPU bound. Read once at context creation, so a reload is needed.
antialias: true,
antialias: true, // false saves GPU fill rate
// ------------------------------------------------------------------
// Location
@@ -82,6 +92,7 @@ window.CONFIG = {
lat: 48.5667,
lon: 13.4319
// label: 'Passau' // overrides the reverse-geocoded name
// lat: 51.5074, lon: -0.1278 // London example
},
// ------------------------------------------------------------------
@@ -90,8 +101,9 @@ window.CONFIG = {
// false = live Open-Meteo conditions (also used for the theme choice).
// true = cycle sunny -> cloudy -> stormy -> night, useful to compare
// all weather looks without waiting on the API.
weatherSim: false,
weatherSim: false, // true cycles sunny/cloudy/stormy/night
weatherSimInterval: 30000, // ms per weather step when weatherSim is true
// weatherSim: true, weatherSimInterval: 15000
// ------------------------------------------------------------------
// Tiles and caches
@@ -101,15 +113,17 @@ window.CONFIG = {
// ('background-tiles' / store 'tiles') and are never re-fetched once
// cached: a warm cache renders fully offline.
tiles: {
expireDays: null, // e.g. 90 = re-fetch basemap tiles every 90 days
expireDays: null, // null = never expire; e.g. 90 = re-fetch every 90 days
debug: false // true = tile borders + N/S + x/y labels baked
// into the ground texture (orientation debug)
// tiles: { expireDays: 30, debug: true }
},
ground: {
// 'satellite' = ESRI World_Imagery (aerial, no labels)
// 'streets' = ESRI World_Street_Map (with place names)
// Both are cached separately (cache id prefix 'sat/' vs plain).
style: 'satellite'
// style: 'streets'
},
// ------------------------------------------------------------------
@@ -121,6 +135,8 @@ window.CONFIG = {
orbit: {
radiusKm: 60, // lobe tip reach (clamped ~190 km so the
// tips plus the fog dome fit the mosaic)
// radiusKm: 35 // tighter flight
// radiusKm: 120 // wider flight, more terrain visible
clockwise: true, // travel direction along the eight
reorient: true, // false keeps the bearing across crossings
// Vertical bobbing inside the 15-35 km band: centre 25 km, amp is
@@ -135,6 +151,8 @@ window.CONFIG = {
// ------------------------------------------------------------------
fog: {
distanceKm: 120 // fully saturated haze at this range; 0/false = off
// distanceKm: 0 // no distance fog
// distanceKm: 220 // deeper aerial perspective
},
// ------------------------------------------------------------------
@@ -143,7 +161,7 @@ window.CONFIG = {
// World units (1 unit ~ 12.9 km). Keep 'top' below the lowest flight
// altitude so aircraft fly above the deck.
clouds: {
enabled: true,
enabled: true, // false removes the volumetric cloud deck
top: 1.0, // ~12.9 km
bottom: -0.2, // ~-2.6 km (deck base slightly below terrain)
// Coverage per weather level, 0 = clear, 1 = overcast. Only the
@@ -158,9 +176,11 @@ window.CONFIG = {
// bearing. speedScale exaggerates real advection so the motion is
// visible at the world scale (1 unit ~ 12.9 km).
wind: {
speedScale: 80,
minSpeed: 0.004,
maxSpeed: 0.08
speedScale: 80, // 0 = no wind motion, 40 slow, 120 fast
minSpeed: 0.004, // world units/s floor when API wind is calm
maxSpeed: 0.08 // world units/s ceiling for storm winds
// wind: { speedScale: 0 } // static clouds
// wind: { speedScale: 140, maxSpeed: 0.12 } // very visible motion
}
// density: { sunny: 0.05, cloudy: 0.9, stormy: 1.0, night: 0.2 }
},
@@ -199,7 +219,7 @@ window.CONFIG = {
// Paths are Bezier curves resampled to arc length, flown as a full
// profile: climb, cruise, descent, landing, ground hold, new leg.
flights: {
enabled: true,
enabled: true, // false removes aircraft and contrails
altitudeKm: 14, // cruise altitude
climbKm: 100, // climb/descent run to and from cruise
count: 21, // simultaneous aircraft (max 240)
@@ -213,11 +233,12 @@ window.CONFIG = {
wStrip: 1,
// Contrails: contrailChance of the aircraft leaves a trail once
// above contrailStartKm, visible for contrailLifeS seconds.
contrailChance: 1.00,
contrailStartKm: 4,
contrailLifeS: 300,
contrailChance: 1.00, // 0 = no contrails, 1 = every eligible jet
contrailStartKm: 4, // start after this distance from the airport
contrailLifeS: 300, // seconds before a trail disappears
contrailWidthM: 1400, // full trail width
contrailFadeKm: 300, // fully faded at this distance (ramp starts at 35 %)
// contrailChance: 0.35, contrailLifeS: 120 // short sparse trails
// Night contrast: a physically scaled contrail is a faint grey thread
// that disappears at 4x pixel scale, so this is the night share of its
// opacity (0.34 was the old value) and it also drives the gain on the
@@ -243,15 +264,17 @@ window.CONFIG = {
// height field the terrain shadows are cast against.
terrain: {
enabled: true, // false = flat plane (no DEM, no terrain shadows)
// terrain: false // completely disable the 3D ground
exaggeration: 8, // vertical scale (1 = real, nearly invisible here)
edgeFadeTiles: 4, // soft rim at the mosaic border, in tiles (~13 km)
edgeSkirtKm: 800, // coarse outer terrain pulled past the horizon
edgeSkirtRings: 24, // coarse rings in the outer skirt
edgeSkirtNoise: 0.28, // fallback height variation if outer DEM is off
outerDem: {
enabled: true,
enabled: true, // false uses procedural fallback heights
zoom: 7, // reduced-resolution terrarium zoom for the skirt
maxMeters: 2500 // height normalization for skirt colors
// outerDem: { enabled: false }
},
carLights: true, // moving vehicle lights on the real road network
cityLights: true, // settlement lights from OSM place nodes
@@ -264,6 +287,7 @@ window.CONFIG = {
// Roads come from Overpass (motorway/trunk for the A-net, primary/
// secondary for the side layer), cached per grid cell.
carLights: {
// All distances are real metres/km unless the name says Px.
roadWidthM: 24, // real carriageway width of the road line
bandPx: 1.2, // pixel floor of the road line
bandBrightness: 0.10, // road line glow (the points are the main layer)
@@ -284,12 +308,15 @@ window.CONFIG = {
// Japan, Australia, India, southern Africa, ...), 'left'/'right' forces it.
trafficSide: 'auto',
dashM: 620, // mean vehicle spacing on motorways
// (side roads use dashM * 2.8)
// side roads use dashM * 2.4
// dashM: 350 // denser traffic
// dashM: 1200 // sparse traffic
spreadKm: 45, // gaussian sigma around the motorway network
spreadFloor: 0.30, // share that far side roads keep
speed: 1.0, // flow speed multiplier
density: 1.0, // vehicle density multiplier
brightness: 1.3 // vehicle light intensity
// speed: 2.0, density: 0.6, brightness: 1.0
},
// ------------------------------------------------------------------
@@ -300,9 +327,10 @@ window.CONFIG = {
// piece. offDeg +5 deg is about 30 min before sunset here, onDeg -6 deg
// is civil twilight. In the morning the same thresholds switch off again.
lights: {
offDeg: 5,
onDeg: -6,
offDeg: 5, // sun altitude where lights start switching off
onDeg: -6, // sun altitude where lights are fully on
softDeg: 1.2 // width of the individual transition
// offDeg: 8, onDeg: -4, softDeg: 2.0 // earlier, softer twilight
},
// ------------------------------------------------------------------
@@ -325,7 +353,6 @@ window.CONFIG = {
airGain: 0.55, // Rayleigh airlight strength (blue-biased)
physicalSky: true, // Rayleigh sky scattering instead of pure theme gradient
rayleighGain: 8.0, // exposure for the physical sky term
distanceFog: false, // legacy aerial perspective is off
haze: {
enabled: false, // full-screen haze pass causes horizon/sky flicker
heightKm: 100,
@@ -336,12 +363,14 @@ window.CONFIG = {
maxAlpha: 0.55
},
terrainHaze: {
enabled: true,
scaleHeightKm: 8.5,
density: 0.22,
gain: 1.0,
maxAlpha: 0.65,
color: [0.58, 0.64, 0.72]
enabled: true, // terrain-distance based haze on the ground
scaleHeightKm: 8.5, // exponential vertical falloff
density: 0.22, // optical depth per world unit
gain: 1.0, // overall multiplier
maxAlpha: 0.65, // maximum haze opacity
color: [0.58, 0.64, 0.72] // fallback colour; dynamic night tint overrides
// terrainHaze: { enabled: false }
// terrainHaze: { density: 0.35, maxAlpha: 0.80 }
},
airHaze: {
enabled: false, // replaced by stable front haze using terrain distance
@@ -352,27 +381,37 @@ window.CONFIG = {
color: [0.58, 0.64, 0.72]
},
frontHaze: {
enabled: true,
enabled: true, // stable front haze pass using terrain distance
scaleHeightKm: 8.5,
density: 0.22,
gain: 1.0,
maxAlpha: 0.65,
color: [0.58, 0.64, 0.72]
// frontHaze: { enabled: false }
// frontHaze: { density: 0.30, maxAlpha: 0.75 }
},
model: {
enabled: false // legacy full atmosphere model remains off
enabled: false // legacy full-screen atmosphere model
// model: { enabled: true, heightKm: 80, density: 0.25 }
},
hazeResidual: 0.30, // surface colour surviving at the full fog distance
cloudBrightness: 1.0, // cloud albedo (theme hue, brightness from the model)
cloudHaze: 0.22, // share of the ground haze applied to the deck
// cloudBrightness: 1.35 // brighter cloud tops
// cloudHaze: 0.10 // clouds stay cleaner against the haze
// Cloud shadows: the terrain samples the same cloud field as the sky pass.
cloudShadows: true,
cloudShadowDensity: 1.8, // optical depth through the deck
cloudShadowFloor: 0.06, // darkest shade under a thick cloud
cloudShadowAmbient: 0.65, // share of the skylight a deck also blocks
// cloudShadows: false
// cloudShadowDensity: 2.6 // stronger moving cloud shade
// cloudShadowFloor: 0.18 // softer, less contrasty shade
// Terrain self-shadowing over the DEM height field.
terrainShadows: true,
terrainShadowFloor: 0.42, // brightness a fully shadowed slope keeps (0 = black)
// terrainShadows: false
// terrainShadowFloor: 0.25 // deeper ridge shadows
// Optional variants (leave commented out to use the defaults):
// turbidity: 3.0 // hazy, warm, strongly reddened low sun
// moonGain: 1.2 // bright full-moon nights
@@ -388,6 +427,22 @@ window.CONFIG = {
stars: {
tint: 0.10, // 0 = pure white points, 1 = full blackbody colour
brightness: 1.6 // overall glow of the catalogue points
// stars: { tint: 0.35, brightness: 2.2 } // stronger colour and glow
},
// ------------------------------------------------------------------
// Planets
// ------------------------------------------------------------------
// Approximate Keplerian positions for Mercury..Pluto, rendered as
// larger coloured points in the night sky. Positions are geocentric and
// use the same simulated clock as sun/moon/stars.
planets: {
enabled: true,
brightness: 1.0, // 0.5 = subtle, 2.0 = clearly readable
sizeScale: 1.0, // 0.6 = small, 1.4 = prominent
showPluto: true // Pluto is faint; false removes it
// planets: { enabled: false }
// planets: { brightness: 1.6, sizeScale: 1.25, showPluto: false }
},
// ------------------------------------------------------------------
@@ -395,8 +450,10 @@ window.CONFIG = {
// ------------------------------------------------------------------
curvature: {
enabled: true,
earthRadiusKm: 6371,
exaggeration: 4.0
earthRadiusKm: 6371, // physical Earth radius used for the bend
exaggeration: 4.0 // 1 = physically true, 4 = visually readable
// curvature: { enabled: false } // flat world
// curvature: { exaggeration: 2.0 } // gentler horizon drop
},
// ------------------------------------------------------------------
@@ -419,6 +476,7 @@ window.CONFIG = {
// Below the horizon the view holds the moon's azimuth at the horizon.
camera: {
aim: 'off', // 'off' | 'moon'
// aim: 'moon' // look at the moon while flying the path
aimEase: 0.94, // 0 = instant turn, 0.99 = very slow
aimBob: 0.25 // share of the altitude bob kept while aiming
// camera: { aim: 'moon' } // look at the moon
@@ -435,9 +493,7 @@ window.CONFIG = {
day: {
startAt: null, // null = strictly real time
speed: 1 // virtual seconds per real second
// day: { startAt: '2026-10-29T20:56', speed: 1 } // start at a chosen
// // moment, real pace
// day: { startAt: '2026-10-29T20:56', speed: 1440 } // accelerated
// startAt: '2026-10-29T20:56', speed: 1440 // one simulated day per minute
},
// ------------------------------------------------------------------