Compare commits

...
68 Commits
Author SHA1 Message Date
Richard Zink af6b63d756 config: set renderScale to 0.33 2026-10-14 10:50:35 +02:00
Richard Zink 8a4884a377 fix: align sun altitude with sunrise sunset 2026-10-14 07:48:52 +02:00
Richard Zink e1343fdf11 config: set car density to 0.225 2026-10-14 07:14:54 +02:00
Richard Zink 3bc6fa4a3a config: raise car density to 0.30 2026-10-14 07:13:24 +02:00
Richard Zink 1ceb92f2c8 config: increase car density and reduce spacing 2026-10-14 07:12:15 +02:00
Richard Zink 7ccdc9929d feat: make car count follow time profile 2026-10-14 07:06:44 +02:00
Richard Zink 07317ba8e5 config: restore cloud horizon softness 2026-10-14 06:59:13 +02:00
Richard Zink a29ce1e914 test: reduce cloud horizon softness 2026-10-14 06:57:29 +02:00
Richard Zink ad26683384 test: disable cloud near fade 2026-10-14 06:54:36 +02:00
Richard Zink 278b1b957f fix: reduce cloud near fade bubble 2026-10-14 06:52:48 +02:00
Richard Zink fc7868cdc5 config: reduce aircraft count to 6 2026-10-14 06:45:27 +02:00
Richard Zink 9e2c7d1207 config: lower rain cloud coverage and render scale 2026-10-14 06:36:21 +02:00
Richard Zink 5deab893da config: reduce car density and spacing 2026-10-13 22:07:20 +02:00
Richard Zink 121b80b117 revert: cloud raymarch LOD 2026-10-13 22:00:14 +02:00
Richard Zink b906986718 perf: add distance-dependent terrain mesh LOD 2026-10-13 21:53:16 +02:00
Richard Zink cf41b72133 perf: start cloud raymarch at 48 samples 2026-10-13 21:34:12 +02:00
Richard Zink 06ad6db900 perf: distance-adaptive cloud raymarch 2026-10-13 21:33:29 +02:00
Richard Zink e14f938252 docs: update performance and cloud configuration 2026-10-13 20:49:38 +02:00
Richard Zink 3e5406dc1d config: reduce car density to 5% 2026-10-13 20:40:40 +02:00
Richard Zink 2f67eeabd3 config: native render scale, more cars and flights 2026-10-13 20:39:17 +02:00
Richard Zink 5364348b21 perf: reduce terrain shadow samples 2026-10-13 20:36:33 +02:00
Richard Zink 96161b1f9e perf: reduce cloud shadow samples 2026-10-13 20:36:12 +02:00
Richard Zink 99ca1b069c perf: reduce cloud noise octaves 2026-10-13 20:35:23 +02:00
Richard Zink b4d44079ea perf: adaptive cloud march length 2026-10-13 20:27:38 +02:00
Richard Zink 30c5b4eb7c perf: reduce haze column samples 2026-10-13 20:26:26 +02:00
Richard Zink 8ea8316b19 perf: skip terrain distance pass when unused 2026-10-13 20:24:37 +02:00
Richard Zink d4eabfa738 perf: reduce cloud march steps 2026-10-13 20:24:13 +02:00
Richard Zink f3d66c3e9d perf: lower render scale and cloud march cap 2026-10-13 20:23:21 +02:00
Richard Zink f8580e595a feat: soft cloud layer edges 2026-10-13 20:16:46 +02:00
Richard Zink e86819457c feat: soft cloud layer edges 2026-10-13 20:11:07 +02:00
Richard Zink 3db36bba58 Revert "config: test without terrain haze"
This reverts commit f4eb826c3a.
2026-10-13 20:01:48 +02:00
Richard Zink 5c2eb857bb Revert "config: test without front haze"
This reverts commit 4bdf5ac540.
2026-10-13 20:01:48 +02:00
Richard Zink 4bdf5ac540 config: test without front haze 2026-10-13 16:08:26 +02:00
Richard Zink f4eb826c3a config: test without terrain haze 2026-10-13 15:13:03 +02:00
Richard Zink 4cd8b57752 Revert "feat: wait for terrain before drawing clouds"
This reverts commit 8cca47f86e.
2026-10-13 14:59:44 +02:00
Richard Zink f8c17a0980 Revert "config: test without front haze"
This reverts commit bebfd64902.
2026-10-13 14:57:45 +02:00
Richard Zink 31162c88e0 Revert "config: reduce far cloud softening"
This reverts commit 6bedc2c95c.
2026-10-13 14:57:45 +02:00
Richard Zink 2f1bee9f25 Revert "fix: soften cloud march edge"
This reverts commit 8884a77f7d.
2026-10-13 14:57:45 +02:00
Richard Zink d08c193a5a Revert "config: lower cloud deck and reduce near fade"
This reverts commit 1381b90e73.
2026-10-13 14:57:45 +02:00
Richard Zink b3a34c654c Revert "config: test sea-level cloud deck"
This reverts commit 238cc1d7e8.
2026-10-13 14:57:45 +02:00
Richard Zink 238cc1d7e8 config: test sea-level cloud deck 2026-10-13 14:55:16 +02:00
Richard Zink 1381b90e73 config: lower cloud deck and reduce near fade 2026-10-13 14:51:47 +02:00
Richard Zink 8884a77f7d fix: soften cloud march edge 2026-10-13 14:48:01 +02:00
Richard Zink 6bedc2c95c config: reduce far cloud softening 2026-10-13 14:46:06 +02:00
Richard Zink bebfd64902 config: test without front haze 2026-10-13 14:40:51 +02:00
Richard Zink 5cfd9c0bc3 Revert "config: test without terrain edge skirt"
This reverts commit 54c2759fa2.
2026-10-13 14:30:46 +02:00
Richard Zink 54c2759fa2 config: test without terrain edge skirt 2026-10-13 14:30:14 +02:00
Richard Zink 1e582c1f7f config: allow clouds in front of terrain 2026-10-13 14:28:39 +02:00
Richard Zink 0ddaa80643 fix: clip cloud rays at terrain distance 2026-10-13 14:25:49 +02:00
Richard Zink 8cca47f86e feat: wait for terrain before drawing clouds 2026-10-13 14:21:22 +02:00
Richard Zink 2afc0b2545 Revert "feat: terrain-following cloud base"
This reverts commit 3e17279499.
2026-10-13 14:18:42 +02:00
Richard Zink 3e17279499 feat: terrain-following cloud base 2026-10-13 14:16:34 +02:00
Richard Zink c02a198f3f fix: fall back to direct tile URLs on proxy errors 2026-10-13 11:14:45 +02:00
Richard Zink 5ce027fd5d config: disable overpass proxy probe by default 2026-10-13 11:12:46 +02:00
Richard Zink c0c612c0cc fix: use relative proxy paths under subpath 2026-10-13 11:02:43 +02:00
Richard Zink d91858addc config: use German date-only clock 2026-10-13 10:04:55 +02:00
Richard Zink 17395ebf7b ui: hide info panel scrollbar 2026-10-13 10:03:07 +02:00
Richard Zink 8ed3fcc7fc ui: shrink info clock 2026-10-13 10:02:04 +02:00
Richard Zink d911e1b5ee config: disable credits 2026-10-13 09:07:28 +02:00
Richard Zink 33d89683ef clouds: lower deck and fade near-camera cloud clipping 2026-10-13 08:47:56 +02:00
Richard Zink 6f19b34900 flights: draw two narrow engine contrails and raise beacon 2026-10-13 08:42:37 +02:00
Richard Zink 6b375ea983 sun: add configurable warm corona glow 2026-10-13 08:33:03 +02:00
Richard Zink 8f31ff8839 sun: halve disc size and add brightness gain 2026-10-13 08:30:41 +02:00
Richard Zink b5c0030192 config: return to real time and disable debug simulations 2026-10-13 08:28:24 +02:00
Richard Zink 86c72c2160 meteor showers: test with 100 active debug meteors 2026-10-13 08:23:19 +02:00
Richard Zink 36a8493b27 meteor showers: use gl.canvas for meteor point size 2026-10-13 08:20:03 +02:00
Richard Zink 4fcaa99969 config: set day start time to 07:05 2026-10-13 08:19:26 +02:00
Richard Zink 0f22aad650 meteor showers: add debug shower and known radiant streaks 2026-10-13 08:10:55 +02:00
5 changed files with 893 additions and 155 deletions

