From 7f733b8efe68424abc6e9d5af296ff12325e6285 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Mon, 12 Oct 2026 17:33:31 +0200 Subject: [PATCH] atmosphere: smooth front haze with 24-bit distance and dither --- vendor/clouds3d.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index fc961a3..f352136 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -460,15 +460,18 @@ var FRAG_SRC = [ 'if (uMode == 3) {', 'if (uFrontHazeOn < 0.5) { gl_FragColor = vec4(0.0); return; }', 'vec2 uv = gl_FragCoord.xy / uResolution;', - 'float distNorm = texture2D(uTerrainDistTex, uv).a;', + 'vec4 distTex = texture2D(uTerrainDistTex, uv);', 'float column = 0.0;', - 'if (distNorm > 0.0005 && distNorm < 0.999) {', + 'if (distTex.a > 0.5) {', + 'float distNorm = (distTex.r * 65536.0 + distTex.g * 256.0 + distTex.b) / 16777215.0;', 'column = hazeColumnToDistance(rd, distNorm * max(1.0, uFarPlane));', '} else {', 'column = airHazeColumn(rd);', '}', 'float tau = uFrontHazeDensity * column;', 'float alpha = clamp((1.0 - exp(-tau)) * uFrontHazeGain, 0.0, uFrontHazeMaxAlpha);', + 'float dither = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453);', + 'alpha = clamp(alpha + (dither - 0.5) / 255.0, 0.0, uFrontHazeMaxAlpha);', 'gl_FragColor = vec4(uFrontHazeColor, alpha);', 'return;', '}', @@ -818,7 +821,11 @@ var TERRAIN_FRAG_SRC = [ 'void main() {', 'if (uDistancePassOn > 0.5) {', 'float d = clamp(length(vViewPos) / max(1.0, uFarPlane), 0.0, 1.0);', - 'gl_FragColor = vec4(0.0, 0.0, 0.0, d);', + 'float v = d * 16777215.0;', + 'float r = floor(v / 65536.0) / 255.0;', + 'float g = floor(mod(v, 65536.0) / 256.0) / 255.0;', + 'float b = floor(mod(v, 256.0)) / 255.0;', + 'gl_FragColor = vec4(r, g, b, 1.0);', 'return;', '}', 'vec2 gUv = vUV;', @@ -2274,8 +2281,8 @@ function ensureTerrainDistFbo(gl, w, h) { terrainDistTex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, terrainDistTex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); terrainDistDepth = gl.createRenderbuffer();