Commit Graph
364 Commits
Author SHA1 Message Date
Richard Zink 48160b730f Dark night sky + slow star twinkle + moonlit clouds
clouds3d:
- Star twinkle: 3 Hz ±45% -> 0.5 Hz ±15% (gentle scintillation
  instead of static-like flickering)
- Night darkening: applied only to sky pixels via the cloud mask,
  not to clouds. The darkening factor jumped 0.45 -> 0.85 so the
  night sky really does go black around moonlit clouds. Clouds
  keep their uLight-tinted colour so they remain visible.

clouds2d:
- Same darkening approach but via multiplicative factor (no cloud
  mask in the 2D shader): col *= 1 - nightFactor * 0.7
2026-10-07 20:09:08 +02:00
Richard Zink 595b22aac1 More cloud structure: 4 fBm layers, 4 octaves each
Density reverted to original 0.20/0.70/1.00/0.45 but structure
denser than ever:
- fbm3: 3 -> 4 octaves (more detail at fine scales)
- cloudDensity: 4 layers (base + mid 35% + fine1 18% + fine2 10%)
- smoothstep 0.24 -> 0.20 for tighter cloud edges
Cost: 4 fbm * 4 octaves = 16 noise3 samples per step * 18 steps
= 288 samples per pixel. Watch FPS on low-end GPUs.
2026-10-07 20:07:20 +02:00
Richard Zink 42c078a407 Permanent above-clouds cruise + more structure
- Remove dive component from camY. Was mix(2.0, 1.2, diveT)
  (occasional dips into cloud top); now fixed at 2.2, always above
  the y=1.5 cloud ceiling. Cloud deck always visible below.
- WEATHER_DENSITY bumped again: sunny 0.55->0.65, cloudy 0.85->0.90,
  night 0.65->0.75. Even 'sunny' is now a partly-cloudy sky.
- clouds3d: third fBm detail layer at 3.2x frequency (was 2 layers).
  Contributions: base 1.0, mid 0.30, fine 0.12. Combined with the
  tighter smoothstep (0.18 -> 0.16) the silhouettes have wispier,
  more interesting edges instead of soft blobs.
- Same density bump in clouds2d for consistency.
2026-10-07 20:05:39 +02:00
Richard Zink 9a933b3dc4 More clouds + finer structure, switch default back to clouds3d
- WEATHER_DENSITY bumped: sunny 0.20->0.55, cloudy 0.70->0.85,
  night 0.45->0.65. Stormy stays at 1.0 (already maxed).
  Even 'sunny' now has visible cloud structure, not just clear sky.
- clouds3d: add a second fBm layer at 4x frequency for fine detail,
  blended at 18% into the base. Combined with the tighter smoothstep
  (0.24 -> 0.18) the cloud silhouettes have more interesting edges
  instead of soft blob shapes.
- Same density bump applied to clouds2d so swapping renderers
  doesn't change the visual weather.
- config.renderer: clouds2d -> clouds3d (user request)
2026-10-07 20:01:52 +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 460b7cfd6c Replace white noise with Perlin-style smooth noise
The previous noise.png was random pixels (gradient 0.064 per
step), which produces grainy static when sampled at fine octaves
instead of fluffy clouds. New noise uses 4 octaves of bilinear-
interpolated value noise with Perlin's quintic fade curve, giving
a much lower gradient (0.012) so multi-octave sampling produces
soft cloud shapes.
2026-10-07 19:49:45 +02:00
Richard Zink 0b8cf464b8 Enable debug panel so weather buttons are visible 2026-10-07 19:48:18 +02:00
Richard Zink ba7b90d7d9 Fix config.js: weatherSim was inserted into window.THEMES by mistake
My previous patch used rfind('};') which landed on the THEMES
block's closer instead of CONFIG's. Moved weatherSim + weatherSimInterval
into CONFIG and cleaned the duplicated block. Rebuild docker so
the corrected file replaces the broken one.
2026-10-07 19:47:13 +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 1f90276fed Default to clouds2d (texture-based) renderer 2026-10-07 19:42:19 +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 65af0bf2f0 clouds3d: anti-flicker dither + softer smoothstep
The cloud horizon flickered when the camera was far from the
deck because the regular raymarch steps aligned with the cloud
boundary. Two cheap fixes:
- Per-pixel jitter (hash21 of gl_FragCoord + uTime) shifts each
  ray's start by up to one stepSize; the brain averages the
  random offsets into a smooth edge
- Wider smoothstep (0.18 -> 0.24) softens the binary cloud/no-cloud
  boundary the jitter is now dithering across
