atmosphere: make Rayleigh sky follow spherical Earth radius

This commit is contained in:
Richard Zink committed 2026-10-12 15:13:26 +02:00
1 parent 7329957658
commit a06f7038d8
1 file changed
+48 -3
+48 -3
View File
@@ -257,6 +257,51 @@ var FRAG_SRC = [
'if (r.y > 0.0) m = max(m, r.y);',
'return m;',
'}',
'vec3 sphericalRayleighTau(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 uRayleighBeta * mView;',
'}',
'float R = max(1.0, uEarthRadius);',
'float H = max(1.0, uAtmoHeightUnits);',
'float Hs = max(0.05, uAtmoScaleHeightUnits);',
'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 vec3(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 uRayleighBeta * column;',
'}',
// Two modes driven by uMode:
// 0 = SKY: full-screen pass that paints the sky gradient and
// stars into the framebuffer (opaque, alpha = 1).
@@ -345,9 +390,7 @@ var FRAG_SRC = [
'float phase = 0.5 + 0.5 * cosT * cosT;',
'float sunUp = smoothstep(-0.25, 0.05, uSunAlt);',
'vec3 sunTop = uSunColor * uSunInt * sunUp;',
'float viewY = max(rd.y, 0.0);',
'float mView = (viewY > 0.02) ? min(38.0, 1.0 / viewY) : 38.0;',
'vec3 tauView = uRayleighBeta * mView;',
'vec3 tauView = sphericalRayleighTau(rd);',
'vec3 single = phase * sunTop * (1.0 - exp(-tauView));',
'vec3 multi = phase * sunTop * tauView * tauView * 0.12;',
'vec3 ambient = max(vec3(uSkyAmb), uStarAmb * vec3(0.7, 0.85, 1.0)) *',
@@ -5661,6 +5704,8 @@ window.clouds3dRender = function(target) {
gl.enableVertexAttribArray(s.aPos);
gl.vertexAttribPointer(s.aPos, 2, gl.FLOAT, false, 0, 0);
gl.uniformMatrix4fv(s.uViewProjInv, false, viewProjInv);
gl.uniform3f(s.uCamPos, camX, camY, camZ);
gl.uniform1f(s.uCurvatureOn, CURVATURE_ON ? 1.0 : 0.0);
gl.disable(gl.DEPTH_TEST);
gl.depthMask(false);
gl.uniform1i(s.uMode, 0);