mapspinner 0.1.43 → 0.1.45

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.43",
3
+ "version": "0.1.45",
4
4
  "description": "WebGL2 Earth-scale terrain rendering SDK for interactive globe applications",
5
5
  "main": "src/index.js",
6
6
  "exports": {
package/src/gl-render.js CHANGED
@@ -421,7 +421,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
421
421
  gl.uniform1f(loc('vtxDetail'), g('vtxDetail', 1.0)); // DECISIVE: vtxDisplace strength (early-return on 0)
422
422
  gl.uniform1f(loc('canyonDepthMul'), g('canyonDepth', 1.0));
423
423
  gl.uniform1f(loc('uVsCheap'), (typeof window!=='undefined' && window.__vsCheap) ? 1.0 : 0.0); // VS carve-cost profiling A/B
424
- gl.uniform1f(loc('uBeachShelfM'), g('beachShelf', 2400.0)); // land coastal shelf (geometry); probe MUST match render
424
+ gl.uniform1f(loc('uBeachShelfM'), g('beachShelf', 12000.0)); // land coastal shelf (geometry); probe MUST match render
425
425
  gl.uniform1f(loc('cliffAmt'), g('cliffAmt', 1.0));
426
426
  gl.uniform1i(loc('uFloatLinearOK'), _halfFloatLinearOK ? 1 : 0);
427
427
  // FXC unroll-defeat (2026-06-12 AMD d3d11 fix): runtime octave bound for broadShapeM; the shader
@@ -960,7 +960,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
960
960
  const _g = (n,d)=> (typeof window!=='undefined' && window['__'+n]!=null) ? +window['__'+n] : d;
961
961
  gl.uniform1f(U('canyonDepthMul'), _g('canyonDepth', 1.0));
962
962
  gl.uniform1f(U('uVsCheap'), (typeof window!=='undefined' && window.__vsCheap) ? 1.0 : 0.0); // VS carve-cost profiling A/B
963
- gl.uniform1f(U('uBeachShelfM'), _g('beachShelf', 2400.0)); // land coastal shelf (geometry): h<S eased h*h/S = wide beach
963
+ gl.uniform1f(U('uBeachShelfM'), _g('beachShelf', 12000.0)); // land coastal shelf (geometry): h<S eased h*h/S = wide beach
964
964
  gl.uniform1f(U('uHiFreqCut'), _g('hiFreqCut', 0.25)); // 0.5->0.25 (2026-06-10 'blotchy' -- see setComposeHeightUniforms)
965
965
  gl.uniform1f(U('uVertexAO'), _g('vertexAO', 1.0)); // per-vertex shading/AO strength (DEFECT 2, 2026-06-06)
966
966
  gl.uniform1f(U('cliffAmt'), _g('cliffAmt', 1.0));
@@ -1039,7 +1039,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
1039
1039
  gl.uniform1f(U('oceanAmp'), (oc.oceanAmplitude != null) ? oc.oceanAmplitude : 1.0);
1040
1040
  gl.uniform1f(U('oceanChoppy'), (oc.oceanChoppiness != null) ? oc.oceanChoppiness : 0.5);
1041
1041
  gl.uniform1f(U('oceanFoam'), (oc.oceanFoam != null) ? oc.oceanFoam : 0.5);
1042
- gl.uniform1f(U('uBeachTopM'), _g('beachTop', 140.0)); // beach ceiling: grass stops, sand to the waterline + under it. 30->90 (user 2026-06-14: 3x beach width)
1042
+ gl.uniform1f(U('uBeachTopM'), _g('beachTop', 420.0)); // beach ceiling: grass stops, sand to the waterline + under it. 30->90 (user 2026-06-14: 3x beach width)
1043
1043
 
1044
1044
  // SINGLE INSTANCED DRAW: the deform params that were per-quad uniforms (ox,oy,l,level + face)
1045
1045
  // are now PER-INSTANCE attributes. Build one interleaved instance buffer [ox,oy,l,level,face]
@@ -1109,7 +1109,12 @@ export async function initMapspinnerRender(gl, opts = {}) {
1109
1109
  // seabed, so the depth test culled the water across entire shorelines. Level-9 cells
1110
1110
  // (~1.6km) sag ~5cm, far under any visible bathymetry, still ~16-64x fewer water verts
1111
1111
  // than the deep terrain leaves.
1112
- const WCAP = 9;
1112
+ // WCAP 9 -> 11 (user 2026-06-14 'water lines still jagged and square, doesnt meet land properly'):
1113
+ // the water-pass `if(vH>1.0) discard` keys off the water mesh's COARSE interpolated seabed height,
1114
+ // so the discarded waterline stepped at ~1.6km (level-9) cells = square/jagged edges that didn't
1115
+ // follow the fine seabed coastline. Level-11 cells (~400m) -> ~4x finer waterline. Water-vertex
1116
+ // cost rises (watch FPS); still far fewer verts than the full-LOD terrain leaves.
1117
+ const WCAP = 11;
1113
1118
  // OWN persistent buffer (instBufWater) + static-frame skip: on an unchanged quad set, reuse the
1114
1119
  // cached water instances (skip the dedup Set-loop + Float32Array + bufferData). Separate buffer
1115
1120
  // means the terrain pass never clobbers it (the prior water-as-terrain regression root).
@@ -623,7 +623,14 @@ highp float composeHeight(vec3 dir0, highp vec2 faceLocal, float tileM){ // W7
623
623
  // SLOPE down to the abyssal plain (which keeps its raw depth). Monotone remap of h, pure fn of
624
624
  // the field -> seam-safe, LOD-invariant, and the collision probe shares it by construction.
625
625
  if (h < 0.0) {
626
- highp float d = -h;
626
+ // C1 WATERLINE (user 2026-06-14 'geometry crease + shading/rock hard line where land meets beach'):
627
+ // the land shelf is FLAT at the waterline (slope 0) but the seabed used slope 0.24 from h=0 -> a
628
+ // slope discontinuity = a crease (+ the shading brightness line + rock where steep) right at the
629
+ // shore. Ease the shallow seabed with the SAME flat-at-waterline shelf curve (mirror of the land
630
+ // side) before the 0.24/1.19 bathymetry, so BOTH sides meet the waterline with slope 0 = no crease.
631
+ highp float bShelfS = uBeachShelfM > 1.0 ? uBeachShelfM : 600.0;
632
+ highp float d0 = -h;
633
+ highp float d = (d0 < bShelfS) ? (d0 * d0 / bShelfS) * (2.0 - d0 / bShelfS) : d0;
627
634
  h = -(min(d, 500.0) * 0.24 + max(d - 500.0, 0.0) * 1.19);
628
635
  h = max(h, -11000.0); // cap depth at Mariana Trench (~11km)
629
636
  } else {
@@ -852,7 +859,9 @@ void main() {
852
859
  // shelf/slope bathymetry remap + underwater displacement -- MUST mirror composeHeight exactly
853
860
  // (this is the FS-material running value; composeHeight is the geometry/probe height).
854
861
  if (vH < 0.0) {
855
- highp float dSea = -vH;
862
+ highp float bShelfS = uBeachShelfM > 1.0 ? uBeachShelfM : 600.0; // C1 waterline -- mirror composeHeight exactly
863
+ highp float dSea0 = -vH;
864
+ highp float dSea = (dSea0 < bShelfS) ? (dSea0 * dSea0 / bShelfS) * (2.0 - dSea0 / bShelfS) : dSea0;
856
865
  vH = -(min(dSea, 500.0) * 0.24 + max(dSea - 500.0, 0.0) * 1.19);
857
866
  vH = max(vH, -11000.0); // cap depth at Mariana Trench (~11km)
858
867
  } else {
@@ -1579,8 +1588,13 @@ void main() {
1579
1588
  mappedW = clamp((mappedW - 0.5) * uLookContrast + 0.5, 0.0, 1.0);
1580
1589
  // coverage: optically thick water -> opaque; first metres see-through; grazing fresnel and
1581
1590
  // foam are opaque regardless of depth; feather the exact waterline contact.
1591
+ // THIN WATER STAYS CLEAR (user 2026-06-14 'water isnt transparent where its thin'): the grazing
1592
+ // fresnel forced shallow water OPAQUE even looking across a shoreline. Gate fresnel opacity by a
1593
+ // depth ramp so thin water shows the bed regardless of view angle; foam + Beer-Lambert depth
1594
+ // opacity stay so deep/foamy water still reads solid.
1595
+ float shallowClear = smoothstep(0.0, 6.0, depthM); // 0 in thin water -> clear; 1 by ~6m -> full fresnel
1582
1596
  float alphaW = clamp(1.0 - Tavg, 0.0, 1.0);
1583
- alphaW = max(alphaW, fres * 0.9);
1597
+ alphaW = max(alphaW, fres * 0.9 * shallowClear);
1584
1598
  alphaW = max(alphaW, foamAmt * 0.8);
1585
1599
  // SHALLOW-SURFACE FLOOR (2026-06-11, found by the coast witness after the shelf landed):
1586
1600
  // the continental shelf keeps water metres-deep for kilometres, where Beer-Lambert alpha