clouds: remove old cloud raymarch shader pass
This commit is contained in:
1 parent
20b47f5460
commit
06fb2f8d8f
1 file changed
+1
-138
Vendored
+1
-138
@@ -439,124 +439,7 @@ var FRAG_SRC = [
|
||||
'return;',
|
||||
'}',
|
||||
|
||||
// ---- CLOUDS pass ----
|
||||
// Ray-terrain intersection (used to discard clouds that are
|
||||
// entirely behind the terrain mesh).
|
||||
'vec2 terrRoots = curvedLayerRoots(0.0, ro, rd);',
|
||||
'float tTerrain = -1.0;',
|
||||
'if (terrRoots.x > 0.0) tTerrain = terrRoots.x;',
|
||||
'else if (terrRoots.y > 0.0) tTerrain = terrRoots.y;',
|
||||
// Keep cloud occlusion on the curved Earth horizon only. Detailed
|
||||
// terrain-height clipping made the deck boil and cut holes.
|
||||
'if (tTerrain < 0.1) tTerrain = -1.0;',
|
||||
// Cloud march. The output is the cloud's effective colour and
|
||||
// coverage (alpha); the render pass uses alpha-blend so the
|
||||
// terrain mesh from the previous pass shows through transparent
|
||||
// cloud pixels.
|
||||
'float baseThresh = mix(0.72, 0.40, uDensity);',
|
||||
// March the deck in HEIGHT, not along the ray. Sampling a slab along
|
||||
// the ray gives every view angle its own set of sample heights, and
|
||||
// those sets line up across the screen as bands - exactly the stacked
|
||||
// slabs this looked like. Walking the layer from its own top to its
|
||||
// own bottom and weighting each step by its path length is independent
|
||||
// of the view angle, and grazing rays get the long path they really
|
||||
// have.
|
||||
'vec2 bot = curvedLayerRoots(uCloudBot, ro, rd);',
|
||||
'vec2 top = curvedLayerRoots(uCloudTop, ro, rd);',
|
||||
'float roPy = ro.y + earthDrop(ro.xz);',
|
||||
'float tEnter = 1e9;',
|
||||
'float tExit = -1e9;',
|
||||
'if (roPy >= uCloudBot && roPy <= uCloudTop) {',
|
||||
'tEnter = 0.0;',
|
||||
'tExit = max(maxPositiveRoot(bot), maxPositiveRoot(top));',
|
||||
'} else if (roPy > uCloudTop) {',
|
||||
'tEnter = minPositiveRoot(top);',
|
||||
'tExit = maxPositiveRoot(bot);',
|
||||
'if (tExit < 0.0) tExit = maxPositiveRoot(top);',
|
||||
'} else {',
|
||||
'tEnter = minPositiveRoot(bot);',
|
||||
'tExit = maxPositiveRoot(top);',
|
||||
'if (tExit < 0.0) tExit = maxPositiveRoot(bot);',
|
||||
'}',
|
||||
'if (tEnter > 1e8 || tExit <= tEnter) { tEnter = 0.0; tExit = 14.0; }',
|
||||
'if (tTerrain > 0.0 && tEnter > tTerrain) discard;',
|
||||
'if (tTerrain > 0.0) tExit = min(tExit, tTerrain);',
|
||||
// A grazing ray would sample a path of well over a thousand km with
|
||||
// only 24 steps - coarse blobs along the horizon. Past this length
|
||||
// the deck is inside the haze anyway, so the march stops there.
|
||||
'tExit = min(tExit, tEnter + 18.0);',
|
||||
'float stepSize = max(0.0, (tExit - tEnter) / 24.0);',
|
||||
'float t = tEnter + stepSize * (0.5 + ign(gl_FragCoord.xy));',
|
||||
'vec3 cloudSum = vec3(0.0);',
|
||||
'float trans = 1.0;',
|
||||
'for (int i = 0; i < 24; i++) {',
|
||||
'vec3 p = ro + rd * t;',
|
||||
'p.y += (ign(gl_FragCoord.xy + vec2(float(i) * 7.13, float(i) * 3.71)) - 0.5) * stepSize * 0.35;',
|
||||
'float py = p.y + earthDrop(p.xz);',
|
||||
'if (py > uCloudTop || py < uCloudBot - 0.1) break;',
|
||||
'if (tTerrain > 0.0 && t >= tTerrain) break;',
|
||||
'float cSoft = smoothstep(4.0, 18.0, t);',
|
||||
'float d = cloudDensity(p, baseThresh, cSoft);',
|
||||
'if (d > 0.02) {',
|
||||
'float lit = clamp((py - uCloudBot) / ((uCloudTop - uCloudBot) * 1.167), 0.0, 1.0);',
|
||||
'vec3 cloudCol;',
|
||||
'if (uPhysical > 0.5) {',
|
||||
// The night palette colours are already darkened for
|
||||
// night, and multiplying them by the night light would
|
||||
// double-darken into invisibility. Physical mode
|
||||
// therefore uses a brightness-normalised albedo (theme
|
||||
// hue kept, brightness from the light model) and lets
|
||||
// the vertical gradient act as a shading ramp.
|
||||
'vec3 albC = uCloudAlbedo * mix(0.78, 1.0, lit);',
|
||||
// Self-shading: probe the density towards the sun, so
|
||||
// thick cloud interior stays dark and thin edges light up.
|
||||
// d > 0.85 already clamps selfLit to its floor, so the
|
||||
// second density lookup (a whole fbm) is skipped there.
|
||||
'float thick = (d > 0.85) ? 1.0 :',
|
||||
'cloudDensity(p + uSunDir * 2.2, baseThresh, cSoft);',
|
||||
'float selfLit = clamp(1.0 - thick * 1.3, 0.12, 1.0);',
|
||||
// Forward scattering - clouds brighten towards the sun
|
||||
// (silver lining) instead of a flat day/night ramp.
|
||||
'float cosT = dot(rd, -uSunDir);',
|
||||
'float phase = 0.30 + 0.70 * pow(max(0.0, cosT), 2.5);',
|
||||
'vec3 direct = albC * uSunColor * phase * uSunInt * selfLit;',
|
||||
// A cloud deck is a bright, thick scatterer: it catches
|
||||
// the whole diffuse column (skylight, starlight) and
|
||||
// stands clearly above the dark sky at night.
|
||||
'vec3 ambC = albC * max(vec3(uSkyAmb), uStarAmb * vec3(0.75, 0.85, 1.0)) * 1.7;',
|
||||
'vec3 moonC = albC * uMoonColor * (0.35 + 0.65 * max(0.0, dot(rd, uMoonDir))) * uMoonInt * 3.0;',
|
||||
'cloudCol = direct + ambC + moonC;',
|
||||
'} else {',
|
||||
'cloudCol = mix(uCloudShadow, uCloud, lit);',
|
||||
'cloudCol = mix(cloudCol, uLight, max(0.15, uDayProgress) * 0.35 * lit);',
|
||||
'}',
|
||||
'float alpha = clamp(d * stepSize * 1.30, 0.0, 1.0);',
|
||||
'cloudSum += cloudCol * alpha * trans;',
|
||||
'trans *= (1.0 - alpha);',
|
||||
'if (trans < 0.04) break;',
|
||||
'}',
|
||||
't += stepSize;',
|
||||
'}',
|
||||
'float cloudAlpha = 1.0 - trans;',
|
||||
'vec3 cloudColor = (cloudAlpha > 0.001) ? cloudSum / cloudAlpha : vec3(0.0);',
|
||||
// Aerial perspective for the deck too: a distant cloud is seen
|
||||
// through its own air column, so it dissolves into the same airlight
|
||||
// the ground fades into. Without it the far clouds keep full contrast
|
||||
// and the horizon reads as stacked bands.
|
||||
// A cloud at 12 km looks through far less air than the ground at the
|
||||
// horizon, so this uses its own much smaller factor, a desaturated
|
||||
// haze colour (not the saturated blue) and a hard cap: distant cloud
|
||||
// loses contrast, it does not turn blue.
|
||||
'if (uPhysical > 0.5 && cloudAlpha > 0.001) {',
|
||||
'float cTau = uAirDensity * min(tExit, 60.0) * uCloudHaze;',
|
||||
'float cHaze = min(0.55, 1.0 - exp(-cTau));',
|
||||
'vec3 airAvg = vec3(dot(uAirColor, vec3(0.3333)));',
|
||||
'vec3 hazeCol = mix(uAirColor, airAvg, 0.55);',
|
||||
'float cosTA = dot(rd, uSunDir);',
|
||||
'float phaseA = 0.5 + 0.5 * cosTA * cosTA;',
|
||||
'cloudColor = mix(cloudColor, hazeCol * phaseA, cHaze);',
|
||||
'}',
|
||||
'gl_FragColor = vec4(cloudColor, cloudAlpha);',
|
||||
'if (uMode == 1) { gl_FragColor = vec4(0.0); return; }',
|
||||
'}'
|
||||
].join('\n');
|
||||
|
||||
@@ -6389,26 +6272,6 @@ window.clouds3dRender = function(target) {
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Cloud pass (uMode = 1) --------------------------------------
|
||||
// Alpha-blend over the framebuffer (terrain mesh + sky+stars).
|
||||
// Depth test/write OFF — the manual discard in the cloud shader
|
||||
// (tCloudTop > tTerrain) handles cloud-behind-mesh occlusion, and
|
||||
// the depth values from the full-screen quad would only confuse the
|
||||
// alpha blend.
|
||||
gl.useProgram(s.prog);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, s.buf);
|
||||
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.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
gl.uniform1i(s.uMode, 1);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
if (ATMO_MODEL_ON) {
|
||||
gl.uniform1i(s.uMode, 2);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
Reference in new issue
Block a user