clouds: fix terrain clipping with curved occlusion
This commit is contained in:
1 parent
d59df7f4d1
commit
c546879b98
1 file changed
+15
-8
Vendored
+15
-8
@@ -180,17 +180,18 @@ var FRAG_SRC = [
|
|||||||
'return dot(d, d) / (2.0 * max(1.0, uEarthRadius));',
|
'return dot(d, d) / (2.0 * max(1.0, uEarthRadius));',
|
||||||
'}',
|
'}',
|
||||||
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
||||||
'float n = fbm3(p * 0.35 + vec3(0.0, 0.0, uTime * 0.06));',
|
'float py = p.y + earthDrop(p.xz);',
|
||||||
|
'vec3 cp = vec3(p.x, py, p.z);',
|
||||||
|
'float n = fbm3(cp * 0.35 + vec3(0.0, 0.0, uTime * 0.06));',
|
||||||
// The detail octave weighs at most 0.20 and fades to zero with
|
// The detail octave weighs at most 0.20 and fades to zero with
|
||||||
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
||||||
// 4-octave lookup is skipped for the (numerous) far samples.
|
// 4-octave lookup is skipped for the (numerous) far samples.
|
||||||
'if (soft < 0.95) {',
|
'if (soft < 0.95) {',
|
||||||
'float d = fbm3(p * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));',
|
'float d = fbm3(cp * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));',
|
||||||
'n = n + d * mix(0.20, 0.0, soft);',
|
'n = n + d * mix(0.20, 0.0, soft);',
|
||||||
'}',
|
'}',
|
||||||
// Cloud layer between uCloudBot and uCloudTop, densest in the
|
// Cloud layer between uCloudBot and uCloudTop, densest in the
|
||||||
// middle (bell curve). The layer follows the Earth curvature.
|
// middle (bell curve). The layer follows the Earth curvature.
|
||||||
'float py = p.y + earthDrop(p.xz);',
|
|
||||||
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
||||||
'float profile = 4.0 * h * (1.0 - h); // bell curve',
|
'float profile = 4.0 * h * (1.0 - h); // bell curve',
|
||||||
'profile = max(profile, 0.0);',
|
'profile = max(profile, 0.0);',
|
||||||
@@ -429,11 +430,15 @@ var FRAG_SRC = [
|
|||||||
// ---- CLOUDS pass ----
|
// ---- CLOUDS pass ----
|
||||||
// Ray-terrain intersection (used to discard clouds that are
|
// Ray-terrain intersection (used to discard clouds that are
|
||||||
// entirely behind the terrain mesh).
|
// entirely behind the terrain mesh).
|
||||||
'float tTerrain = (ro.y > 0.0 && rd.y < -0.001) ? -ro.y / rd.y : -1.0;',
|
'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;',
|
||||||
'if (tTerrain > 0.0 && uElevOn > 0.5 && rd.y < -0.01) {',
|
'if (tTerrain > 0.0 && uElevOn > 0.5 && rd.y < -0.01) {',
|
||||||
'for (int ti = 0; ti < 4; ti++) {',
|
'for (int ti = 0; ti < 4; ti++) {',
|
||||||
'vec3 hp = ro + rd * tTerrain;',
|
'vec3 hp = ro + rd * tTerrain;',
|
||||||
'float dh = terrElev(hp.xz) * uElevScale - hp.y;',
|
'float terrainY = terrElev(hp.xz) * uElevScale - earthDrop(hp.xz);',
|
||||||
|
'float dh = terrainY - hp.y;',
|
||||||
'if (abs(dh) < 0.02) break;',
|
'if (abs(dh) < 0.02) break;',
|
||||||
'tTerrain += dh / -rd.y;',
|
'tTerrain += dh / -rd.y;',
|
||||||
'if (tTerrain < 0.1 || tTerrain > 90.0) { tTerrain = -1.0; break; }',
|
'if (tTerrain < 0.1 || tTerrain > 90.0) { tTerrain = -1.0; break; }',
|
||||||
@@ -484,6 +489,7 @@ var FRAG_SRC = [
|
|||||||
'p.y += (ign(gl_FragCoord.xy + vec2(float(i) * 7.13, float(i) * 3.71)) - 0.5) * stepSize;',
|
'p.y += (ign(gl_FragCoord.xy + vec2(float(i) * 7.13, float(i) * 3.71)) - 0.5) * stepSize;',
|
||||||
'float py = p.y + earthDrop(p.xz);',
|
'float py = p.y + earthDrop(p.xz);',
|
||||||
'if (py > uCloudTop || py < uCloudBot - 0.1) break;',
|
'if (py > uCloudTop || py < uCloudBot - 0.1) break;',
|
||||||
|
'if (uElevOn > 0.5 && py < terrElev(p.xz) * uElevScale) break;',
|
||||||
'if (tTerrain > 0.0 && t >= tTerrain) break;',
|
'if (tTerrain > 0.0 && t >= tTerrain) break;',
|
||||||
'float cSoft = smoothstep(7.0, 20.0, t);',
|
'float cSoft = smoothstep(7.0, 20.0, t);',
|
||||||
'float d = cloudDensity(p, baseThresh, cSoft);',
|
'float d = cloudDensity(p, baseThresh, cSoft);',
|
||||||
@@ -679,15 +685,16 @@ var CLOUD_SAMPLER_GLSL = [
|
|||||||
'return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));',
|
'return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));',
|
||||||
'}',
|
'}',
|
||||||
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
'float cloudDensity(vec3 p, float baseThresh, float soft) {',
|
||||||
'float n = fbm3(p * 0.35 + vec3(0.0, 0.0, uTime * 0.06));',
|
'float py = p.y + earthDrop(p.xz);',
|
||||||
|
'vec3 cp = vec3(p.x, py, p.z);',
|
||||||
|
'float n = fbm3(cp * 0.35 + vec3(0.0, 0.0, uTime * 0.06));',
|
||||||
// The detail octave weighs at most 0.20 and fades to zero with
|
// The detail octave weighs at most 0.20 and fades to zero with
|
||||||
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
// distance; past soft = 0.95 it contributes under 1 %, so the whole
|
||||||
// 4-octave lookup is skipped for the (numerous) far samples.
|
// 4-octave lookup is skipped for the (numerous) far samples.
|
||||||
'if (soft < 0.95) {',
|
'if (soft < 0.95) {',
|
||||||
'float d = fbm3(p * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));',
|
'float d = fbm3(cp * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));',
|
||||||
'n = n + d * mix(0.20, 0.0, soft);',
|
'n = n + d * mix(0.20, 0.0, soft);',
|
||||||
'}',
|
'}',
|
||||||
'float py = p.y + earthDrop(p.xz);',
|
|
||||||
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
'float h = clamp((py - uCloudBot) / (uCloudTop - uCloudBot), 0.0, 1.0);',
|
||||||
'float profile = 4.0 * h * (1.0 - h);',
|
'float profile = 4.0 * h * (1.0 - h);',
|
||||||
'profile = max(profile, 0.0);',
|
'profile = max(profile, 0.0);',
|
||||||
|
|||||||
Reference in new issue
Block a user