fix: soften cloud march edge
This commit is contained in:
1 parent
6bedc2c95c
commit
8884a77f7d
2 files changed
+14
-4
No files matched your search
@@ -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
|
||||||
},
|
},
|
||||||
|
// Maximum raymarch length through the cloud deck, in world units.
|
||||||
|
// Too small creates a hard cloud-deck edge/ring near the horizon.
|
||||||
|
maxMarchUnits: 120, // 30 was the old fixed cap
|
||||||
|
// maxMarchUnits: 60 // cheaper, but a harder far edge
|
||||||
// Far softening reduces detail/noise at long view distances. Lower
|
// Far softening reduces detail/noise at long view distances. Lower
|
||||||
// max keeps the deck denser near the horizon and can remove the
|
// max keeps the deck denser near the horizon and can remove the
|
||||||
// transparent ring around the terrain edge.
|
// transparent ring around the terrain edge.
|
||||||
|
|||||||
Vendored
+10
-4
@@ -90,6 +90,7 @@ var FRAG_SRC = [
|
|||||||
'uniform float uCloudFarSoftStart;',
|
'uniform float uCloudFarSoftStart;',
|
||||||
'uniform float uCloudFarSoftEnd;',
|
'uniform float uCloudFarSoftEnd;',
|
||||||
'uniform float uCloudFarSoftMax;',
|
'uniform float uCloudFarSoftMax;',
|
||||||
|
'uniform float uCloudMaxMarch;',
|
||||||
'uniform sampler2D uElev;', // terrarium RGB height grid, same UV as uGround
|
'uniform sampler2D uElev;', // terrarium RGB height grid, same UV as uGround
|
||||||
'uniform float uElevOn;', // terrain enabled (0/1)
|
'uniform float uElevOn;', // terrain enabled (0/1)
|
||||||
'uniform float uElevScale;', // metres -> world units (incl. exaggeration)
|
'uniform float uElevScale;', // metres -> world units (incl. exaggeration)
|
||||||
@@ -709,9 +710,9 @@ var FRAG_SRC = [
|
|||||||
'tExit = min(tExit, dist - 0.02);',
|
'tExit = min(tExit, dist - 0.02);',
|
||||||
'}',
|
'}',
|
||||||
'}',
|
'}',
|
||||||
'tExit = min(tExit, tEnter + 30.0);',
|
'tExit = min(tExit, tEnter + max(1.0, uCloudMaxMarch));',
|
||||||
'if (tExit <= tEnter) { gl_FragColor = vec4(0.0); return; }',
|
'if (tExit <= tEnter) { gl_FragColor = vec4(0.0); return; }',
|
||||||
'float stepSize = (tExit - tEnter) / 24.0;',
|
'float stepSize = (tExit - tEnter) / 32.0;',
|
||||||
'float t = tEnter + stepSize * 0.5;',
|
'float t = tEnter + stepSize * 0.5;',
|
||||||
'float coverage = clamp(uDensity, 0.0, 1.0);',
|
'float coverage = clamp(uDensity, 0.0, 1.0);',
|
||||||
'float baseThresh = mix(0.62, 0.20, coverage);',
|
'float baseThresh = mix(0.62, 0.20, coverage);',
|
||||||
@@ -721,7 +722,7 @@ var FRAG_SRC = [
|
|||||||
'float phase = 0.30 + 0.70 * pow(max(0.0, cosT), 2.5);',
|
'float phase = 0.30 + 0.70 * pow(max(0.0, cosT), 2.5);',
|
||||||
'float trans = 1.0;',
|
'float trans = 1.0;',
|
||||||
'vec3 cloudSum = vec3(0.0);',
|
'vec3 cloudSum = vec3(0.0);',
|
||||||
'for (int i = 0; i < 24; i++) {',
|
'for (int i = 0; i < 32; i++) {',
|
||||||
'vec3 p = uCamPos + rd * t;',
|
'vec3 p = uCamPos + rd * t;',
|
||||||
'p += rd * (ign(gl_FragCoord.xy + vec2(float(i) * 7.13, float(i) * 3.71)) - 0.5) * stepSize * 0.25;',
|
'p += rd * (ign(gl_FragCoord.xy + vec2(float(i) * 7.13, float(i) * 3.71)) - 0.5) * stepSize * 0.25;',
|
||||||
'float alt = p.y + earthDrop(p.xz);',
|
'float alt = p.y + earthDrop(p.xz);',
|
||||||
@@ -737,7 +738,8 @@ var FRAG_SRC = [
|
|||||||
'vec3 moonC = albC * uMoonColor * (0.35 + 0.65 * max(0.0, dot(rd, uMoonDir))) * uMoonInt * 3.0;',
|
'vec3 moonC = albC * uMoonColor * (0.35 + 0.65 * max(0.0, dot(rd, uMoonDir))) * uMoonInt * 3.0;',
|
||||||
'vec3 cloudCol = direct + ambC + moonC;',
|
'vec3 cloudCol = direct + ambC + moonC;',
|
||||||
'float nearFade = smoothstep(uCloudNearFadeStart, uCloudNearFadeEnd, t);',
|
'float nearFade = smoothstep(uCloudNearFadeStart, uCloudNearFadeEnd, t);',
|
||||||
'float alpha = clamp(d * stepSize * 3.50 * densityGain * nearFade, 0.0, 1.0);',
|
'float marchFade = 1.0 - smoothstep(uCloudMaxMarch * 0.70, uCloudMaxMarch, t - tEnter);',
|
||||||
|
'float alpha = clamp(d * stepSize * 3.50 * densityGain * nearFade * marchFade, 0.0, 1.0);',
|
||||||
'cloudSum += cloudCol * alpha * trans;',
|
'cloudSum += cloudCol * alpha * trans;',
|
||||||
'trans *= (1.0 - alpha);',
|
'trans *= (1.0 - alpha);',
|
||||||
'if (trans < 0.04) break;',
|
'if (trans < 0.04) break;',
|
||||||
@@ -1316,6 +1318,7 @@ function init(canvas) {
|
|||||||
uCloudFarSoftStart: gl.getUniformLocation(prog, 'uCloudFarSoftStart'),
|
uCloudFarSoftStart: gl.getUniformLocation(prog, 'uCloudFarSoftStart'),
|
||||||
uCloudFarSoftEnd: gl.getUniformLocation(prog, 'uCloudFarSoftEnd'),
|
uCloudFarSoftEnd: gl.getUniformLocation(prog, 'uCloudFarSoftEnd'),
|
||||||
uCloudFarSoftMax: gl.getUniformLocation(prog, 'uCloudFarSoftMax'),
|
uCloudFarSoftMax: gl.getUniformLocation(prog, 'uCloudFarSoftMax'),
|
||||||
|
uCloudMaxMarch: gl.getUniformLocation(prog, 'uCloudMaxMarch'),
|
||||||
uElev: uElev, uElevOn: uElevOn, uElevScale: uElevScale, uTerrainExag: uTerrainExag,
|
uElev: uElev, uElevOn: uElevOn, uElevScale: uElevScale, uTerrainExag: uTerrainExag,
|
||||||
uSunDir: uSunDir, uMoonDir: uMoonDir, uMode: uMode,
|
uSunDir: uSunDir, uMoonDir: uMoonDir, uMode: uMode,
|
||||||
uAtmoModelOn: uAtmoModelOn, uAtmoHeightUnits: uAtmoHeightUnits,
|
uAtmoModelOn: uAtmoModelOn, uAtmoHeightUnits: uAtmoHeightUnits,
|
||||||
@@ -1509,6 +1512,8 @@ CLOUD_TOP = Math.max(0.2, Math.min(CLOUD_TOP, 2.0));
|
|||||||
CLOUD_BOT = Math.min(CLOUD_BOT, CLOUD_TOP - 0.4);
|
CLOUD_BOT = Math.min(CLOUD_BOT, CLOUD_TOP - 0.4);
|
||||||
var CLOUD_NEAR_FADE_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.nearFade) || {};
|
var CLOUD_NEAR_FADE_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.nearFade) || {};
|
||||||
var CLOUD_FAR_SOFT_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.farSoft) || {};
|
var CLOUD_FAR_SOFT_CFG = (window.CONFIG && window.CONFIG.clouds && window.CONFIG.clouds.farSoft) || {};
|
||||||
|
var CLOUD_MAX_MARCH_UNITS = (window.CONFIG && typeof window.CONFIG.clouds.maxMarchUnits === 'number')
|
||||||
|
? Math.max(10.0, Math.min(300.0, window.CONFIG.clouds.maxMarchUnits)) : 30.0;
|
||||||
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 CLOUD_FAR_SOFT_START = (typeof CLOUD_FAR_SOFT_CFG.start === 'number')
|
var CLOUD_FAR_SOFT_START = (typeof CLOUD_FAR_SOFT_CFG.start === 'number')
|
||||||
@@ -7406,6 +7411,7 @@ window.clouds3dRender = function(target) {
|
|||||||
gl.uniform1f(s.uCloudFarSoftStart, CLOUD_FAR_SOFT_START);
|
gl.uniform1f(s.uCloudFarSoftStart, CLOUD_FAR_SOFT_START);
|
||||||
gl.uniform1f(s.uCloudFarSoftEnd, CLOUD_FAR_SOFT_END);
|
gl.uniform1f(s.uCloudFarSoftEnd, CLOUD_FAR_SOFT_END);
|
||||||
gl.uniform1f(s.uCloudFarSoftMax, CLOUD_FAR_SOFT_MAX);
|
gl.uniform1f(s.uCloudFarSoftMax, CLOUD_FAR_SOFT_MAX);
|
||||||
|
gl.uniform1f(s.uCloudMaxMarch, CLOUD_MAX_MARCH_UNITS);
|
||||||
|
|
||||||
// Ground mosaic uniforms + periodic re-fetch trigger.
|
// Ground mosaic uniforms + periodic re-fetch trigger.
|
||||||
// uGroundCenter is the world position (X, Z) of the centre tile's
|
// uGroundCenter is the world position (X, Z) of the centre tile's
|
||||||
|
|||||||
Reference in new issue
Block a user