atmosphere: add stable air haze behind terrain
This commit is contained in:
1 parent
989310ab3b
commit
a33e6ddcfc
2 files changed
+100
-1
No files matched your search
@@ -333,6 +333,14 @@ window.CONFIG = {
|
|||||||
maxAlpha: 0.65,
|
maxAlpha: 0.65,
|
||||||
color: [0.58, 0.64, 0.72]
|
color: [0.58, 0.64, 0.72]
|
||||||
},
|
},
|
||||||
|
airHaze: {
|
||||||
|
enabled: true,
|
||||||
|
scaleHeightKm: 8.5,
|
||||||
|
density: 0.16,
|
||||||
|
gain: 1.0,
|
||||||
|
maxAlpha: 0.45,
|
||||||
|
color: [0.58, 0.64, 0.72]
|
||||||
|
},
|
||||||
model: {
|
model: {
|
||||||
enabled: false // legacy full atmosphere model remains off
|
enabled: false // legacy full atmosphere model remains off
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+92
-1
@@ -110,6 +110,12 @@ var FRAG_SRC = [
|
|||||||
'uniform float uSunAirMass;', // relative air mass of the sun beam
|
'uniform float uSunAirMass;', // relative air mass of the sun beam
|
||||||
'uniform float uRayleighGain;',
|
'uniform float uRayleighGain;',
|
||||||
'uniform float uPhysicalSkyOn;',
|
'uniform float uPhysicalSkyOn;',
|
||||||
|
'uniform float uAirHazeOn;',
|
||||||
|
'uniform float uAirHazeDensity;',
|
||||||
|
'uniform float uAirHazeScaleHeightUnits;',
|
||||||
|
'uniform float uAirHazeGain;',
|
||||||
|
'uniform float uAirHazeMaxAlpha;',
|
||||||
|
'uniform vec3 uAirHazeColor;',
|
||||||
'uniform vec3 uCloudAlbedo;', // theme-tinted but brightness-normalised
|
'uniform vec3 uCloudAlbedo;', // theme-tinted but brightness-normalised
|
||||||
'uniform float uAirDensity;', // slant optical depth per world unit
|
'uniform float uAirDensity;', // slant optical depth per world unit
|
||||||
'uniform float uCloudHaze;', // clouds sit above most of the haze: much weaker
|
'uniform float uCloudHaze;', // clouds sit above most of the haze: much weaker
|
||||||
@@ -303,6 +309,51 @@ var FRAG_SRC = [
|
|||||||
'}',
|
'}',
|
||||||
'return uRayleighBeta * column;',
|
'return uRayleighBeta * column;',
|
||||||
'}',
|
'}',
|
||||||
|
'float airHazeColumn(vec3 rd) {',
|
||||||
|
'if (uCurvatureOn < 0.5) {',
|
||||||
|
'float viewY = max(rd.y, 0.0);',
|
||||||
|
'float mView = (viewY > 0.02) ? min(38.0, 1.0 / viewY) : 38.0;',
|
||||||
|
'return mView;',
|
||||||
|
'}',
|
||||||
|
'float R = max(1.0, uEarthRadius);',
|
||||||
|
'float H = max(1.0, uAtmoHeightUnits);',
|
||||||
|
'float Hs = max(0.05, uAirHazeScaleHeightUnits);',
|
||||||
|
'vec3 C = vec3(uCamPos.x, -R, uCamPos.z);',
|
||||||
|
'vec3 oc = uCamPos - C;',
|
||||||
|
'float b = dot(oc, rd);',
|
||||||
|
'float rOut = R + H;',
|
||||||
|
'float cOut = dot(oc, oc) - rOut * rOut;',
|
||||||
|
'float tStart = 0.0;',
|
||||||
|
'float tEnd = 100.0;',
|
||||||
|
'float discOut = b * b - cOut;',
|
||||||
|
'if (discOut > 0.0) {',
|
||||||
|
'float sq = sqrt(discOut);',
|
||||||
|
'float t1 = -b - sq;',
|
||||||
|
'float t2 = -b + sq;',
|
||||||
|
'if (cOut > 0.0) tStart = max(0.0, t1);',
|
||||||
|
'tEnd = max(0.0, t2);',
|
||||||
|
'}',
|
||||||
|
'float cIn = dot(oc, oc) - R * R;',
|
||||||
|
'float discIn = b * b - cIn;',
|
||||||
|
'if (discIn > 0.0) {',
|
||||||
|
'float sq = sqrt(discIn);',
|
||||||
|
'float t1 = -b - sq;',
|
||||||
|
'float t2 = -b + sq;',
|
||||||
|
'if (t1 > 0.0) tEnd = min(tEnd, t1);',
|
||||||
|
'else if (t2 > 0.0) tEnd = min(tEnd, t2);',
|
||||||
|
'}',
|
||||||
|
'if (tEnd <= tStart) return 0.0;',
|
||||||
|
'float step = (tEnd - tStart) / 16.0;',
|
||||||
|
'float t = tStart + step * 0.5;',
|
||||||
|
'float column = 0.0;',
|
||||||
|
'for (int i = 0; i < 16; i++) {',
|
||||||
|
'vec3 p = uCamPos + rd * t;',
|
||||||
|
'float alt = max(0.0, length(p - C) - R);',
|
||||||
|
'column += exp(-alt / Hs) * step / Hs;',
|
||||||
|
't += step;',
|
||||||
|
'}',
|
||||||
|
'return column;',
|
||||||
|
'}',
|
||||||
// Two modes driven by uMode:
|
// Two modes driven by uMode:
|
||||||
// 0 = SKY: full-screen pass that paints the sky gradient and
|
// 0 = SKY: full-screen pass that paints the sky gradient and
|
||||||
// stars into the framebuffer (opaque, alpha = 1).
|
// stars into the framebuffer (opaque, alpha = 1).
|
||||||
@@ -402,6 +453,12 @@ var FRAG_SRC = [
|
|||||||
'vec3 phys = (single + multi + ambient) * uRayleighGain;',
|
'vec3 phys = (single + multi + ambient) * uRayleighGain;',
|
||||||
'col = mix(col, phys, 0.82);',
|
'col = mix(col, phys, 0.82);',
|
||||||
'}',
|
'}',
|
||||||
|
'if (uAirHazeOn > 0.5) {',
|
||||||
|
'float hazeColumn = airHazeColumn(rd);',
|
||||||
|
'float hazeTau = uAirHazeDensity * hazeColumn;',
|
||||||
|
'float hazeAlpha = clamp((1.0 - exp(-hazeTau)) * uAirHazeGain, 0.0, uAirHazeMaxAlpha);',
|
||||||
|
'col = mix(col, uAirHazeColor, hazeAlpha);',
|
||||||
|
'}',
|
||||||
'float nightFactor = 1.0 - smoothstep(-0.15, 0.05, uSunAlt);',
|
'float nightFactor = 1.0 - smoothstep(-0.15, 0.05, uSunAlt);',
|
||||||
'float skyMask = smoothstep(-0.20, 0.40, rd.y);',
|
'float skyMask = smoothstep(-0.20, 0.40, rd.y);',
|
||||||
// Stars must not sit on the moon: the disc is opaque, so every
|
// Stars must not sit on the moon: the disc is opaque, so every
|
||||||
@@ -924,6 +981,12 @@ function init(canvas) {
|
|||||||
var uSunAirMass = gl.getUniformLocation(prog, 'uSunAirMass');
|
var uSunAirMass = gl.getUniformLocation(prog, 'uSunAirMass');
|
||||||
var uRayleighGain = gl.getUniformLocation(prog, 'uRayleighGain');
|
var uRayleighGain = gl.getUniformLocation(prog, 'uRayleighGain');
|
||||||
var uPhysicalSkyOn = gl.getUniformLocation(prog, 'uPhysicalSkyOn');
|
var uPhysicalSkyOn = gl.getUniformLocation(prog, 'uPhysicalSkyOn');
|
||||||
|
var uAirHazeOn = gl.getUniformLocation(prog, 'uAirHazeOn');
|
||||||
|
var uAirHazeDensity = gl.getUniformLocation(prog, 'uAirHazeDensity');
|
||||||
|
var uAirHazeScaleHeightUnits = gl.getUniformLocation(prog, 'uAirHazeScaleHeightUnits');
|
||||||
|
var uAirHazeGain = gl.getUniformLocation(prog, 'uAirHazeGain');
|
||||||
|
var uAirHazeMaxAlpha = gl.getUniformLocation(prog, 'uAirHazeMaxAlpha');
|
||||||
|
var uAirHazeColor = gl.getUniformLocation(prog, 'uAirHazeColor');
|
||||||
var uCloudAlbedo = gl.getUniformLocation(prog, 'uCloudAlbedo');
|
var uCloudAlbedo = gl.getUniformLocation(prog, 'uCloudAlbedo');
|
||||||
var uAirDensity = gl.getUniformLocation(prog, 'uAirDensity');
|
var uAirDensity = gl.getUniformLocation(prog, 'uAirDensity');
|
||||||
var uCloudHaze = gl.getUniformLocation(prog, 'uCloudHaze');
|
var uCloudHaze = gl.getUniformLocation(prog, 'uCloudHaze');
|
||||||
@@ -1029,7 +1092,11 @@ function init(canvas) {
|
|||||||
uMoonInt: uMoonInt, uSkyAmb: uSkyAmb, uStarAmb: uStarAmb,
|
uMoonInt: uMoonInt, uSkyAmb: uSkyAmb, uStarAmb: uStarAmb,
|
||||||
uPhysical: uPhysical, uAirColor: uAirColor,
|
uPhysical: uPhysical, uAirColor: uAirColor,
|
||||||
uRayleighBeta: uRayleighBeta, uSunAirMass: uSunAirMass,
|
uRayleighBeta: uRayleighBeta, uSunAirMass: uSunAirMass,
|
||||||
uRayleighGain: uRayleighGain, uPhysicalSkyOn: uPhysicalSkyOn, uCloudAlbedo: uCloudAlbedo,
|
uRayleighGain: uRayleighGain, uPhysicalSkyOn: uPhysicalSkyOn,
|
||||||
|
uAirHazeOn: uAirHazeOn, uAirHazeDensity: uAirHazeDensity,
|
||||||
|
uAirHazeScaleHeightUnits: uAirHazeScaleHeightUnits,
|
||||||
|
uAirHazeGain: uAirHazeGain, uAirHazeMaxAlpha: uAirHazeMaxAlpha,
|
||||||
|
uAirHazeColor: uAirHazeColor, uCloudAlbedo: uCloudAlbedo,
|
||||||
uAirDensity: uAirDensity, uCloudHaze: uCloudHaze,
|
uAirDensity: uAirDensity, uCloudHaze: uCloudHaze,
|
||||||
uSkyTex: uSkyTex, uSkyOn: uSkyOn, uStarLon: uStarLon, uPole: uPole,
|
uSkyTex: uSkyTex, uSkyOn: uSkyOn, uStarLon: uStarLon, uPole: uPole,
|
||||||
uMoonTex: uMoonTex, uMoonTexOn: uMoonTexOn, uMoonR: uMoonR,
|
uMoonTex: uMoonTex, uMoonTexOn: uMoonTexOn, uMoonR: uMoonR,
|
||||||
@@ -2516,6 +2583,24 @@ var TERRAIN_HAZE_COLOR = new Float32Array(
|
|||||||
? [TERRAIN_HAZE_CFG.color[0], TERRAIN_HAZE_CFG.color[1], TERRAIN_HAZE_CFG.color[2]]
|
? [TERRAIN_HAZE_CFG.color[0], TERRAIN_HAZE_CFG.color[1], TERRAIN_HAZE_CFG.color[2]]
|
||||||
: [0.58, 0.64, 0.72]
|
: [0.58, 0.64, 0.72]
|
||||||
);
|
);
|
||||||
|
var AIR_HAZE_CFG = ATMO.airHaze || TERRAIN_HAZE_CFG || {};
|
||||||
|
var AIR_HAZE_ON = (typeof AIR_HAZE_CFG.enabled === 'boolean')
|
||||||
|
? AIR_HAZE_CFG.enabled
|
||||||
|
: (TERRAIN_HAZE_ON && AIR_HAZE_CFG.enabled !== false);
|
||||||
|
var AIR_HAZE_SCALE_HEIGHT_KM = (typeof AIR_HAZE_CFG.scaleHeightKm === 'number')
|
||||||
|
? Math.max(1.0, Math.min(30.0, AIR_HAZE_CFG.scaleHeightKm)) : 8.5;
|
||||||
|
var AIR_HAZE_SCALE_HEIGHT_UNITS = AIR_HAZE_SCALE_HEIGHT_KM / KM_PER_TILE;
|
||||||
|
var AIR_HAZE_DENSITY = (typeof AIR_HAZE_CFG.density === 'number')
|
||||||
|
? Math.max(0.01, Math.min(5.0, AIR_HAZE_CFG.density)) : 0.16;
|
||||||
|
var AIR_HAZE_GAIN = (typeof AIR_HAZE_CFG.gain === 'number')
|
||||||
|
? Math.max(0.1, Math.min(5.0, AIR_HAZE_CFG.gain)) : 1.0;
|
||||||
|
var AIR_HAZE_MAX_ALPHA = (typeof AIR_HAZE_CFG.maxAlpha === 'number')
|
||||||
|
? Math.max(0.05, Math.min(1.0, AIR_HAZE_CFG.maxAlpha)) : 0.45;
|
||||||
|
var AIR_HAZE_COLOR = new Float32Array(
|
||||||
|
Array.isArray(AIR_HAZE_CFG.color) && AIR_HAZE_CFG.color.length >= 3
|
||||||
|
? [AIR_HAZE_CFG.color[0], AIR_HAZE_CFG.color[1], AIR_HAZE_CFG.color[2]]
|
||||||
|
: [0.58, 0.64, 0.72]
|
||||||
|
);
|
||||||
var CURV_CFG = (window.CONFIG && window.CONFIG.curvature) || {};
|
var CURV_CFG = (window.CONFIG && window.CONFIG.curvature) || {};
|
||||||
var CURVATURE_ON = CURV_CFG.enabled !== false;
|
var CURVATURE_ON = CURV_CFG.enabled !== false;
|
||||||
var CURV_EXAG = (typeof CURV_CFG.exaggeration === 'number')
|
var CURV_EXAG = (typeof CURV_CFG.exaggeration === 'number')
|
||||||
@@ -5608,6 +5693,12 @@ window.clouds3dRender = function(target) {
|
|||||||
gl.uniform1f(s.uSunAirMass, airMass(Math.max(sunAlt, 0.0)));
|
gl.uniform1f(s.uSunAirMass, airMass(Math.max(sunAlt, 0.0)));
|
||||||
gl.uniform1f(s.uRayleighGain, ATMO_RAYLEIGH_GAIN);
|
gl.uniform1f(s.uRayleighGain, ATMO_RAYLEIGH_GAIN);
|
||||||
gl.uniform1f(s.uPhysicalSkyOn, ATMO_PHYSICAL_SKY ? 1.0 : 0.0);
|
gl.uniform1f(s.uPhysicalSkyOn, ATMO_PHYSICAL_SKY ? 1.0 : 0.0);
|
||||||
|
gl.uniform1f(s.uAirHazeOn, AIR_HAZE_ON ? 1.0 : 0.0);
|
||||||
|
gl.uniform1f(s.uAirHazeDensity, AIR_HAZE_DENSITY);
|
||||||
|
gl.uniform1f(s.uAirHazeScaleHeightUnits, AIR_HAZE_SCALE_HEIGHT_UNITS);
|
||||||
|
gl.uniform1f(s.uAirHazeGain, AIR_HAZE_GAIN);
|
||||||
|
gl.uniform1f(s.uAirHazeMaxAlpha, AIR_HAZE_MAX_ALPHA);
|
||||||
|
gl.uniform3f(s.uAirHazeColor, AIR_HAZE_COLOR[0], AIR_HAZE_COLOR[1], AIR_HAZE_COLOR[2]);
|
||||||
gl.uniform3f(s.uSunColor, _beam[0], _beam[1], _beam[2]);
|
gl.uniform3f(s.uSunColor, _beam[0], _beam[1], _beam[2]);
|
||||||
gl.uniform1f(s.uSunInt, _beamL);
|
gl.uniform1f(s.uSunInt, _beamL);
|
||||||
gl.uniform3f(s.uMoonColor, _mBeam[0], _mBeam[1], _mBeam[2]);
|
gl.uniform3f(s.uMoonColor, _mBeam[0], _mBeam[1], _mBeam[2]);
|
||||||
|
|||||||
Reference in new issue
Block a user