No files matched your search

+1
View File
@@ -1 +1,2 @@
background-standalone.html background-standalone.html
Screenshot*.png
+41 -8
View File
@@ -7,9 +7,10 @@ dropped into an iframe or kiosk browser and left running.
## Features ## Features
- **WebGL flight scene** (`vendor/clouds3d.js`): a 3D terrain mesh built from - **WebGL flight scene** (`vendor/clouds3d.js`): a 3D terrain mesh built from
real elevation data (Copernicus DEM), a raymarched volumetric cloud deck, real elevation data (Copernicus DEM), a raymarched volumetric cloud deck with
optional round-world curvature, and a figure-eight flight path around the soft layer edges and adaptive march length, optional round-world curvature,
configured location with a vertical bob inside the 15-35 km flight band. and a figure-eight flight path around the configured location with a vertical
bob inside the 15-35 km flight band.
- **One physical light model** shared by sky, clouds, contrails, aircraft and - **One physical light model** shared by sky, clouds, contrails, aircraft and
ground: direct beam through a Kasten-Young air mass with Rayleigh, ozone and ground: direct beam through a Kasten-Young air mass with Rayleigh, ozone and
aerosol extinction, diffuse skylight, moonlight, a starlight floor and aerial aerosol extinction, diffuse skylight, moonlight, a starlight floor and aerial
@@ -129,13 +130,13 @@ flowchart TD
F --> G[Sky pass: gradient, stars, Milky Way, sun, moon] F --> G[Sky pass: gradient, stars, Milky Way, sun, moon]
G --> H[Star catalogue points] G --> H[Star catalogue points]
H --> I[Planet points] H --> I[Planet points]
G --> J[Terrain distance pass] G --> J[Terrain distance pass, only when needed]
J --> K[Terrain mesh pass] J --> K[Terrain mesh pass]
K --> L[City lights] K --> L[City lights]
L --> M[Car lights] L --> M[Car lights]
M --> N[Optional atmosphere model] M --> N[Optional atmosphere model]
N --> O[Front haze] N --> O[Front haze]
O --> P[Cloud raymarch] O --> P[Cloud raymarch, soft edges and adaptive march]
P --> Q[Aircraft] P --> Q[Aircraft]
Q --> R[Contrails] Q --> R[Contrails]
``` ```
@@ -252,16 +253,16 @@ Groups:
| --- | --- | | --- | --- |
| `theme`, `language`, `timeFormat`, `units`, `credits` | palette, UI language, clock format, °C/°F, attribution line | | `theme`, `language`, `timeFormat`, `units`, `credits` | palette, UI language, clock format, °C/°F, attribution line |
| `debug` | debug panel (weather, shader counters, theme palette and lighting) | | `debug` | debug panel (weather, shader counters, theme palette and lighting) |
| `renderScale`, `maxFps` | internal 3D resolution and frame cap | | `renderScale`, `antialias`, `maxFps`, `performance` | internal 3D resolution, MSAA, frame cap and adaptive cloud-march quality |
| `location` | `lat`/`lon` (+ optional `label`) - everything geographic | | `location` | `lat`/`lon` (+ optional `label`) - everything geographic |
| `weatherSim`, `weatherSimInterval` | ignore the API and cycle the weather looks | | `weatherSim`, `weatherSimInterval` | ignore the API and cycle the weather looks |
| `tiles` | basemap re-fetch interval (`expireDays`), tile-border debug overlay | | `tiles` | basemap re-fetch interval (`expireDays`), tile-border debug overlay |
| `ground.style` | `'satellite'` (ESRI World_Imagery) or `'streets'` (ESRI World_Street_Map) | | `ground.style` | `'satellite'` (ESRI World_Imagery) or `'streets'` (ESRI World_Street_Map) |
| `orbit` | figure-eight path, `radiusKm`, direction, reorientation, `altBob` | | `orbit` | figure-eight path, `radiusKm`, direction, reorientation, `altBob` |
| `fog.distanceKm` | distance haze (0/false = off) | | `fog.distanceKm` | distance haze (0/false = off) |
| `clouds` | deck height (`top`/`bottom` in world units), `density` per weather level, and `wind` motion from Open-Meteo | | `clouds` | deck height (`top`/`bottom` in world units), `density` per weather level, `wind` motion, soft edge/horizon fading, `maxMarchUnits` and `terrainOcclusion` |
| `flights` | aircraft count, altitudes, speeds, destination weights, contrails, night strobes | | `flights` | aircraft count, altitudes, speeds, destination weights, contrails, night strobes |
| `terrain` | DEM mesh, `exaggeration`, edge fade/skirt, `outerDem`, `carLights`, `cityLights`, `wireframe` | | `terrain` | DEM mesh, `exaggeration`, edge fade/skirt, `outerDem`, distance-dependent `lod`, `carLights`, `cityLights`, `wireframe` |
| `carLights` | road width, light sizes, lane separation, traffic range/fade, `trafficSide`, spacing, speed, density, brightness | | `carLights` | road width, light sizes, lane separation, traffic range/fade, `trafficSide`, spacing, speed, density, brightness |
| `lights` | twilight switching window of every artificial light (`offDeg`, `onDeg`, `softDeg`) | | `lights` | twilight switching window of every artificial light (`offDeg`, `onDeg`, `softDeg`) |
| `atmosphere` | turbidity, moon/star gains, night floor, albedo/sky/air gains, haze blocks, cloud albedo/haze, cloud shadows, terrain shadows | | `atmosphere` | turbidity, moon/star gains, night floor, albedo/sky/air gains, haze blocks, cloud albedo/haze, cloud shadows, terrain shadows |
@@ -280,6 +281,38 @@ Groups:
(`y ≈ 1.16-2.70`). Cloud deck heights, fog distance and orbit radius are all (`y ≈ 1.16-2.70`). Cloud deck heights, fog distance and orbit radius are all
expressed in these units or in km where noted. expressed in these units or in km where noted.
### Performance
`CONFIG.performance` controls adaptive cloud raymarching:
```javascript
performance: {
adaptiveCloudMarch: true,
lowFps: 24,
highFps: 35,
minCloudMarchUnits: 45
}
```
When the debug FPS drops below `lowFps`, the cloud march is shortened. When it
stays above `highFps`, the march is restored toward `CONFIG.clouds.maxMarchUnits`.
Other main performance knobs:
- `renderScale`: lower internal 3D resolution.
- `antialias: false`: disables MSAA.
- `maxFps`: caps the animation loop.
- `clouds.maxMarchUnits`: maximum cloud raymarch length.
- `clouds.softEdges`, `edgeSoftness`, `horizonSoftness`: soft cloud edges;
disabling `softEdges` restores the old hard shell behaviour.
- `terrain.lod`: distance-dependent terrain mesh LOD; fine near the centre,
coarser toward the border. Set `terrain.lod.enabled: false` for the old
uniform mesh grid.
- `atmosphere.cloudShadows` and `atmosphere.terrainShadows`: disable if the
scene is GPU-bound.
- `flights.count`, `flights.contrailChance`, `carLights.density`,
`emergencyVehicles.count`: reduce scene-object density.
### Themes and theme lighting ### Themes and theme lighting
A theme is a stylesheet plus an optional lighting block: A theme is a stylesheet plus an optional lighting block:
+21 -9
View File
@@ -208,6 +208,11 @@
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
align-items: stretch; align-items: stretch;
scrollbar-width: none;
}
#info-panel::-webkit-scrollbar {
display: none;
} }
@media (orientation: portrait) and (max-width: 700px) { @media (orientation: portrait) and (max-width: 700px) {
@@ -216,15 +221,15 @@
} }
} }
#analog-clock { #analog-clock {
width: 100%; width: 78%;
height: auto; height: auto;
margin: 0 auto 0.4vh auto; margin: 0 auto 0.35vh auto;
display: block; display: block;
flex-shrink: 0; flex-shrink: 0;
} }
#digital-clock { #digital-clock {
text-align: center; text-align: center;
font-size: 1.3em; font-size: 1.2em;
letter-spacing: 0.12em; letter-spacing: 0.12em;
margin-bottom: 0.6vh; margin-bottom: 0.6vh;
padding-bottom: 0.5vh; padding-bottom: 0.5vh;
@@ -679,6 +684,11 @@ window.addEventListener('resize', scheduleFitInfoPanel);
var SITE_LAT = (window.CONFIG && window.CONFIG.location && window.CONFIG.location.lat) || 51.5074; var SITE_LAT = (window.CONFIG && window.CONFIG.location && window.CONFIG.location.lat) || 51.5074;
var SITE_LON = (window.CONFIG && window.CONFIG.location && window.CONFIG.location.lon) || -0.1278; var SITE_LON = (window.CONFIG && window.CONFIG.location && window.CONFIG.location.lon) || -0.1278;
// SunCalc.getPosition returns the geometric centre altitude. The
// scene's sunrise/sunset times use the standard apparent upper-limb
// altitude (-0.833 deg: refraction + solar semidiameter), so the
// lighting altitude is shifted by the same amount.
var SUN_HORIZON_CORR_RAD = 0.833 * Math.PI / 180;
var realDayProgress = 0; var realDayProgress = 0;
@@ -918,14 +928,15 @@ window.sunPalettes = [
function getColor(t) { function getColor(t) {
var now = sceneNow(); var now = sceneNow();
var sunPos = SunCalc.getPosition(now, SITE_LAT, SITE_LON); var sunPos = SunCalc.getPosition(now, SITE_LAT, SITE_LON);
var sunAlt = sunPos.altitude + SUN_HORIZON_CORR_RAD;
var moonIllum = SunCalc.getMoonIllumination(now); var moonIllum = SunCalc.getMoonIllumination(now);
// The day palette covers sunAlt down to sunPalettes[0].alt // The day palette covers sunAlt down to sunPalettes[0].alt
// (-pi/2, deep below horizon). Only below that do we hand off // (-pi/2, deep below horizon). Only below that do we hand off
// to the moon-based night palette. This makes twilight a // to the moon-based night palette. This makes twilight a
// smooth transition through the day palette entries. // smooth transition through the day palette entries.
if (sunPos.altitude > window.sunPalettes[0].alt) { if (sunAlt > window.sunPalettes[0].alt) {
return getDayColor(sunPos.altitude); return getDayColor(sunAlt);
} else { } else {
return getNightColor(moonIllum); return getNightColor(moonIllum);
} }
@@ -1981,7 +1992,8 @@ window.weatherThemes = {
// Sun altitude in radians. Negative = below horizon (night). // Sun altitude in radians. Negative = below horizon (night).
var _sunNow = sceneNow(); var _sunNow = sceneNow();
var _sunPos = SunCalc.getPosition(_sunNow, SITE_LAT, SITE_LON); var _sunPos = SunCalc.getPosition(_sunNow, SITE_LAT, SITE_LON);
window.__currentSunAlt = _sunPos.altitude; var _sunAlt = _sunPos.altitude + SUN_HORIZON_CORR_RAD;
window.__currentSunAlt = _sunAlt;
window.__currentSceneDate = _sunNow; window.__currentSceneDate = _sunNow;
window.__flightDow = _sunNow.getDay(); window.__flightDow = _sunNow.getDay();
// Unit vector towards the sun in world space. SunCalc azimuth // Unit vector towards the sun in world space. SunCalc azimuth
@@ -1990,9 +2002,9 @@ window.weatherThemes = {
// World frame: +X = west, +Z = north, +Y = up -> east is -X. // World frame: +X = west, +Z = north, +Y = up -> east is -X.
var _sunBearingR = _sunPos.azimuth + Math.PI; var _sunBearingR = _sunPos.azimuth + Math.PI;
window.__currentSunDir = [ window.__currentSunDir = [
-Math.cos(_sunPos.altitude) * Math.sin(_sunBearingR), -Math.cos(_sunAlt) * Math.sin(_sunBearingR),
Math.sin(_sunPos.altitude), Math.sin(_sunAlt),
Math.cos(_sunPos.altitude) * Math.cos(_sunBearingR) Math.cos(_sunAlt) * Math.cos(_sunBearingR)
]; ];
// ---- Local sidereal time ------------------------------------- // ---- Local sidereal time -------------------------------------
// Same formula SunCalc uses internally (Meeus): GMST in degrees // Same formula SunCalc uses internally (Meeus): GMST in degrees
+136 -18
View File
@@ -54,14 +54,22 @@ window.CONFIG = {
theme: 'ash', // 'ash' | 'nord' | 'gruvbox' (see window.THEMES) theme: 'ash', // 'ash' | 'nord' | 'gruvbox' (see window.THEMES)
// theme: 'nord' // theme: 'nord'
// theme: 'gruvbox' // theme: 'gruvbox'
language: 'en', // 'en', 'de', 'it', 'es', 'fr', 'ru' language: 'de', // 'en', 'de', 'it', 'es', 'fr', 'ru'
// language: 'de' // language: 'de'
timeFormat: 'DD. MMMM, YYYY ‒ HH:mm:SS', timeFormat: 'DD. MMMM YYYY',
// timeFormat: 'YYYY-MM-DD HH:mm:ss' // timeFormat: 'YYYY-MM-DD HH:mm:ss'
// timeFormat: 'dddd, DD. MMMM YYYY HH:mm' // timeFormat: 'dddd, DD. MMMM YYYY HH:mm'
debug: 0, // 1 = debug panel + progress logs in the console debug: 0, // 1 = debug panel + progress logs in the console
// debug: 1 // debug: 1
credits: true, // false = hide the attribution line credits: false, // attribution line hidden
// Optional same-origin Overpass proxy probe. The public Overpass mirrors
// work directly from the browser; keep this false unless the background
// nginx proxy is known to be reachable and you want cached same-origin calls.
overpass: {
useProxy: false, // true = probe /overpass/... and use it when available
// useProxy: true
},
// credits: false // credits: false
units: { temperature: 'C' }, // 'F' for Fahrenheit units: { temperature: 'C' }, // 'F' for Fahrenheit
// units: { temperature: 'F' } // units: { temperature: 'F' }
@@ -74,14 +82,26 @@ window.CONFIG = {
// and upscaled with image-rendering: pixelated, so it reads as pixel // 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. // art instead of a blurry rescale. The DOM UI stays crisp at any value.
// 1 = native resolution (sharpest, most expensive). // 1 = native resolution (sharpest, most expensive).
renderScale: 0.5, // 1 native, 0.5 pixel-art 2x, 0.25 4x renderScale: 0.33, // 1 native, 0.5 pixel-art 2x, 0.4/0.33/0.25 cheaper
// Scene frame cap. All motion is time-based, so this only changes // Scene frame cap. All motion is time-based, so this only changes
// smoothness, never speed. 0 = free running (vsync). // smoothness, never speed. 0 = free running (vsync).
maxFps: 30, // 0 = free running maxFps: 30, // 0 = free running
// MSAA on the WebGL framebuffer. Costs fill rate, and with renderScale // MSAA on the WebGL framebuffer. Costs fill rate, and with renderScale
// below 1 the pixel blocks dominate anyway - set false if the scene is // 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. // GPU bound. Read once at context creation, so a reload is needed.
antialias: true, // false saves GPU fill rate antialias: false, // false saves GPU fill rate
// ------------------------------------------------------------------
// Performance
// ------------------------------------------------------------------
// Adaptive cloud raymarch: shortens the cloud march when the debug FPS
// drops, and lengthens it again when the scene stays comfortably fast.
performance: {
adaptiveCloudMarch: true,
lowFps: 24, // reduce march below this FPS
highFps: 35, // restore march above this FPS
minCloudMarchUnits: 45 // never shorten below this raymarch length
},
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// Location // Location
@@ -101,7 +121,7 @@ window.CONFIG = {
// false = live Open-Meteo conditions (also used for the theme choice). // false = live Open-Meteo conditions (also used for the theme choice).
// true = cycle sunny -> cloudy -> stormy -> night, useful to compare // true = cycle sunny -> cloudy -> stormy -> night, useful to compare
// all weather looks without waiting on the API. // all weather looks without waiting on the API.
weatherSim: true, // test mode: fixed sunny weather weatherSim: false, // real Open-Meteo weather
weatherSimInterval: 15000, // ms per weather step when weatherSim is true weatherSimInterval: 15000, // ms per weather step when weatherSim is true
// weatherSim: false, weatherSimInterval: 30000 // weatherSim: false, weatherSimInterval: 30000
// Synthetic weather states used by weatherSim. Each state sets theme, // Synthetic weather states used by weatherSim. Each state sets theme,
@@ -147,6 +167,58 @@ window.CONFIG = {
// emergencyVehicles: { colorVariation: 0.25, ledColor: [0.02, 0.18, 1.0], halogenColor: [0.70, 0.82, 1.0] } // emergencyVehicles: { colorVariation: 0.25, ledColor: [0.02, 0.18, 1.0], halogenColor: [0.70, 0.82, 1.0] }
}, },
// ------------------------------------------------------------------
// Meteor showers
// ------------------------------------------------------------------
// Known meteor showers are rendered as short night-sky streaks whose
// backward extension points toward the shower radiant. The debug shower
// is a temporary test shower for a fixed local start time.
meteorShowers: {
enabled: true,
brightness: 1.0,
maxActive: 12,
rate: 0.25, // meteors per second across all active showers
speedDegPerSec: 14, // apparent angular speed
lengthDeg: 18, // trail length in degrees
trailPoints: 14, // point sprites per trail
pointSize: 10, // base point size in pixels
nightOnly: true,
colors: [
[1.00, 0.96, 0.88],
[0.72, 1.00, 0.86],
[1.00, 0.72, 0.42]
],
debug: {
enabled: false,
name: 'Debug Shower',
startAt: '2026-10-13T07:00:00',
durationMin: 10,
rate: 8.0,
maxActive: 100,
radiant: { raH: 3.2, decDeg: 58 },
lengthDeg: 22,
speedDegPerSec: 18,
brightness: 2.4,
nightOnly: false
},
showers: [
{ name: 'Quadrantids', startMonth: 1, startDay: 1, peakMonth: 1, peakDay: 3, endMonth: 1, endDay: 15, zhr: 110, raH: 15.4, decDeg: 49 },
{ name: 'Lyrids', startMonth: 4, startDay: 16, peakMonth: 4, peakDay: 22, endMonth: 4, endDay: 25, zhr: 18, raH: 18.1, decDeg: 34 },
{ name: 'Eta Aquariids', startMonth: 4, startDay: 19, peakMonth: 5, peakDay: 6, endMonth: 5, endDay: 28, zhr: 50, raH: 22.5, decDeg: -1 },
{ name: 'Delta Aquariids', startMonth: 7, startDay: 15, peakMonth: 7, peakDay: 30, endMonth: 8, endDay: 18, zhr: 25, raH: 22.8, decDeg: -16 },
{ name: 'Perseids', startMonth: 7, startDay: 17, peakMonth: 8, peakDay: 12, endMonth: 8, endDay: 24, zhr: 100, raH: 3.2, decDeg: 58 },
{ name: 'Draconids', startMonth: 10, startDay: 6, peakMonth: 10, peakDay: 8, endMonth: 10, endDay: 10, zhr: 10, raH: 17.5, decDeg: 54 },
{ name: 'Orionids', startMonth: 10, startDay: 2, peakMonth: 10, peakDay: 21, endMonth: 11, endDay: 7, zhr: 20, raH: 6.4, decDeg: 15 },
{ name: 'Taurids', startMonth: 10, startDay: 10, peakMonth: 11, peakDay: 5, endMonth: 12, endDay: 10, zhr: 5, raH: 3.9, decDeg: 21 },
{ name: 'Leonids', startMonth: 11, startDay: 6, peakMonth: 11, peakDay: 17, endMonth: 11, endDay: 30, zhr: 15, raH: 10.2, decDeg: 22 },
{ name: 'Geminids', startMonth: 12, startDay: 4, peakMonth: 12, peakDay: 14, endMonth: 12, endDay: 17, zhr: 120, raH: 7.5, decDeg: 33 },
{ name: 'Ursids', startMonth: 12, startDay: 17, peakMonth: 12, peakDay: 22, endMonth: 12, endDay: 26, zhr: 10, raH: 14.5, decDeg: 75 }
]
// meteorShowers: { enabled: false }
// meteorShowers: { debug: { enabled: false } }
// meteorShowers: { debug: { startAt: '2026-10-13T07:00:00', durationMin: 10, rate: 2.0 } }
},
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// Weather effects // Weather effects
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -269,15 +341,33 @@ window.CONFIG = {
// altitude so aircraft fly above the deck. // altitude so aircraft fly above the deck.
clouds: { clouds: {
enabled: true, // false removes the volumetric cloud deck enabled: true, // false removes the volumetric cloud deck
top: 1.0, // ~12.9 km top: 0.78, // ~10.1 km, lower deck keeps camera clearance
bottom: -0.2, // ~-2.6 km (deck base slightly below terrain) bottom: -0.2, // ~-2.6 km (deck base slightly below terrain)
nearFade: {
enabled: false, // test: disable the cloud-free near bubble
start: 0.0, // world units: clouds fade out very close to camera
end: 0.1 // full density from this distance onward
},
// Soft cloud edges: instead of a hard shell boundary, the deck fades
// vertically and near grazing horizon rays. This targets the visible
// cloud-deck ring without changing the actual cloud top/bottom.
softEdges: true,
edgeSoftness: 0.18, // world units of vertical soft padding
horizonSoftness: 6.0, // path-length fade for grazing cloud rays
maxMarchUnits: 80, // raymarch cap; 30 was the old fixed cap
// softEdges: false // old hard-edged shell behaviour
// Terrain occlusion for clouds. false draws clouds in front of the
// terrain mesh even when terrain is closer; true clips cloud rays
// against the terrain distance buffer.
terrainOcclusion: false, // inverted occlusion: clouds stay in front
// terrainOcclusion: true
// Coverage per weather level, 0 = clear, 1 = overcast. Only the // Coverage per weather level, 0 = clear, 1 = overcast. Only the
// levels listed here override the built-in defaults // levels listed here override the built-in defaults
// (sunny 0.20, cloudy 0.70, stormy 0.80, night 0.45). Live weather // (sunny 0.20, cloudy 0.70, stormy 0.80, night 0.45). Live weather
// only ever reports sunny/cloudy/stormy, so the deck keeps that // only ever reports sunny/cloudy/stormy, so the deck keeps that
// coverage through the night as well - 'night' is used by the weather // coverage through the night as well - 'night' is used by the weather
// simulation (weatherSim: true) alone. // simulation (weatherSim: true) alone.
density: { sunny: 0.25, cloudy: 0.50, rain: 0.75, snow: 0.65, stormy: 0.80 }, density: { sunny: 0.25, cloudy: 0.50, rain: 0.45, snow: 0.65, stormy: 0.80 },
// 'night' intentionally has no own density: it follows the last // 'night' intentionally has no own density: it follows the last
// non-night weather density (sunny/cloudy/stormy). // non-night weather density (sunny/cloudy/stormy).
// Cloud motion from Open-Meteo wind. Open-Meteo reports wind FROM // Cloud motion from Open-Meteo wind. Open-Meteo reports wind FROM
@@ -292,6 +382,7 @@ window.CONFIG = {
// wind: { speedScale: 140, maxSpeed: 0.12 } // very visible motion // wind: { speedScale: 140, maxSpeed: 0.12 } // very visible motion
} }
// density: { sunny: 0.05, cloudy: 0.9, rain: 0.95, snow: 0.85, stormy: 1.0 } // density: { sunny: 0.05, cloudy: 0.9, rain: 0.95, snow: 0.85, stormy: 1.0 }
// top: 0.65, nearFade: { start: 0.5, end: 3.5 }
}, },
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -331,7 +422,7 @@ window.CONFIG = {
enabled: true, // false removes aircraft and contrails enabled: true, // false removes aircraft and contrails
altitudeKm: 14, // cruise altitude altitudeKm: 14, // cruise altitude
climbKm: 100, // climb/descent run to and from cruise climbKm: 100, // climb/descent run to and from cruise
count: 21, // simultaneous aircraft (max 240) count: 6, // simultaneous aircraft (max 240)
speedKmh: 850, // mean ground speed speedKmh: 850, // mean ground speed
speedVar: 0.18, // +/- speed deviation (0..0.5) speedVar: 0.18, // +/- speed deviation (0..0.5)
minLegKm: 60, // shortest leg (no taxi hops) minLegKm: 60, // shortest leg (no taxi hops)
@@ -345,9 +436,14 @@ window.CONFIG = {
contrailChance: 1.00, // 0 = no contrails, 1 = every eligible jet contrailChance: 1.00, // 0 = no contrails, 1 = every eligible jet
contrailStartKm: 4, // start after this distance from the airport contrailStartKm: 4, // start after this distance from the airport
contrailLifeS: 300, // seconds before a trail disappears contrailLifeS: 300, // seconds before a trail disappears
contrailWidthM: 1400, // full trail width contrailWidthM: 1400, // aircraft/trail scale width
contrailEngineWidthM: 700, // width of each engine contrail
contrailEngineOffset: { x: 0.36, y: -0.055, z: -0.14 }, // engine exhaust in model units
markingLightOffset: { x: 0.0, y: 0.235, z: 0.0 }, // top-centre fuselage beacon
contrailFadeKm: 300, // fully faded at this distance (ramp starts at 35 %) contrailFadeKm: 300, // fully faded at this distance (ramp starts at 35 %)
// contrailChance: 0.35, contrailLifeS: 120 // short sparse trails // contrailChance: 0.35, contrailLifeS: 120 // short sparse trails
// contrailEngineWidthM: 520, contrailEngineOffset: { x: 0.36, y: -0.055, z: -0.18 }
// markingLightOffset: { x: 0.0, y: 0.26, z: 0.05 }
// Night contrast: a physically scaled contrail is a faint grey thread // 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 // 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 // opacity (0.34 was the old value) and it also drives the gain on the
@@ -379,6 +475,16 @@ window.CONFIG = {
edgeSkirtKm: 800, // coarse outer terrain pulled past the horizon edgeSkirtKm: 800, // coarse outer terrain pulled past the horizon
edgeSkirtRings: 24, // coarse rings in the outer skirt edgeSkirtRings: 24, // coarse rings in the outer skirt
edgeSkirtNoise: 0.28, // fallback height variation if outer DEM is off edgeSkirtNoise: 0.28, // fallback height variation if outer DEM is off
// Distance-dependent terrain mesh LOD: fine near the mosaic centre,
// coarser toward the border. The outer skirt remains the farthest LOD.
lod: {
enabled: true,
nearStepPx: 32, // mesh vertex spacing near the centre
farStepPx: 96, // mesh vertex spacing near the border
innerTiles: 8, // fully fine area around the centre
outerTiles: 20 // fully coarse area toward the border
// lod: { enabled: false } // old uniform mesh
},
outerDem: { outerDem: {
enabled: true, // false uses procedural fallback heights enabled: true, // false uses procedural fallback heights
zoom: 7, // reduced-resolution terrarium zoom for the skirt zoom: 7, // reduced-resolution terrarium zoom for the skirt
@@ -416,17 +522,17 @@ window.CONFIG = {
// 'auto' derives the driving side from the location (left in the UK, // 'auto' derives the driving side from the location (left in the UK,
// Japan, Australia, India, southern Africa, ...), 'left'/'right' forces it. // Japan, Australia, India, southern Africa, ...), 'left'/'right' forces it.
trafficSide: 'auto', trafficSide: 'auto',
dashM: 620, // mean vehicle spacing on motorways dashM: 800, // mean vehicle spacing on motorways
// side roads use dashM * 2.4 // side roads use dashM * 2.4
// dashM: 350 // denser traffic // dashM: 350 // denser traffic
// dashM: 1200 // sparse traffic // dashM: 1200 // sparse traffic
spreadKm: 45, // gaussian sigma around the motorway network spreadKm: 45, // gaussian sigma around the motorway network
spreadFloor: 0.30, // share that far side roads keep spreadFloor: 0.40, // share that far side roads keep
speed: 1.0, // flow speed multiplier speed: 1.0, // flow speed multiplier
density: 0.25, // vehicle density multiplier density: 0.225, // vehicle density multiplier
brightness: 1.0, // vehicle light intensity brightness: 1.0, // vehicle light intensity
motorwayDensity: 0.95, // share of the density budget on motorways/trunk motorwayDensity: 0.95, // share of the density budget on motorways/trunk
sideDensity: 0.35, // share of the density budget on primary/secondary/tertiary sideDensity: 0.55, // share of the density budget on primary/secondary/tertiary
sideDashFactor: 3.2, // wider spacing on side roads: fewer local cars sideDashFactor: 3.2, // wider spacing on side roads: fewer local cars
// Time-based traffic profile. Values are multipliers around the // Time-based traffic profile. Values are multipliers around the
// configured density. Times are local scene-clock hours. // configured density. Times are local scene-clock hours.
@@ -445,7 +551,7 @@ window.CONFIG = {
sundayEveningPeak: 18.5, sundayEveningPeak: 18.5,
sundayEveningWidth: 1.8, sundayEveningWidth: 1.8,
sundayEveningGain: 0.85, // commuter return traffic sundayEveningGain: 0.85, // commuter return traffic
nightReduction: 0.70 // deep-night traffic reduced to 30 % nightReduction: 0.85 // deep-night traffic reduced to 15 %
// timeProfile: { enabled: false } // timeProfile: { enabled: false }
// timeProfile: { morningGain: 0.8, eveningGain: 1.0, nightReduction: 0.85 } // timeProfile: { morningGain: 0.8, eveningGain: 1.0, nightReduction: 0.85 }
} }
@@ -597,7 +703,19 @@ window.CONFIG = {
// drawn larger so it reads as a disc; the surface brightness and the // drawn larger so it reads as a disc; the surface brightness and the
// scene lighting are NOT scaled with it. // scene lighting are NOT scaled with it.
sun: { sun: {
angularRadius: 0.0558 // 12x the physical 0.00465 rad angularRadius: 0.0279, // 6x the physical 0.00465 rad
brightness: 2.1, // sun disc/glow gain
glow: {
enabled: true,
core: 1.15, // bright inner corona
inner: 0.95, // warm near halo
outer: 0.38, // soft far halo
outerRadius: 11.0, // outer halo radius in sun-disc radii
color: [1.00, 0.78, 0.36]
}
// angularRadius: 0.0558, brightness: 1.0
// angularRadius: 0.0140, brightness: 2.4
// glow: { core: 1.6, inner: 1.4, outer: 0.55, outerRadius: 14.0 }
}, },
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -636,8 +754,8 @@ window.CONFIG = {
// time, 1440 = one simulated day per minute. Clock hands, digital readout, // time, 1440 = one simulated day per minute. Clock hands, digital readout,
// weather and sky all use the same clock. Hash overrides: #at=... #speed=... // weather and sky all use the same clock. Hash overrides: #at=... #speed=...
day: { day: {
startAt: '2026-10-13T06:59:00', // frozen test clock startAt: null, // real time
speed: 0 // frozen time speed: 1 // real time
// startAt: null, speed: 1 // real time // startAt: null, speed: 1 // real time
}, },
+694 -120
View File
File diff suppressed because it is too large. Load diff