feat: wait for terrain before drawing clouds

This commit is contained in:
Richard Zink committed 2026-10-13 14:21:22 +02:00
1 parent 2afc0b2545
commit 8cca47f86e
2 files changed
+12 -4

No files matched your search

+4
View File
@@ -335,6 +335,10 @@ window.CONFIG = {
start: 0.35, // world units: clouds fade out very close to camera start: 0.35, // world units: clouds fade out very close to camera
end: 2.5 // full density from this distance onward end: 2.5 // full density from this distance onward
}, },
// Delay the volumetric cloud pass until the DEM/terrain mesh is
// ready. This avoids clouds appearing over an unfinished ground model.
waitForTerrain: true, // false = draw clouds immediately
// waitForTerrain: false
// Coverage per weather level, 0 = clear, 1 = overcast. Only the // Coverage per weather level, 0 = clear, 1 = overcast. Only the
// levels listed here override the built-in defaults // levels listed here override the built-in defaults
// (sunny 0.20, cloudy 0.70, stormy 0.80, night 0.45). Live weather // (sunny 0.20, cloudy 0.70, stormy 0.80, night 0.45). Live weather
+8 -4
View File
@@ -1504,6 +1504,10 @@ var CLOUD_NEAR_FADE_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFI
var CLOUD_NEAR_FADE_START = (typeof CLOUD_NEAR_FADE_CFG.start === 'number') ? Math.max(0, CLOUD_NEAR_FADE_CFG.start) : 0.35; var CLOUD_NEAR_FADE_START = (typeof CLOUD_NEAR_FADE_CFG.start === 'number') ? Math.max(0, CLOUD_NEAR_FADE_CFG.start) : 0.35;
var CLOUD_NEAR_FADE_END = Math.max(CLOUD_NEAR_FADE_START + 0.1, (typeof CLOUD_NEAR_FADE_CFG.end === 'number') ? CLOUD_NEAR_FADE_CFG.end : 2.5); var CLOUD_NEAR_FADE_END = Math.max(CLOUD_NEAR_FADE_START + 0.1, (typeof CLOUD_NEAR_FADE_CFG.end === 'number') ? CLOUD_NEAR_FADE_CFG.end : 2.5);
var CLOUDS_ON = !(window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.enabled === false); var CLOUDS_ON = !(window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.enabled === false);
var CLOUDS_WAIT_FOR_TERRAIN = !(window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.waitForTerrain === false);
function cloudsActive() {
return CLOUDS_ON && (!CLOUDS_WAIT_FOR_TERRAIN || (elevTexture && terrainVbo));
}
var CLOUD_WIND_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.wind) || {}; var CLOUD_WIND_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.wind) || {};
var CLOUD_WIND_SCALE = (typeof CLOUD_WIND_CFG.speedScale === 'number') ? Math.max(0, CLOUD_WIND_CFG.speedScale) : 80; var CLOUD_WIND_SCALE = (typeof CLOUD_WIND_CFG.speedScale === 'number') ? Math.max(0, CLOUD_WIND_CFG.speedScale) : 80;
var CLOUD_WIND_MIN = (typeof CLOUD_WIND_CFG.minSpeed === 'number') ? Math.max(0, CLOUD_WIND_CFG.minSpeed) : 0.004; var CLOUD_WIND_MIN = (typeof CLOUD_WIND_CFG.minSpeed === 'number') ? Math.max(0, CLOUD_WIND_CFG.minSpeed) : 0.004;
@@ -7342,7 +7346,7 @@ window.clouds3dRender = function(target) {
gl.uniform1f(s.uAirHazeMaxAlpha, AIR_HAZE_MAX_ALPHA); gl.uniform1f(s.uAirHazeMaxAlpha, AIR_HAZE_MAX_ALPHA);
gl.uniform3f(s.uAirHazeColor, _airHazeColor[0], _airHazeColor[1], _airHazeColor[2]); gl.uniform3f(s.uAirHazeColor, _airHazeColor[0], _airHazeColor[1], _airHazeColor[2]);
gl.uniform1i(s.uTerrainDistTex, 7); gl.uniform1i(s.uTerrainDistTex, 7);
gl.uniform1f(s.uCloudsOn, CLOUDS_ON ? 1.0 : 0.0); gl.uniform1f(s.uCloudsOn, cloudsActive() ? 1.0 : 0.0);
gl.uniform1f(s.uFrontHazeOn, FRONT_HAZE_ON ? 1.0 : 0.0); gl.uniform1f(s.uFrontHazeOn, FRONT_HAZE_ON ? 1.0 : 0.0);
gl.uniform1f(s.uFrontHazeDensity, FRONT_HAZE_DENSITY); gl.uniform1f(s.uFrontHazeDensity, FRONT_HAZE_DENSITY);
gl.uniform1f(s.uFrontHazeScaleHeightUnits, FRONT_HAZE_SCALE_HEIGHT_UNITS); gl.uniform1f(s.uFrontHazeScaleHeightUnits, FRONT_HAZE_SCALE_HEIGHT_UNITS);
@@ -7657,7 +7661,7 @@ window.clouds3dRender = function(target) {
gl.uniform1f(terr.uCloudBot, CLOUD_BOT); gl.uniform1f(terr.uCloudBot, CLOUD_BOT);
gl.uniform1f(terr.uCloudTop, CLOUD_TOP); gl.uniform1f(terr.uCloudTop, CLOUD_TOP);
gl.uniform1f(terr.uDensity, density); gl.uniform1f(terr.uDensity, density);
gl.uniform1f(terr.uCloudShadowOn, ATMO_CLOUD_SHADOWS ? 1.0 : 0.0); gl.uniform1f(terr.uCloudShadowOn, (ATMO_CLOUD_SHADOWS && cloudsActive()) ? 1.0 : 0.0);
gl.uniform1f(terr.uCloudShadowDensity, ATMO_CS_DENSITY); gl.uniform1f(terr.uCloudShadowDensity, ATMO_CS_DENSITY);
gl.uniform1f(terr.uCloudShadowFloor, ATMO_CS_FLOOR); gl.uniform1f(terr.uCloudShadowFloor, ATMO_CS_FLOOR);
gl.uniform1f(terr.uCloudShadowAmbient, ATMO_CS_AMBIENT); gl.uniform1f(terr.uCloudShadowAmbient, ATMO_CS_AMBIENT);
@@ -7720,7 +7724,7 @@ window.clouds3dRender = function(target) {
gl.enableVertexAttribArray(terr.aColor); gl.enableVertexAttribArray(terr.aColor);
gl.vertexAttribPointer(terr.aColor, 3, gl.FLOAT, false, STRIDE, 32); gl.vertexAttribPointer(terr.aColor, 3, gl.FLOAT, false, STRIDE, 32);
} }
var distPassOk = (FRONT_HAZE_ON || CLOUDS_ON) && ensureTerrainDistFbo(gl, canvas.width, canvas.height); var distPassOk = (FRONT_HAZE_ON || cloudsActive()) && ensureTerrainDistFbo(gl, canvas.width, canvas.height);
if (distPassOk) { if (distPassOk) {
gl.bindFramebuffer(gl.FRAMEBUFFER, terrainDistFbo); gl.bindFramebuffer(gl.FRAMEBUFFER, terrainDistFbo);
gl.viewport(0, 0, terrainDistW, terrainDistH); gl.viewport(0, 0, terrainDistW, terrainDistH);
@@ -8017,7 +8021,7 @@ window.clouds3dRender = function(target) {
gl.drawArrays(gl.TRIANGLES, 0, 3); gl.drawArrays(gl.TRIANGLES, 0, 3);
} }
if (CLOUDS_ON) { if (cloudsActive()) {
gl.useProgram(s.prog); gl.useProgram(s.prog);
gl.bindBuffer(gl.ARRAY_BUFFER, s.buf); gl.bindBuffer(gl.ARRAY_BUFFER, s.buf);
gl.enableVertexAttribArray(s.aPos); gl.enableVertexAttribArray(s.aPos);