mapspinner 0.1.47 → 0.1.49
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/planet.html +10 -2
- package/src/gl-render.js +9 -5
- package/src/shaders/terrain.glsl +20 -11
package/package.json
CHANGED
package/planet.html
CHANGED
|
@@ -531,16 +531,24 @@ function frameLoop(){
|
|
|
531
531
|
// the eye lands exactly eyeHeight (2.0m) above it. (The old +130m, then +3m, margin made __altM read
|
|
532
532
|
// a height above an inflated reference -> the eye was really ground+margin+2m, not 2m.) The mirror
|
|
533
533
|
// fallback keeps a small +3m only because the CPU jsBroadShape can under-predict vs the GPU.
|
|
534
|
+
let doClamp = true;
|
|
534
535
|
if (gpuM != null && isFinite(gpuM)) {
|
|
535
536
|
renderedM = gpuM + 1.0; // +1m margin for sub-vertex micro-relief (vtxDisplace peaks exceed 2m in rugged terrain)
|
|
537
|
+
} else if (r >= RADIUS) {
|
|
538
|
+
renderedM = jsBroadShape(cam.pos[0], cam.pos[1], cam.pos[2]) + 3.0; // above sea level: mirror is fine for land
|
|
536
539
|
} else {
|
|
537
|
-
|
|
540
|
+
// UNDERWATER DIVE FIX (user 2026-06-14 'camera stops at sea level'): below sea level with NO GPU
|
|
541
|
+
// probe this frame, the CPU mirror (jsBroadShape) OMITS the seaBias/bathymetry remap, so it reports
|
|
542
|
+
// ~sea-level over ocean and the clamp would shove the camera back up to the surface = 'stuck at sea
|
|
543
|
+
// level'. Skip the clamp this frame; the GPU probe (the only thing that knows the seabed) resumes
|
|
544
|
+
// collision next frame, so you can descend through the surface and explore the seabed.
|
|
545
|
+
doClamp = false; renderedM = -11000.0;
|
|
538
546
|
}
|
|
539
547
|
// cap to composeHeight's CMAX=15000; allow negative for seabed
|
|
540
548
|
const surfElev = Math.min(renderedM, 15000.0) / WEBGL2_TERRAIN_R_M;
|
|
541
549
|
const eyeHeight = 2.0 / WEBGL2_M_PER_UNIT; // EXACTLY 2.0 m above ground (km-units = 2m / m-per-unit)
|
|
542
550
|
const minR = RADIUS * (1.0 + surfElev) + eyeHeight;
|
|
543
|
-
if (r < minR) { const s = minR/r; cam.pos[0]*=s; cam.pos[1]*=s; cam.pos[2]*=s; }
|
|
551
|
+
if (doClamp && r < minR) { const s = minR/r; cam.pos[0]*=s; cam.pos[1]*=s; cam.pos[2]*=s; }
|
|
544
552
|
const maxR = RADIUS * 50;
|
|
545
553
|
if (r > maxR) { const s = maxR/r; cam.pos[0]*=s; cam.pos[1]*=s; cam.pos[2]*=s; }
|
|
546
554
|
|
package/src/gl-render.js
CHANGED
|
@@ -421,8 +421,8 @@ 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',
|
|
425
|
-
gl.uniform1f(loc('uLandBias'), g('landBias',
|
|
424
|
+
gl.uniform1f(loc('uBeachShelfM'), g('beachShelf', 0.0)); // land coastal shelf (geometry); probe MUST match render
|
|
425
|
+
gl.uniform1f(loc('uLandBias'), g('landBias', 0.0)); // +650m hypsometry bias = ~+30% land:sea (measured: landFrac 0.041 -> 0.054 over a 700-dir sphere grid, user 2026-06-14). window.__landBias dials it live.
|
|
426
426
|
gl.uniform1f(loc('cliffAmt'), g('cliffAmt', 1.0));
|
|
427
427
|
gl.uniform1i(loc('uFloatLinearOK'), _halfFloatLinearOK ? 1 : 0);
|
|
428
428
|
// FXC unroll-defeat (2026-06-12 AMD d3d11 fix): runtime octave bound for broadShapeM; the shader
|
|
@@ -961,8 +961,8 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
961
961
|
const _g = (n,d)=> (typeof window!=='undefined' && window['__'+n]!=null) ? +window['__'+n] : d;
|
|
962
962
|
gl.uniform1f(U('canyonDepthMul'), _g('canyonDepth', 1.0));
|
|
963
963
|
gl.uniform1f(U('uVsCheap'), (typeof window!=='undefined' && window.__vsCheap) ? 1.0 : 0.0); // VS carve-cost profiling A/B
|
|
964
|
-
gl.uniform1f(U('uBeachShelfM'), _g('beachShelf',
|
|
965
|
-
gl.uniform1f(U('uLandBias'), _g('landBias',
|
|
964
|
+
gl.uniform1f(U('uBeachShelfM'), _g('beachShelf', 0.0)); // land coastal shelf (geometry): h<S eased h*h/S = wide beach
|
|
965
|
+
gl.uniform1f(U('uLandBias'), _g('landBias', 0.0)); // +650m hypsometry bias = ~+30% land:sea (window.__landBias); MUST match the probe (setComposeHeightUniforms) for collision parity
|
|
966
966
|
gl.uniform1f(U('uHiFreqCut'), _g('hiFreqCut', 0.25)); // 0.5->0.25 (2026-06-10 'blotchy' -- see setComposeHeightUniforms)
|
|
967
967
|
gl.uniform1f(U('uVertexAO'), _g('vertexAO', 1.0)); // per-vertex shading/AO strength (DEFECT 2, 2026-06-06)
|
|
968
968
|
gl.uniform1f(U('cliffAmt'), _g('cliffAmt', 1.0));
|
|
@@ -1105,7 +1105,11 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
1105
1105
|
// shows. Cap every visible leaf at level WCAP and DEDUP to its ancestor tile: a coarse,
|
|
1106
1106
|
// LOD-churn-free cover of the same footprint, typically ~10-50x fewer water vertices.
|
|
1107
1107
|
// __waterSurface=0 disables live.
|
|
1108
|
-
|
|
1108
|
+
// UNDERWATER: skip the sea-level water surface entirely (user 2026-06-14 'underwater looks weird,
|
|
1109
|
+
// we cant see anything / it must draw the sea bed'). The surface mesh drawn from below was an
|
|
1110
|
+
// opaque sheet that occluded the seabed; with it gone, the underwater camera sees the seabed
|
|
1111
|
+
// terrain directly (with the underwater fog). Above water it draws normally.
|
|
1112
|
+
if ((typeof window === 'undefined' || window.__waterSurface !== false) && !_uw) {
|
|
1109
1113
|
// WCAP 7 -> 9 (coast witness caught it: a level-7 tile's 16-cell mesh chord sags
|
|
1110
1114
|
// A_cell^2/(8R) ~ 0.8m below the true sphere mid-cell -- BELOW the metres-deep shelf
|
|
1111
1115
|
// seabed, so the depth test culled the water across entire shorelines. Level-9 cells
|
package/src/shaders/terrain.glsl
CHANGED
|
@@ -627,11 +627,13 @@ highp float composeHeight(vec3 dir0, highp vec2 faceLocal, float tileM){ // W7
|
|
|
627
627
|
// C1 WATERLINE (user 2026-06-14 'geometry crease + shading/rock hard line where land meets beach'):
|
|
628
628
|
// the land shelf is FLAT at the waterline (slope 0) but the seabed used slope 0.24 from h=0 -> a
|
|
629
629
|
// slope discontinuity = a crease (+ the shading brightness line + rock where steep) right at the
|
|
630
|
-
// shore. Ease
|
|
631
|
-
//
|
|
632
|
-
|
|
630
|
+
// shore. Ease ONLY a NARROW band of depth (NOT the 28km land beach width -- that shallowed the
|
|
631
|
+
// whole ocean into 'almost-land everywhere', user 2026-06-14) with the flat-at-waterline curve so
|
|
632
|
+
// both sides meet the waterline at slope 0 (no crease); beyond SEABED_EASE the true bathymetry
|
|
633
|
+
// resumes so the ocean goes DEEP.
|
|
634
|
+
const highp float SEABED_EASE = 300.0; // metres of depth flattened at the shore (decoupled from the land beach)
|
|
633
635
|
highp float d0 = -h;
|
|
634
|
-
highp float d = (d0 <
|
|
636
|
+
highp float d = (d0 < SEABED_EASE) ? (d0 * d0 / SEABED_EASE) * (2.0 - d0 / SEABED_EASE) : d0;
|
|
635
637
|
h = -(min(d, 500.0) * 0.24 + max(d - 500.0, 0.0) * 1.19);
|
|
636
638
|
h = max(h, -11000.0); // cap depth at Mariana Trench (~11km)
|
|
637
639
|
} else {
|
|
@@ -860,9 +862,9 @@ void main() {
|
|
|
860
862
|
// shelf/slope bathymetry remap + underwater displacement -- MUST mirror composeHeight exactly
|
|
861
863
|
// (this is the FS-material running value; composeHeight is the geometry/probe height).
|
|
862
864
|
if (vH < 0.0) {
|
|
863
|
-
highp float
|
|
865
|
+
const highp float SEABED_EASE = 300.0; // mirror composeHeight: narrow waterline ease, deep ocean beyond
|
|
864
866
|
highp float dSea0 = -vH;
|
|
865
|
-
highp float dSea = (dSea0 <
|
|
867
|
+
highp float dSea = (dSea0 < SEABED_EASE) ? (dSea0 * dSea0 / SEABED_EASE) * (2.0 - dSea0 / SEABED_EASE) : dSea0;
|
|
866
868
|
vH = -(min(dSea, 500.0) * 0.24 + max(dSea - 500.0, 0.0) * 1.19);
|
|
867
869
|
vH = max(vH, -11000.0); // cap depth at Mariana Trench (~11km)
|
|
868
870
|
} else {
|
|
@@ -1065,7 +1067,11 @@ void main() {
|
|
|
1065
1067
|
// water pass: NO skirt (user 2026-06-11) -- the surface is an exact sphere at R, so adjacent
|
|
1066
1068
|
// LODs agree exactly and there are no T-junction cracks to hide; a skirt would only drape a
|
|
1067
1069
|
// visible curtain through the transparent shallows.
|
|
1068
|
-
|
|
1070
|
+
// SKIRT halved (user 2026-06-14 'we keep seeing skirts' -- visible underwater/through the now-clear
|
|
1071
|
+
// water): 0.12->0.06 tile-scaled + floor 60->30. Still reaches below a coarser neighbor to hide the
|
|
1072
|
+
// LOD T-junction crack (the real discontinuity is tens of m, far under 0.06*tilespan), but the
|
|
1073
|
+
// vertical curtain is half as tall = far less visible when the seabed is seen through clear water.
|
|
1074
|
+
highp float skirt = (vertex.z > 0.5 && uIsWater < 0.5) ? max(defOffset.z * 0.06, 30.0) : 0.0; // W7: metres (tile-size scaled) -> highp
|
|
1069
1075
|
vWorld = dir0 * (R + hR - skirt); // ABSOLUTE world pos (RENDER height: ocean top flat) -> FS lighting/atmosphere
|
|
1070
1076
|
// TEXTURE DOMAIN WARP -- VS-side, DOUBLED BACK (user 2026-06-12): 225/900/3500 -> 450/1800/7000.
|
|
1071
1077
|
{
|
|
@@ -2156,11 +2162,14 @@ void main() {
|
|
|
2156
2162
|
highp vec3 segKm = pAtm - camA;
|
|
2157
2163
|
highp float dKm = length(segKm);
|
|
2158
2164
|
float depth = max(0.0, terrainR - length(camWorld));
|
|
2159
|
-
//
|
|
2160
|
-
|
|
2165
|
+
// CLEARER WATER + LONG VISIBILITY (user 2026-06-14 'fix underwater visibility so we can explore
|
|
2166
|
+
// under the ocean'): the old absorb (4,0.8,0.3)/km + a 50->500m hard fog fade closed the view to
|
|
2167
|
+
// opaque blue within ~500m. Lower the coefficients (still red-first absorption) and push the hard
|
|
2168
|
+
// fade to ~3-15km so the seabed landscape is explorable; red still fades fast (realistic blue cast).
|
|
2169
|
+
vec3 absorb = vec3(1.0, 0.30, 0.15) * (1.0 + depth * 0.0002);
|
|
2161
2170
|
vec3 uwTrans = exp(-absorb * dKm);
|
|
2162
|
-
vec3 uwFog = vec3(0.
|
|
2163
|
-
color = mix(color * uwTrans + uwFog * (1.0 - uwTrans), uwFog, smoothstep(
|
|
2171
|
+
vec3 uwFog = vec3(0.004, 0.10, 0.22) + vec3(0.0, 0.02, 0.04) * depth / 1000.0;
|
|
2172
|
+
color = mix(color * uwTrans + uwFog * (1.0 - uwTrans), uwFog, smoothstep(3000.0, 15000.0, dKm * 1000.0));
|
|
2164
2173
|
}
|
|
2165
2174
|
// RIVERS post-lighting (witnessed browser-2115/2118: the river-blue in ALBEDO is multiplied
|
|
2166
2175
|
// by the warm sun irradiance (sunIrr.b is low) so land rivers lose their blue in the lit
|