clouds: use curved cloud layer and allow clouds over terrain

This commit is contained in:
Richard Zink committed 2026-10-12 18:13:54 +02:00
1 parent d9da8fdb47
commit 6802f83d1d
1 file changed
+29 -9
+29 -9
View File
@@ -374,6 +374,27 @@ var FRAG_SRC = [
'float sq = sqrt(disc);',
'return vec2((-b - sq) * 0.5, (-b + sq) * 0.5);',
'}',
'vec2 cloudLayerRoots(float layerY, vec3 rd) {',
'float camY = uCamPos.y;',
'if (uCurvatureOn < 0.5) {',
'if (abs(rd.y) < 1e-5) return vec2(-1.0, -1.0);',
'float t = (layerY - camY) / rd.y;',
'return vec2(t, t);',
'}',
'float R = max(1.0, uEarthRadius);',
'float a = (rd.x * rd.x + rd.z * rd.z) / (2.0 * R);',
'float b = rd.y;',
'float c = camY - layerY;',
'if (abs(a) < 1e-8) {',
'if (abs(b) < 1e-5) return vec2(-1.0, -1.0);',
'float t = -c / b;',
'return vec2(t, t);',
'}',
'float disc = b * b - 4.0 * a * c;',
'if (disc < 0.0) return vec2(-1.0, -1.0);',
'float sq = sqrt(disc);',
'return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));',
'}',
'float cloudDensitySpherical(vec3 p, float alt, float baseThresh, float soft) {',
'vec3 q = vec3(p.x, alt, p.z);',
'float n = fbm3(q * 0.22 + vec3(0.0, 0.0, uTime * 0.05));',
@@ -629,12 +650,9 @@ var FRAG_SRC = [
'if (uMode == 1) {',
'if (uCloudsOn < 0.5) { gl_FragColor = vec4(0.0); return; }',
'float R = max(1.0, uEarthRadius);',
'vec3 C = vec3(uCamPos.x, -R, uCamPos.z);',
'vec3 oc = uCamPos - C;',
'float camAlt = max(0.0, length(oc) - R);',
'vec2 top = cloudShellRoots(uCloudTop, oc, rd);',
'vec2 bot = cloudShellRoots(uCloudBot, oc, rd);',
'float camAlt = uCamPos.y;',
'vec2 top = cloudLayerRoots(uCloudTop, rd);',
'vec2 bot = cloudLayerRoots(uCloudBot, rd);',
'float tEnter = 1e9;',
'float tExit = -1e9;',
'if (camAlt >= uCloudBot && camAlt <= uCloudTop) {',
@@ -655,7 +673,9 @@ var FRAG_SRC = [
'vec4 distTex = texture2D(uTerrainDistTex, uv);',
'if (distTex.a > 0.5) {',
'float distNorm = (distTex.r * 65536.0 + distTex.g * 256.0 + distTex.b) / 16777215.0;',
'tExit = min(tExit, distNorm * max(1.0, uFarPlane));',
'float dist = distNorm * max(1.0, uFarPlane);',
'if (dist < tEnter - 0.05) { gl_FragColor = vec4(0.0); return; }',
'tExit = min(tExit, max(tEnter, dist));',
'}',
'}',
'tExit = min(tExit, tEnter + 30.0);',
@@ -671,7 +691,7 @@ var FRAG_SRC = [
'for (int i = 0; i < 24; i++) {',
'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;',
'float alt = max(0.0, length(p - C) - R);',
'float alt = p.y + earthDrop(p.xz);',
'if (alt > uCloudTop + 0.1 || alt < uCloudBot - 0.1) break;',
'float soft = smoothstep(4.0, 20.0, t);',
'float d = cloudDensitySpherical(p, alt, baseThresh, soft);',
@@ -683,7 +703,7 @@ var FRAG_SRC = [
'vec3 ambC = albC * max(vec3(uSkyAmb), uStarAmb * vec3(0.7, 0.85, 1.0)) * 1.7;',
'vec3 moonC = albC * uMoonColor * (0.35 + 0.65 * max(0.0, dot(rd, uMoonDir))) * uMoonInt * 3.0;',
'vec3 cloudCol = direct + ambC + moonC;',
'float alpha = clamp(d * stepSize * 2.20, 0.0, 1.0);',
'float alpha = clamp(d * stepSize * 3.50, 0.0, 1.0);',
'cloudSum += cloudCol * alpha * trans;',
'trans *= (1.0 - alpha);',
'if (trans < 0.04) break;',