Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af6b63d756 | ||
|
|
8a4884a377 | ||
|
|
e1343fdf11 | ||
|
|
3bc6fa4a3a | ||
|
|
1ceb92f2c8 | ||
|
|
7ccdc9929d | ||
|
|
07317ba8e5 | ||
|
|
a29ce1e914 | ||
|
|
ad26683384 | ||
|
|
278b1b957f | ||
|
|
fc7868cdc5 | ||
|
|
9e2c7d1207 | ||
|
|
5deab893da | ||
|
|
121b80b117 | ||
|
|
b906986718 | ||
|
|
cf41b72133 | ||
|
|
06ad6db900 | ||
|
|
e14f938252 | ||
|
|
3e5406dc1d | ||
|
|
2f67eeabd3 | ||
|
|
5364348b21 | ||
|
|
96161b1f9e | ||
|
|
99ca1b069c | ||
|
|
b4d44079ea | ||
|
|
30c5b4eb7c | ||
|
|
8ea8316b19 | ||
|
|
d4eabfa738 | ||
|
|
f3d66c3e9d | ||
|
|
f8580e595a | ||
|
|
e86819457c | ||
|
|
3db36bba58 | ||
|
|
5c2eb857bb | ||
|
|
4bdf5ac540 | ||
|
|
f4eb826c3a | ||
|
|
4cd8b57752 | ||
|
|
f8c17a0980 | ||
|
|
31162c88e0 | ||
|
|
2f1bee9f25 | ||
|
|
d08c193a5a | ||
|
|
b3a34c654c | ||
|
|
238cc1d7e8 | ||
|
|
1381b90e73 | ||
|
|
8884a77f7d | ||
|
|
6bedc2c95c | ||
|
|
bebfd64902 | ||
|
|
5cfd9c0bc3 | ||
|
|
54c2759fa2 | ||
|
|
1e582c1f7f | ||
|
|
0ddaa80643 | ||
|
|
8cca47f86e | ||
|
|
2afc0b2545 | ||
|
|
3e17279499 | ||
|
|
c02a198f3f | ||
|
|
5ce027fd5d | ||
|
|
c0c612c0cc | ||
|
|
d91858addc | ||
|
|
17395ebf7b | ||
|
|
8ed3fcc7fc | ||
|
|
d911e1b5ee | ||
|
|
33d89683ef | ||
|
|
6f19b34900 | ||
|
|
6b375ea983 | ||
|
|
8f31ff8839 | ||
|
|
b5c0030192 | ||
|
|
86c72c2160 | ||
|
|
36a8493b27 | ||
|
|
4fcaa99969 | ||
|
|
0f22aad650 |
No files matched your search
@@ -1 +1,2 @@
|
|||||||
background-standalone.html
|
background-standalone.html
|
||||||
|
Screenshot*.png
|
||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Vendored
+694
-120
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user