Commit Graph
27 Commits
Author SHA1 Message Date
Richard Zink 21f75e64ce clock+camera: sun and moon always from the SunCalc ephemeris (sine-curve sun and ecliptic-elongation moon removed), virtual clock via startAt/speed, optional camera aim at the moon 2026-10-11 22:46:35 +02:00
Richard Zink 113e4c522d airliner mesh is generated in-repo: tools/plane_gen.py writes vendor/plane3d.js (480 tris, CC0, same unit extent as the old Grab3D derivative); attribution updated 2026-10-11 18:42:48 +02:00
Richard Zink 4369afd3ef lighting: remove the palette terrain model - physics is the only lighting, themes tint it through THEMES[theme].lighting; debug panel shows the active palette and its tint/gain; credits no longer claim VIIRS 2026-10-11 15:39:42 +02:00
Richard Zink 6eb25bdd03 physical lighting, volumetric clouds, terrain shadows, pixel-art render scale
- atmosphere: physical terrain lighting (air mass, Rayleigh beam colour,
  skylight, moon, starlight floor), aerial perspective for terrain and
  cloud deck, configurable haze/albedo/ambient gains
- clouds: march the deck in height instead of ray distance, IGN dither
  (no per-frame flicker), per-step height jitter, 4-octave fbm renormalised,
  softer density threshold, distance softening as a procedural mip,
  grazing path clamp, cloud shadows on the ground (cloudShadowDensity/
  Floor/Ambient) and cloud haze factor
- terrain: self-shadows from the elevation field (penumbra + shadow floor),
  soft mosaic rim (edgeFadeTiles), east/west axis corrected (+X = west)
- lights: per-object twilight switching for cars, city dots and ground blocks
- flights: contrail width 620 m, fade to zero by contrailFadeKm, aircraft
  size decoupled from trail width, count halved
- render: CONFIG.renderScale with integer upscale + image-rendering: pixelated
- data: nginx overpass proxy + cache, per-mirror cooldown ladder, ring-based
  cell ordering (disc fills evenly), settlements fetched before roads,
  interim chain persistence, two worker lanes (car/city) with progress logs
- removed: NASA VIIRS night-lights layer (fetch, canvas, texture, uniforms)
2026-10-11 15:04:21 +02:00
Richard Zink 4ecef21729 config.maxFps: scene frame-rate cap (default 30, 0 = free; motion stays time-based) 2026-10-10 11:04:44 +02:00
Richard Zink d0aa86ce9b flights: full CONFIG.flights parameterization (altitude, count, speed, holds, destination weights, contrail chance/alt/life/width) + curved random-destination routing 2026-10-10 11:02:58 +02:00
Richard Zink fbac24773a clouds3d-only cleanup: drop Vanta/three.js/clouds2d, real-sky fixes, settlement lights, dynamic location anchor 2026-10-09 14:13:03 +02:00
Richard Zink f21a967643 Separate flight and fetch directions via URL params
Two independent URL parameters:
  #flight=N|NE|E|SE|S|SW|W|NW  (camera motion direction)
  #fetch=N|NE|E|SE|S|SW|W|NW   (tile collection direction)

Example: #flight=E&fetch=N -> camera flies east, corridor built
north (perpendicular to flight). Lets you test what happens when
the corridor orientation doesn't match the camera's flight path.

URL parsing supports & and ; as separators, plus multiple keys
in one hash. window.__flightDir and window.__fetchDir are exposed
separately so JS code can react to each.
2026-10-07 21:51:24 +02:00
Richard Zink 9027099d89 Add #flight=N|NE|E|SE|S|SW|W|NW URL parameter for corridor direction
Adds 8 compass directions for the tile-build axis. Camera position,
corridor rotation, and refetch math all read from window.__flightDir.

Test URLs:
  #flight=N   north  (default, +Z, current behaviour)
  #flight=E   east   (+X)
  #flight=S   south  (-Z)
  #flight=W   west   (-X)
  #flight=NE  northeast (diagonal)
  #flight=SE  southeast
  #flight=SW  southwest
  #flight=NW  northwest

