mapspinner 0.1.71 → 0.1.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapspinner",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "description": "WebGL2 Earth-scale terrain rendering SDK for interactive globe applications",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -223,7 +223,7 @@ uniform float uMtnBandWide; // widen mtn=smoothstep(16.8,18.6,ele
223
223
  uniform float uClimateRelief; // widen wetLowFlat(0.66,0.9,humid) + coldFlat(0.18,0.34,temp) reliefMul gates
224
224
  uniform float uIsleWide; // widen isleZone seaBias gates (50,350)+(900,1600) -> (30,600)+(600,2200)
225
225
  uniform float uCarveWide; // widen the river/canyon/lake/dune CLIMATE gates so carve depth fades in over a wide span
226
- float canyonRidgeField(vec3 dir){ return inciseRidgeField(normalize(dir) + vec3(13.7, -4.2, 8.9), 380.0, 2.07); } // phase offset matches FS canyonMask. baseFreq 380 = ~100km gorge network (user 2026-06-14: doubled 380->760 to restore deck-visible canyons after a 380->96 regression that put gorges ~400km apart = 'missing', then HALVED 760->380 back to the ~100km baseline). Shared VS carve + FS mask -> congruent by construction.
226
+ float canyonRidgeField(vec3 dir){ return inciseRidgeField(normalize(dir) + vec3(13.7, -4.2, 8.9), 190.0, 2.07); } // phase offset matches FS canyonMask. baseFreq 190 = ~200km gorge network (user 2026-06-14: HALVED 380->190 = fewer, wider-spaced gorges, easier for the coarse grid to represent). Shared VS carve + FS mask -> congruent by construction.
227
227
  // CANYON cross-section now reads as a CANYON, not a V-notch: STEEP WALLS + a FLAT FLOOR.
228
228
  // wall = a sharp smoothstep band -> the carve drops fast over a narrow ridge interval (the cliff
229
229
  // walls), instead of the old gentle bench+gorge blend that made shallow V-troughs.