2026-10-07 19:16:54 +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 d55f2dc1d4 Tighten cruise altitude and shallow out dives
- Cloud ceiling lowered from y=1.8 to y=1.5 (thinner deck)
- Cruise raised from y=2.0 to y=2.6 (clear margin above clouds)
- Dive endpoint raised from y=0.9 to y=1.2 (skims top, never deep)
- Dive exponent 5 -> 8 (much rarer dives)
- Early-out and ceiling bounds updated to match new y=1.5
2026-10-07 19:10:54 +02:00
Richard Zink 47ce467c4a Fix clouds3d: remove orphan closing brace
A leftover '},' from the previous patch was producing an extra
closing brace at line 55 of the joined GLSL, causing '}' syntax
errors on every frame.
2026-10-07 19:08:48 +02:00
Richard Zink 468e66058e Fix clouds3d: move starField out of main() (GLSL syntax)
GLSL does not allow nested function definitions; the starField()
helper must live at top-level alongside hash3/noise3/fbm3.
2026-10-07 19:04:50 +02:00
Richard Zink ee821dd724 Airliner cockpit view + night stars
- Cruise altitude lowered to y=2.0 (just above cloud top at y=1.8)
- Look direction nearly level (rd.y ~ -0.05 at horizon line)
- Stars rendered as 3D hash-grid sphere, only above horizon and
  only when uDayProgress < 1 (i.e. at night). Subtle sin twinkle
  keeps them from looking like static dither.
2026-10-07 19:02:06 +02:00
Richard Zink e80d255d58 Fly mostly above the clouds with brief dips
Camera altitude is now driven by pow(sin,5) so the view stays at
y=2.6 most of the time and only briefly dips to y=0.9 to skim the
top of the cloud deck. Marching also skips the empty gap between
camera and cloud ceiling when looking down from above.
2026-10-07 18:57:55 +02:00
Richard Zink 433d743446 Tune clouds3d for low-end GPUs: 18 steps, 3 octaves
Reduce raymarch iterations from 28 to 18 and fBm octaves from
4 to 3 (with step size 0.55->0.85 to preserve cloud coverage).
Per-pixel cost drops by ~55% while visual density stays similar.
2026-10-07 18:56:40 +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 fcf431470a Disable Vanta default texturePath so only our inline data:image is loaded 2026-10-07 16:15:49 +02:00
Richard Zink 8e05444cfb Add build.py: bundles all assets into a single standalone HTML 2026-10-07 16:12:16 +02:00
Richard Zink 3ccc3e4be7 Set webpage title to 'Background Vanta Clouds2' 2026-10-07 15:01:22 +02:00
Richard Zink 746a7cb615 Add README and MIT LICENSE 2026-10-07 15:00:38 +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
Richard Zink 3241721f2b Skip reverse-geocoding if CONFIG.location.label already set 2026-10-07 14:37:08 +02:00
Richard Zink 5c3a29a12e Display location label/coordinates right-aligned in weather widget 2026-10-07 14:35:10 +02:00
Richard Zink fd73c3ec1c Try browser geolocation for location with London fallback 2026-10-07 14:30:42 +02:00
Richard Zink 223d1a3d74 Use CONFIG.location.lat/lon for weather API requests 2026-10-07 14:27:53 +02:00
Richard Zink 80d15a6edd Document location field in config.js 2026-10-07 14:25:54 +02:00
Richard Zink 9dd76ebd9e Use lat/lon from CONFIG.location; hide debug panel when debug=0; remove street address 2026-10-07 14:22:02 +02:00
Richard Zink 518988251c Convert forecast temperatures based on CONFIG.units (slot + minmax) 2026-10-07 14:17:55 +02:00
Richard Zink 5e9ddd8590 Refresh weather display when debug units dropdown changes 2026-10-07 14:14:39 +02:00
Richard Zink 661542117c Support ss/SS case-insensitive; convert units based on CONFIG.units 2026-10-07 14:12:10 +02:00
Richard Zink d3ccd6f70d Set debug=0, language=de, timeFormat=DD. MMMM, YYYY T HH:mm:SS 2026-10-07 14:06:24 +02:00
Richard Zink 90b5cd2a78 Add vanta.clouds2.min.js for fallback 2026-10-07 14:02:06 +02:00
Richard Zink 7109e1b5a0 Vendor Vanta.js, three.js, suncalc locally for offline operation 2026-10-07 14:01:32 +02:00
Richard Zink eae8bf19a3 Add am/AM (a/A) token to formatDateTime; document in config.js 2026-10-07 13:58:17 +02:00
Richard Zink 1c6b2ffbbe Add white-space: pre to digital clock for line breaks 2026-10-07 13:54:42 +02:00