diff --git a/background-final.html b/background-final.html index 4231eb4..be3c50b 100644 --- a/background-final.html +++ b/background-final.html @@ -2510,6 +2510,9 @@ window.weatherThemes = { window.__currentWeatherName = currentWeatherThemeName; window.__currentDayProgress = realDayProgress; window.__currentThemeSpeed = currentThemeSpeed; + // Sun altitude in radians. Negative = below horizon (night). + var _sunPos = SunCalc.getPosition(new Date(), PASSAU_LAT, PASSAU_LON); + window.__currentSunAlt = _sunPos.altitude; effect.setOptions({ skyColor: c.sky, cloudColor: c.cloud, diff --git a/background.html b/background.html index c6ad63a..ce4f43a 100644 --- a/background.html +++ b/background.html @@ -1657,6 +1657,9 @@ window.weatherThemes = { window.__currentWeatherName = currentWeatherThemeName; window.__currentDayProgress = realDayProgress; window.__currentThemeSpeed = currentThemeSpeed; + // Sun altitude in radians. Negative = below horizon (night). + var _sunPos = SunCalc.getPosition(new Date(), PASSAU_LAT, PASSAU_LON); + window.__currentSunAlt = _sunPos.altitude; effect.setOptions({ skyColor: c.sky, cloudColor: c.cloud, diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index 0f76e69..a05c908 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -61,6 +61,7 @@ var FRAG_SRC = [ 'uniform float uSpeed;', 'uniform float uDensity;', 'uniform float uDayProgress;', + 'uniform float uSunAlt;', // radians, negative = below horizon (night) // 3D hash and value noise 'float hash3(vec3 p) {', 'p = fract(p * vec3(0.1031, 0.1030, 0.0973));', @@ -121,9 +122,9 @@ var FRAG_SRC = [ // pow(...,8) keeps dives rare: most of the time diveT≈0, // and only spikes briefly to 1. 'float diveT = pow(0.5 + 0.5 * sin(uTime * 0.10), 8.0);', - // Cruise at y=2.6 (well above cloud ceiling y=1.5), dive to + // Cruise at y=2.0 (just above cloud ceiling y=1.5), dive to // y=1.2 — close enough to skim the cloud top, never deep inside. - 'float camY = mix(2.6, 1.2, diveT);', + 'float camY = mix(2.0, 1.2, diveT);', 'vec3 ro = vec3(drift, camY, drift * 0.7);', // Ray direction: nearly level, like looking out a cockpit // window. Horizon sits around the middle of the frame. @@ -132,7 +133,12 @@ var FRAG_SRC = [ 'float skyT = clamp(rd.y * 0.7 + 0.5, 0.0, 1.0);', 'vec3 col = mix(uBg, uSky, skyT);', // Stars: hash-grid sphere, above horizon, only at night. - 'float stars = starField(rd) * smoothstep(0.05, 0.35, rd.y) * (1.0 - uDayProgress);', + // Night = sun altitude below 0. Visibility extends well into the +// lower half of the sky so the airplane-cockpit view shows stars +// from the horizon up. + 'float nightFactor = smoothstep(0.05, -0.15, uSunAlt);', + 'float skyMask = smoothstep(-0.10, 0.30, rd.y);', + 'float stars = starField(rd) * skyMask * nightFactor;', 'col = mix(col, uLight, clamp(stars, 0.0, 1.0) * 0.9);', // Density threshold: weather 'sunny' -> high (sparse clouds), // 'stormy' -> low (overcast deck). @@ -191,12 +197,14 @@ function init(canvas) { var uSpeed = gl.getUniformLocation(prog, 'uSpeed'); var uDensity = gl.getUniformLocation(prog, 'uDensity'); var uDayProgress = gl.getUniformLocation(prog, 'uDayProgress'); + var uSunAlt = gl.getUniformLocation(prog, 'uSunAlt'); return { gl: gl, prog: prog, buf: buf, aPos: aPos, uRes: uRes, uTime: uTime, uSky: uSky, uCloud: uCloud, uCloudShadow: uCloudShadow, uLight: uLight, uBg: uBg, - uSpeed: uSpeed, uDensity: uDensity, uDayProgress: uDayProgress + uSpeed: uSpeed, uDensity: uDensity, uDayProgress: uDayProgress, + uSunAlt: uSunAlt }; } @@ -279,6 +287,10 @@ window.clouds3dRender = function(target) { ? Math.max(0, Math.min(1, dayProgress)) : 0.5; gl.uniform1f(s.uDayProgress, day); + var sunAlt = (typeof window.__currentSunAlt === 'number') + ? window.__currentSunAlt : 0; + gl.uniform1f(s.uSunAlt, sunAlt); + var speed = (typeof themeSpeed === 'number') ? Math.max(0.1, Math.min(3, themeSpeed)) : 1.0; gl.uniform1f(s.uSpeed, speed);