Renders with no hash unchanged. Each direction rotates the
corridor so its long axis follows the chosen compass bearing, and
the camera drifts along that bearing.
2026-10-07 21:50:31 +02:00
Richard Zink 5ff67cd1b4 High-contrast weather themes: dark sky, light clouds
Reworked all four weather palettes so the cloud body is much
lighter than the sky — the way real clouds look against blue.
Added boneLight and chalkLight to the getColors keys/map.

Also reduced applyWeatherTheme mix from 0.6 to 0.4 so the
day/night sun-position palette stays visible underneath
the weather tint instead of being washed out by it.

Weather:        sky     cloud   light   bg
  sunny:        blueLt  chalk   chalkLt blue     (was: blueLt stone)
  cloudy:       blue    boneLt  chalk   steel    (was: blue   mid)
  stormy:       steel   stone   bone    panel    (was: steel  panel)
  night:        void    icon    chalk   void     (was: void   raised)
2026-10-07 19:54:43 +02:00
Richard Zink 1bf1b708e8 Add weather simulation + debug-panel weather controls
- weatherSim config flag (default false): cycles through
  ['sunny','cloudy','stormy','night'] every weatherSimInterval ms
  instead of pulling open-meteo
- Debug-panel buttons: Sunny / Cloudy / Stormy / Night for
  instant manual switch; Auto-Cycle toggle, Stop, 5s/15s cycle
- Cleanup: removed duplicate unwrapped tick() in the init block
  (the wrapped one already starts the rAF chain)

The sim keeps the existing 5-minute palette transition between
states, so you still see the colour shift rather than a hard cut.
2026-10-07 19:45:57 +02:00
Richard Zink bfbb73a2af clouds2d: texture-based 4-octave fBm (fizzer-inspired)
Rewrite clouds2d.js to sample a noise texture instead of computing
fBm with hash functions. Each octave is one texture lookup with
doubled UV scale and halved amplitude.

- Same visual range as before but ~4x cheaper on ALU
- REPEAT-wrapped texture tiles seamlessly when scrolled by time
- Per-pixel hash21 jitter keeps the regular tiling from flickering
- Exposes noise as a uniform, so multiple fragment shaders could
  share it
- Theme-agnostic: pulls colours from __currentPalette

Also adds #renderer=clouds2d URL-hash override for quick A/B
testing between the volumetric clouds3d and the 2D version.
2026-10-07 19:40:12 +02:00
Richard Zink f6f35776bc Fix getColors #2: add blue/blueLight (JavaScript hoisting)
The file had two getColors() function declarations. The second
one (hoisted later) wins and was missing the new keys. Both
declarations updated.
2026-10-07 19:34:00 +02:00
Richard Zink 1067754ae8 Fix getColors: add blue/blueLight to keys and map
The previous commit used ASH.blue and ASH.blueLight but these
were not registered in the getColors() key list or CSS-variable
map, so they were undefined and hexToInt blew up trying to call
.replace on undefined. Added both as proper keys, mapped to the
existing --blue / --blue-light CSS variables.
2026-10-07 19:31:18 +02:00
Richard Zink cf9999a919 Bright daytime sky: use blue/blue-light instead of steel
Ash palette has only muted grays as 'blue' (steel, steelLight).
Switched day entries + sunny/cloudy weather themes to use the
brighter blue and blue-light swatches so a clear midday reads as
a bright sky rather than a gray wash.

- sunPalettes[4] (sunAlt 0.4): sky/bg steel -> blue
- sunPalettes[5] (zenith): sky/bg steelLight -> blueLight
- weatherThemes.sunny: sky steelLight -> blueLight, bg mid -> bone
- weatherThemes.cloudy: sky steel -> blue
2026-10-07 19:28:57 +02:00
Richard Zink 673ed6cf0f Fix night sky: visible clouds, real moon-driven darkening
Three coordinated changes:
1. nightPaletteNew.cloud: void -> raised (slightly lighter than
   sky) so clouds have contrast against the new-moon sky
2. nightPaletteFull.cloudShadow: panel -> void so cloud undersides
   fade into the night sky, while the lit topsides (border) stand
   out clearly
3. getNightColor() now keeps 'light' (moonlight) bright and only
   partially darkens sky/bg. The previous version squashed
   everything toward black, killing cloud structure.

Shader side:
- max(0.15, uDayProgress) keeps a baseline moonlight tint on the
  lit side of clouds even when uDayProgress happens to be 0
