mapspinner 0.1.42 → 0.1.44
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 +1 -1
- package/src/gl-render.js +22 -3
- package/src/shaders/terrain.glsl +13 -3
package/package.json
CHANGED
package/src/gl-render.js
CHANGED
|
@@ -780,7 +780,14 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
780
780
|
const camDist = Math.hypot(cam.eye[0], cam.eye[1], cam.eye[2]);
|
|
781
781
|
const alt = Math.max(0.0, camDist - R);
|
|
782
782
|
const altAboveTerrain = Math.max(0.001, alt - R * (cam.surfElev || 0));
|
|
783
|
-
|
|
783
|
+
// FAR-PLANE HORIZON RADIUS = R - 500m (user 2026-06-14: 'nearby mountains disappear at water level;
|
|
784
|
+
// adjust that level to 500m under water'). The far plane tracks the sea-level horizon = sqrt(camDist^2
|
|
785
|
+
// - R^2), which at the deck (camDist~=R) collapses to a few hundred metres -> coastal mountains a km
|
|
786
|
+
// out fall beyond the far plane and vanish. Dropping the horizon reference radius 500m below sea level
|
|
787
|
+
// extends the horizon to tens of km at low altitude so near-shore relief stays in view (negligible
|
|
788
|
+
// depth-precision cost: 500m vs R~6.37e6). Both the cull and the draw use this (single source).
|
|
789
|
+
const RHORIZON = R - 500.0;
|
|
790
|
+
const horizon = Math.sqrt(Math.max(0.0, camDist*camDist - RHORIZON*RHORIZON));
|
|
784
791
|
// MATCH render()'s near exactly (2026-06-14 jank fix): the cull frustum must use the SAME near
|
|
785
792
|
// as the draw frustum, else behind-limb/screen-AABB culling diverges from what is actually drawn
|
|
786
793
|
// at the deck (cull near was max(*0.1,0.1) while render used the <2m 0.05 branch).
|
|
@@ -816,7 +823,14 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
816
823
|
const camDist = Math.hypot(cam.eye[0], cam.eye[1], cam.eye[2]);
|
|
817
824
|
const alt = Math.max(0.0, camDist - R);
|
|
818
825
|
const altAboveTerrain = Math.max(0.001, alt - R * (cam.surfElev || 0));
|
|
819
|
-
|
|
826
|
+
// FAR-PLANE HORIZON RADIUS = R - 500m (user 2026-06-14: 'nearby mountains disappear at water level;
|
|
827
|
+
// adjust that level to 500m under water'). The far plane tracks the sea-level horizon = sqrt(camDist^2
|
|
828
|
+
// - R^2), which at the deck (camDist~=R) collapses to a few hundred metres -> coastal mountains a km
|
|
829
|
+
// out fall beyond the far plane and vanish. Dropping the horizon reference radius 500m below sea level
|
|
830
|
+
// extends the horizon to tens of km at low altitude so near-shore relief stays in view (negligible
|
|
831
|
+
// depth-precision cost: 500m vs R~6.37e6). Both the cull and the draw use this (single source).
|
|
832
|
+
const RHORIZON = R - 500.0;
|
|
833
|
+
const horizon = Math.sqrt(Math.max(0.0, camDist*camDist - RHORIZON*RHORIZON));
|
|
820
834
|
const near = altAboveTerrain < 2.0 ? 0.05 : Math.max(altAboveTerrain * 0.1, 0.05);
|
|
821
835
|
const _fBlend = Math.min(1.0, Math.max(0.0, (alt - 500000.0) / 4500000.0));
|
|
822
836
|
const farGround = Math.max(horizon, alt * 8.0);
|
|
@@ -1095,7 +1109,12 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
1095
1109
|
// seabed, so the depth test culled the water across entire shorelines. Level-9 cells
|
|
1096
1110
|
// (~1.6km) sag ~5cm, far under any visible bathymetry, still ~16-64x fewer water verts
|
|
1097
1111
|
// than the deep terrain leaves.
|
|
1098
|
-
|
|
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;
|
|
1099
1118
|
// OWN persistent buffer (instBufWater) + static-frame skip: on an unchanged quad set, reuse the
|
|
1100
1119
|
// cached water instances (skip the dedup Set-loop + Float32Array + bufferData). Separate buffer
|
|
1101
1120
|
// means the terrain pass never clobbers it (the prior water-as-terrain regression root).
|
package/src/shaders/terrain.glsl
CHANGED
|
@@ -634,7 +634,11 @@ highp float composeHeight(vec3 dir0, highp vec2 faceLocal, float tileM){ // W7
|
|
|
634
634
|
// the field -> seam-safe + the collision probe shares it. GUARD: a stale/unset uniform (0) would
|
|
635
635
|
// disable the shelf -> default 600 so it always applies. window.__beachShelf dials S live.
|
|
636
636
|
highp float bShelf = uBeachShelfM > 1.0 ? uBeachShelfM : 600.0;
|
|
637
|
-
|
|
637
|
+
// C1-CONTINUOUS shelf (user 2026-06-14 'hard shading line where landscape meets beach'): the old
|
|
638
|
+
// h*h/S met the identity at h=S with SLOPE 2 (vs 1) -> a derivative kink -> the slope-keyed shading
|
|
639
|
+
// (rock/AO/material) SNAPPED into a hard line at the shelf top. f = (h*h/S)*(2 - h/S) keeps f(0)=0,
|
|
640
|
+
// f'(0)=0 (flat at the waterline = wide beach) AND f(S)=S, f'(S)=1 (smooth join to natural land).
|
|
641
|
+
if (h < bShelf) h = (h * h / bShelf) * (2.0 - h / bShelf);
|
|
638
642
|
}
|
|
639
643
|
// displacement now continues UNDERWATER (the old land-only gate served the flat-clamped ocean,
|
|
640
644
|
// gone since 026d530): the seabed carries the same micro-relief as land = realistic continuation.
|
|
@@ -853,7 +857,8 @@ void main() {
|
|
|
853
857
|
vH = max(vH, -11000.0); // cap depth at Mariana Trench (~11km)
|
|
854
858
|
} else {
|
|
855
859
|
highp float bShelf = uBeachShelfM > 1.0 ? uBeachShelfM : 600.0; // LAND COASTAL SHELF -- mirror composeHeight exactly (wide beach, user 2026-06-14); guard stale/unset uniform
|
|
856
|
-
if (vH < bShelf) vH = vH * vH / bShelf;
|
|
860
|
+
if (vH < bShelf) vH = (vH * vH / bShelf) * (2.0 - vH / bShelf); // C1-continuous (mirror composeHeight) -- removes the beach-top slope kink / hard shading line
|
|
861
|
+
|
|
857
862
|
}
|
|
858
863
|
vH += vDisp;
|
|
859
864
|
vH += detailFbm(dir0) * uDetailOverlay * 30.0 * step(0.0, vH);
|
|
@@ -1574,8 +1579,13 @@ void main() {
|
|
|
1574
1579
|
mappedW = clamp((mappedW - 0.5) * uLookContrast + 0.5, 0.0, 1.0);
|
|
1575
1580
|
// coverage: optically thick water -> opaque; first metres see-through; grazing fresnel and
|
|
1576
1581
|
// foam are opaque regardless of depth; feather the exact waterline contact.
|
|
1582
|
+
// THIN WATER STAYS CLEAR (user 2026-06-14 'water isnt transparent where its thin'): the grazing
|
|
1583
|
+
// fresnel forced shallow water OPAQUE even looking across a shoreline. Gate fresnel opacity by a
|
|
1584
|
+
// depth ramp so thin water shows the bed regardless of view angle; foam + Beer-Lambert depth
|
|
1585
|
+
// opacity stay so deep/foamy water still reads solid.
|
|
1586
|
+
float shallowClear = smoothstep(0.0, 6.0, depthM); // 0 in thin water -> clear; 1 by ~6m -> full fresnel
|
|
1577
1587
|
float alphaW = clamp(1.0 - Tavg, 0.0, 1.0);
|
|
1578
|
-
alphaW = max(alphaW, fres * 0.9);
|
|
1588
|
+
alphaW = max(alphaW, fres * 0.9 * shallowClear);
|
|
1579
1589
|
alphaW = max(alphaW, foamAmt * 0.8);
|
|
1580
1590
|
// SHALLOW-SURFACE FLOOR (2026-06-11, found by the coast witness after the shelf landed):
|
|
1581
1591
|
// the continental shelf keeps water metres-deep for kilometres, where Beer-Lambert alpha
|