@@ -235,9 +235,12 @@ float canyonCarveM(vec3 dir, out float depth){
235
235
  // WIDENED bands (user 2026-06-02 deepen+widen): the old .78/.86/.905/.93 intervals were a very
236
236
  // narrow ridge slice -> thin hairline gorges. Widen so the canyon reads as a BROAD gorge: a wide
237
237
  // eroded rim shoulder, a steep but visible wall, and a wide flat floor that the gorge bottoms out on.
238
- float bench = smoothstep(0.62, 0.78, ridge); // wide eroded rim shoulder
239
- float wall = smoothstep(0.70, 0.86, ridge); // STEEP cliff wall (wider band)
240
- float floorF= smoothstep(0.80, 0.93, ridge); // reach the flat gorge floor, then clamp
238
+ // GENTLER WALLS (user 2026-06-14 'make canyon slopes more gentle, easier for the rough grid to
239
+ // represent'): widen every band so the same depth descends over a wider ridge interval = lower
240
+ // gradient -> the coarse LOD grid samples the wall without aliasing the cliff.
241
+ float bench = smoothstep(0.50, 0.74, ridge); // wide eroded rim shoulder
242
+ float wall = smoothstep(0.58, 0.90, ridge); // gentle cliff wall (wide band)
243
+ float floorF= smoothstep(0.72, 0.96, ridge); // reach the flat gorge floor, then clamp
241
244
  depth = max(wall, floorF);
242
245
  // 0.18 rim shoulder + 0.82 wall-to-floor; floorF clamps so the bottom is flat (no infinite V).
243
246
  float profile = 0.18 * bench + 0.82 * max(wall, floorF);
@@ -703,7 +706,11 @@ highp float composeHeight(vec3 dir0, highp vec2 faceLocal, float tileM){ // W7
703
706
  h += cliffCarveV;
704
707
  // FLAT RIVER WATER
705
708
  float riverWetLine = riverWetMask * riverWet * step(0.0, h);
706
- if (riverWetLine > 0.0) { float rWaterLevel = h - 20.0; h = mix(h, rWaterLevel, riverWetLine); vDisp *= (1.0 - riverWetLine); }
709
+ // DEEPER, GENTLER-APPROACH CHANNEL WATER (user 2026-06-14 'water in canyons very shallow, base flat,
710
+ // angle of approach to the base far too sharp'): drop the channel bed 20->70m so the water is deep
711
+ // enough to read, and use riverWetLine^0.6 as the carve weight so the bed eases DOWN over a wider
712
+ // margin (concave approach) instead of plunging at the wet edge.
713
+ if (riverWetLine > 0.0) { float rw = pow(riverWetLine, 0.6); float rWaterLevel = h - 70.0; h = mix(h, rWaterLevel, rw); vDisp *= (1.0 - rw); }
707
714
  // DUNES on the low sand desert
708
715
  float duneSand = smoothstep(mix(0.62, 0.50, uCarveWide), mix(0.85, 0.95, uCarveWide), 1.0 - hpf0.a) * smoothstep(mix(0.40, 0.30, uCarveWide), mix(0.58, 0.68, uCarveWide), hpf0.b) * (1.0 - smoothstep(40.0, 160.0, h));
709
716
  float duneCrest; float duneV = duneFieldM(dir0, duneCrest) * duneSand * step(0.0, h);
@@ -938,12 +945,14 @@ void main() {
938
945
  // water level + suppress the micro-displacement on the wet line. riverWetMask is the thalweg mask.
939
946
  float riverWetLine = riverWetMask * riverWet * step(0.0, vH);
940
947
  if (riverWetLine > 0.0) {
941
- highp float rWaterLevel = vH - 20.0; // W7: metres
948
+ // MIRROR of composeHeight (deeper 20->70m channel + pow(.,0.6) gentler concave approach)
949
+ float rw = pow(riverWetLine, 0.6);
950
+ highp float rWaterLevel = vH - 70.0; // W7: metres
942
951
  highp float rFloorBefore = vH;
943
- vH = mix(vH, rWaterLevel, riverWetLine);
944
- vDisp *= (1.0 - riverWetLine); // no micro-bumps on the river surface
952
+ vH = mix(vH, rWaterLevel, rw);
953
+ vDisp *= (1.0 - rw); // no micro-bumps on the river surface
945
954
  // record the deeper/stronger of lake|river as the water surface for vWaterDepth
946
- if (riverWetLine > haveWater) { waterPlane = rWaterLevel; floorBefore = rFloorBefore; haveWater = riverWetLine; }
955
+ if (rw > haveWater) { waterPlane = rWaterLevel; floorBefore = rFloorBefore; haveWater = rw; }
947
956
  }
948
957
  // DUNES on the SAND DESERT (very dry + warm + LOW land): rolling dune relief replaces harsh rock
949
958
  // here (ref: webgl-dunes). Gated opposite to canyons (which want elevated arid plateaus) -- dunes
@@ -1780,6 +1789,7 @@ void main() {
1780
1789
  // vH > -2 gate cut the photo textures at the waterline, leaving the seabed flat-colored.
1781
1790
  float texFarFade = 1.0 - smoothstep(8000.0, 10000.0, pxWorld);
1782
1791
  if (uHasSurfTex > 0.5 && uTexMix > 0.001 && texFarFade > 0.001) {
1792
+ vec3 biomeC = albedo; // SUBTLE landscape color variation (user 2026-06-14 're-introduce ... use existing data, make it subtle'): the macro biome/climate color is ALREADY computed; save it now and mix a touch back after the material override (no new computation).
1783
1793
  // material weights from the existing gates (climate = vClimate: z=temp, w=humid)
1784
1794
  // SAND GATE = THE MACRO DESERT GATE (user 2026-06-11 'all the grassy areas need to have the
1785
1795
  // grass texture'): the old humid<0.42 band splatted SAND across savanna/steppe/meadow-edge
@@ -1908,7 +1918,10 @@ void main() {
1908
1918
  highp vec3 wt4 = wt * 4.0;
1909
1919
  vec4 albA = surfTriTap(uSurfAlb, wt4, tw, lA);
1910
1920
  vec3 cA = vec3(dot(albA.rgb, LUMA));
1911
- vec3 nA = surfTriNrm(uSurfNrm, wt4, tw, lA, n) * 1.4 + surfTriNrm(uSurfNrm, wt, tw, lA, n) * 0.8; // high + low-octave normal
1921
+ // 3 normal octaves (user 2026-06-14 'add an even lower freq octave, displacement/normals only,
1922
+ // 4x less frequent'): wt4 high (detail) + wt low (2.4km) + wt*0.25 VERY-low (9.6km) -- the very-
1923
+ // low one breaks the far repetition even more. Normals/displacement only (no albedo).
1924
+ vec3 nA = surfTriNrm(uSurfNrm, wt4, tw, lA, n) * 1.4 + surfTriNrm(uSurfNrm, wt, tw, lA, n) * 0.8 + surfTriNrm(uSurfNrm, wt * 0.25, tw, lA, n) * 2.4; // very-low octave UP 0.55->2.4 (user 2026-06-14 'dont really see the lower freq octave yet'): at a 9.6km period its slope is gentle, so it needs more weight to read as broad undulation
1912
1925
  float dispA = albA.a;
1913
1926
  // NO BIOME COLOR INHERITANCE (user 2026-06-14 'take away all biome color inheritance, it will
1914
1927
  // speed it up' -- and fixes 'sand near grass tinted green'): each layer wears its OWN material
@@ -1920,7 +1933,7 @@ void main() {
1920
1933
  if (wB > 0.02) { // second layer only where a real transition exists
1921
1934
  vec4 albB = surfTriTap(uSurfAlb, wt4, tw, lB);
1922
1935
  vec3 cB = vec3(dot(albB.rgb, LUMA));
1923
- vec3 nB = surfTriNrm(uSurfNrm, wt4, tw, lB, n) * 1.4 + surfTriNrm(uSurfNrm, wt, tw, lB, n) * 0.8; // high + low-octave normal
1936
+ vec3 nB = surfTriNrm(uSurfNrm, wt4, tw, lB, n) * 1.4 + surfTriNrm(uSurfNrm, wt, tw, lB, n) * 0.8 + surfTriNrm(uSurfNrm, wt * 0.25, tw, lB, n) * 2.4; // very-low octave UP 0.55->2.4 (match nA)
1924
1937
  float dispB = albB.a;
1925
1938
  // HEIGHT-BLEND POKE-THROUGH (user 'each texture's higher areas should poke through the other,
1926
1939
  // offset by the ramp'): height = displacement + a weight-ramp offset (gate positions the
@@ -1953,8 +1966,10 @@ void main() {
1953
1966
  // grass/sand interlocks (fingers) at ALL distances -- still the texture DISPLACEMENT, not noise.
1954
1967
  float dispA_lo = surfTriTap(uSurfAlb, wt, tw, lA).a;
1955
1968
  float dispB_lo = surfTriTap(uSurfAlb, wt, tw, lB).a;
1956
- float hA = (dispA - 0.5) * 1.8 + (dispA_lo - 0.5) * 2.8 + wRamp + ordA * 0.45;
1957
- float hB = (dispB - 0.5) * 1.8 + (dispB_lo - 0.5) * 2.8 - wRamp + ordB * 0.45;
1969
+ float dispA_vlo = surfTriTap(uSurfAlb, wt * 0.25, tw, lA).a; // very-low (9.6km) displacement -> even-larger-scale boundary undulation (less repetitive far)
1970
+ float dispB_vlo = surfTriTap(uSurfAlb, wt * 0.25, tw, lB).a;
1971
+ float hA = (dispA - 0.5) * 1.5 + (dispA_lo - 0.5) * 2.2 + (dispA_vlo - 0.5) * 2.2 + wRamp + ordA * 0.45;
1972
+ float hB = (dispB - 0.5) * 1.5 + (dispB_lo - 0.5) * 2.2 + (dispB_vlo - 0.5) * 2.2 - wRamp + ordB * 0.45;
1958
1973
  float mh = max(hA, hB) - bw;
1959
1974
  float waH = max(hA - mh, 0.0), wbH = max(hB - mh, 0.0);
1960
1975
  float bSharp = waH / max(waH + wbH, 1e-4);
@@ -2006,12 +2021,24 @@ void main() {
2006
2021
  // base = flat MATERIAL color (far/low-k); near = structured detail. The macro biome albedo is no
2007
2022
  // longer the base, so NO biome color bleeds into the ground (user 'take away all biome inheritance').
2008
2023
  albedo = clamp(mix(texMatColor, detail, k), 0.0, 1.0);
2024
+ albedo = mix(albedo, biomeC, 0.68); // climate/biome tint back on top of the material color (deserts tanner, forests greener) -- UP 0.16->0.68 (user 2026-06-14 x2 'tinting-according-to-landscape can be intensified, not really visible yet')
2009
2025
  // FAKE MIDDAY AO from the displacement (user 2026-06-14 'darken the deepest parts of the
2010
2026
  // displacement textures a little'): the texture's LOWEST displacement = crevices/pits; darken
2011
2027
  // them ~18% so the surface reads as sunlit-from-above with soft self-occlusion in the lows.
2012
2028
  // Faded by k so the far field (where the texture mips out) is untouched.
2013
- float texAO = mix(1.0, mix(0.82, 1.0, smoothstep(0.0, 0.5, texAlb.a)), k);
2029
+ // STRONGER fake-midday AO (user 2026-06-14 'should be more intense, we dont really see it'):
2030
+ // darken the recesses harder (0.82->0.5 = up to 50%) over a wider low-displacement range so the
2031
+ // crevices/pits read clearly. Still faded by k so the mipped far field is untouched.
2032
+ float texAO = mix(1.0, mix(0.5, 1.0, smoothstep(0.05, 0.6, texAlb.a)), k);
2014
2033
  albedo *= texAO;
2034
+ // ELEVATION AO (user 2026-06-14 'similar AO on elevation'): the macro analog of the displacement
2035
+ // AO -- darken CONCAVE relief (valley floors, gorges, recesses) using the screen-space CURVATURE
2036
+ // of the lit normal. curv = d(normal).d(position) / |d(position)|^2 -> +ve where the surface
2037
+ // curves into a pit (concave), -ve on ridges. Cheap (fwidth of the already-computed vNrm/vWorld).
2038
+ highp vec3 ddxP = dFdx(vWorld), ddyP = dFdy(vWorld);
2039
+ float curv = (dot(dFdx(vNrm), ddxP) + dot(dFdy(vNrm), ddyP)) / max(dot(ddxP, ddxP) + dot(ddyP, ddyP), 0.01);
2040
+ float elevAO = 1.0 - clamp(curv * 420.0, 0.0, 0.65); // concave -> darken up to 65% (user 2026-06-14 x2 'elevation based ao not visible yet': macro relief curvature is small-magnitude, needs big gain 45->420)
2041
+ albedo *= elevAO;
2015
2042
  // displacement-normal relief: WORLD-SPACE UDN perturbation from surfTriNrm (each projection
2016
2043
  // plane's tangent axes, not the radial frame). Amplitude capped low (scramble lesson d262b5e);
2017
2044
  // applied AFTER the uReliefShade exaggeration below so the exaggeration never amplifies it.