- The final darken pass is now driven by nightFactor (sunAlt-based)
  instead of the unreliable uDayProgress
2026-10-07 19:25:50 +02:00
Richard Zink 58f1ecbc61 Compress twilight to complete within ~1h of sunset
Inserted two extra palette entries around the sunset transition:
- alt -0.262 (-15deg): already full-night (void), so ~1h after
  sunset the sky is properly dark instead of still 11% into the
  long -5.7deg -> -90deg void ramp
- alt -0.087 (-5deg): dusk anchor (panel) — was at -0.1
- alt  0.087 (+5deg): morning anchor (blood) — was at 0.15

Net effect: +5deg to -15deg transition (≈80 minutes of real time
in summer) now sweeps through golden -> rust -> panel -> void
instead of golden -> rust -> panel -> panel/void.
2026-10-07 19:23:23 +02:00
Richard Zink 4145fbdd58 Fix night sky too bright after sunset
Three fixes:
1. getColor() switched from 'sunPos.altitude > 0' to
   '> sunPalettes[0].alt' (-pi/2). The day palette interpolates
   through twilight to deep-below-horizon, so an hour after sunset
   (sunAlt ~ -15deg) we now stay on the day palette and get the
   intended dark 'panel' colour instead of switching to the moon
   palette immediately.
2. getNightColor() now actually applies MIN_NIGHT_BRIGHTNESS via
   shiftColor toward black (the old 'brightness' var was unused
   dead code).
3. applyWeatherTheme() cuts the weather tint by up to 70% at
   night, so a 'cloudy' theme no longer washes the night sky with
   the brighter weather sky colour.
2026-10-07 19:21:24 +02:00
Richard Zink 5e66cdfa2b clouds3d: closer cruise, sun-alt-driven stars
- Cruise altitude 2.6 -> 2.0 (just above cloud ceiling y=1.5,
  gives the 'just above the clouds' airliner feel)
- Expose __currentSunAlt (radians) from animate() so the
  renderer can tell night from day without misreading
  realDayProgress (which mixes pre-dawn + post-sunset hours)
- Replace (1 - uDayProgress) star gate by smoothstep over uSunAlt:
  nightFactor = 1 when sun is well below horizon, 0 when above
- Widen sky band so stars are visible from the horizon upward
  (cockpit-perspective frame is mostly below rd.y=0.3)
2026-10-07 19:14:46 +02:00
Richard Zink 0648676974 Add volumetric clouds3d renderer
Raymarches a horizontal cloud layer (28 steps, 4-octave 3D fBm).
Camera path is sinusoidal in altitude so the view dips into the
cloud deck at intervals for a 'fly through the edges' feel.
Density threshold from weather: sunny -> sparse, stormy -> overcast.
Renderer is selected via CONFIG.renderer ('clouds2d' or 'clouds3d').
2026-10-07 18:54:58 +02:00
Richard Zink 3812f80f40 Make clouds2d.js theme-agnostic
- Remove all hardcoded fallback hex/rgb values
- Skip draw until __currentPalette is published by parent
- applyWeatherTheme now also mixes cloudShadow (was dropped)
2026-10-07 18:53:15 +02:00
Richard Zink c6764fd534 Fix clouds2d: create own canvas element
The 2D WebGL renderer now creates its own <canvas> overlay inside
the target element, instead of expecting the target to already be a
canvas. This fixes 'canvas.getContext is not a function' when the
target is a <div>.
2026-10-07 18:49:42 +02:00
Richard Zink e8df75eebc Enable debug temporarily for diagnosis 2026-10-07 16:56:50 +02:00
Richard Zink d8e619e0c3 Add lightweight 2D WebGL cloud renderer as alternative to Vanta 2026-10-07 16:47:53 +02:00
Richard Zink a82d6cce3d Inline noise.png as base64 data URI to allow file:// access 2026-10-07 16:20:14 +02:00
Richard Zink 3ccc3e4be7 Set webpage title to 'Background Vanta Clouds2' 2026-10-07 15:01:22 +02:00
Richard Zink 965b813f5e Rename index.html to background.html; configure nginx to serve it as index 2026-10-07 14:59:09 +02:00