diff --git a/config.js b/config.js index 437d21a..178f3eb 100644 --- a/config.js +++ b/config.js @@ -313,6 +313,8 @@ window.CONFIG = { albedoGain: 1.0, // theme share on surface colours skyGain: 0.45, // diffuse skylight share on surfaces airGain: 0.55, // Rayleigh airlight strength (blue-biased) + physicalSky: true, // Rayleigh sky scattering instead of pure theme gradient + rayleighGain: 8.0, // exposure for the physical sky term distanceFog: false, // legacy aerial perspective is off model: { enabled: false // volumetric atmosphere/fog removed diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index bfd5e39..51c3595 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -105,6 +105,10 @@ var FRAG_SRC = [ 'uniform float uStarAmb;', // diffuse starlight + airglow 'uniform float uPhysical;', 'uniform vec3 uAirColor;', // Rayleigh airlight at the horizon + 'uniform vec3 uRayleighBeta;', // vertical Rayleigh optical depth RGB + 'uniform float uSunAirMass;', // relative air mass of the sun beam + 'uniform float uRayleighGain;', + 'uniform float uPhysicalSkyOn;', 'uniform vec3 uCloudAlbedo;', // theme-tinted but brightness-normalised 'uniform float uAirDensity;', // slant optical depth per world unit 'uniform float uCloudHaze;', // clouds sit above most of the haze: much weaker @@ -336,6 +340,21 @@ var FRAG_SRC = [ // distance fog saturates to, so no seam at the silhouette. 'float skyT = clamp(rd.y * 0.7 + 0.5, 0.5, 1.0);', 'vec3 col = mix(uBg, uSky, skyT);', + 'if (uPhysicalSkyOn > 0.5) {', + 'float cosT = dot(rd, uSunDir);', + 'float phase = 0.5 + 0.5 * cosT * cosT;', + 'float sunUp = smoothstep(-0.25, 0.05, uSunAlt);', + 'vec3 sunTop = uSunColor * uSunInt * sunUp;', + 'float viewY = max(rd.y, 0.0);', + 'float mView = (viewY > 0.02) ? min(38.0, 1.0 / viewY) : 38.0;', + 'vec3 tauView = uRayleighBeta * mView;', + 'vec3 single = phase * sunTop * (1.0 - exp(-tauView));', + 'vec3 multi = phase * sunTop * tauView * tauView * 0.12;', + 'vec3 ambient = max(vec3(uSkyAmb), uStarAmb * vec3(0.7, 0.85, 1.0)) *', + '(1.0 - exp(-tauView)) * vec3(0.35, 0.55, 1.0);', + 'vec3 phys = (single + multi + ambient) * uRayleighGain;', + 'col = mix(col, phys, 0.82);', + '}', 'float nightFactor = 1.0 - smoothstep(-0.15, 0.05, uSunAlt);', 'float skyMask = smoothstep(-0.20, 0.40, rd.y);', // Stars must not sit on the moon: the disc is opaque, so every @@ -825,6 +844,10 @@ function init(canvas) { var uStarAmb = gl.getUniformLocation(prog, 'uStarAmb'); var uPhysical = gl.getUniformLocation(prog, 'uPhysical'); var uAirColor = gl.getUniformLocation(prog, 'uAirColor'); + var uRayleighBeta = gl.getUniformLocation(prog, 'uRayleighBeta'); + var uSunAirMass = gl.getUniformLocation(prog, 'uSunAirMass'); + var uRayleighGain = gl.getUniformLocation(prog, 'uRayleighGain'); + var uPhysicalSkyOn = gl.getUniformLocation(prog, 'uPhysicalSkyOn'); var uCloudAlbedo = gl.getUniformLocation(prog, 'uCloudAlbedo'); var uAirDensity = gl.getUniformLocation(prog, 'uAirDensity'); var uCloudHaze = gl.getUniformLocation(prog, 'uCloudHaze'); @@ -921,7 +944,9 @@ function init(canvas) { uAtmoBlueColor: uAtmoBlueColor, uAtmoGrayColor: uAtmoGrayColor, uSunColor: uSunColor, uSunInt: uSunInt, uMoonColor: uMoonColor, uMoonInt: uMoonInt, uSkyAmb: uSkyAmb, uStarAmb: uStarAmb, - uPhysical: uPhysical, uAirColor: uAirColor, uCloudAlbedo: uCloudAlbedo, + uPhysical: uPhysical, uAirColor: uAirColor, + uRayleighBeta: uRayleighBeta, uSunAirMass: uSunAirMass, + uRayleighGain: uRayleighGain, uPhysicalSkyOn: uPhysicalSkyOn, uCloudAlbedo: uCloudAlbedo, uAirDensity: uAirDensity, uCloudHaze: uCloudHaze, uSkyTex: uSkyTex, uSkyOn: uSkyOn, uStarLon: uStarLon, uPole: uPole, uMoonTex: uMoonTex, uMoonTexOn: uMoonTexOn, uMoonR: uMoonR, @@ -2337,6 +2362,9 @@ var MOON_TEX_SRC = (typeof window.__moonTex === 'string' && window.__moonTex) var ATMO_NIGHT_FLOOR = (typeof ATMO.nightFloor === 'number') ? Math.max(0.01, ATMO.nightFloor) : 0.05; var ATMO_ALBEDO_GAIN = (typeof ATMO.albedoGain === 'number') ? Math.max(0.1, ATMO.albedoGain) : 1.0; var ATMO_SKY_GAIN = (typeof ATMO.skyGain === 'number') ? Math.max(0.05, ATMO.skyGain) : 0.55; +var ATMO_PHYSICAL_SKY = ATMO.physicalSky !== false; +var ATMO_RAYLEIGH_GAIN = (typeof ATMO.rayleighGain === 'number') + ? Math.max(0.1, Math.min(30.0, ATMO.rayleighGain)) : 8.0; // ---- Artificial light switching (CONFIG.lights) ------------------------- // Every individual light owns a sun-altitude threshold inside the window @@ -5457,6 +5485,10 @@ window.clouds3dRender = function(target) { _amb *= _exp; } gl.uniform3f(s.uAirColor, _air[0], _air[1], _air[2]); + gl.uniform3f(s.uRayleighBeta, TAU_RAYLEIGH[0], TAU_RAYLEIGH[1], TAU_RAYLEIGH[2]); + gl.uniform1f(s.uSunAirMass, airMass(Math.max(sunAlt, 0.0))); + gl.uniform1f(s.uRayleighGain, ATMO_RAYLEIGH_GAIN); + gl.uniform1f(s.uPhysicalSkyOn, ATMO_PHYSICAL_SKY ? 1.0 : 0.0); gl.uniform3f(s.uSunColor, _beam[0], _beam[1], _beam[2]); gl.uniform1f(s.uSunInt, _beamL); gl.uniform3f(s.uMoonColor, _mBeam[0], _mBeam[1], _mBeam[2]);