mapspinner 0.1.55 → 0.1.57
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 +4 -4
- package/src/shaders/terrain.glsl +47 -9
- package/src/terrain-gen-controls.js +1 -1
package/package.json
CHANGED
package/src/gl-render.js
CHANGED
|
@@ -787,7 +787,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
787
787
|
// out fall beyond the far plane and vanish. Dropping the horizon reference radius 500m below sea level
|
|
788
788
|
// extends the horizon to tens of km at low altitude so near-shore relief stays in view (negligible
|
|
789
789
|
// depth-precision cost: 500m vs R~6.37e6). Both the cull and the draw use this (single source).
|
|
790
|
-
const RHORIZON = R -
|
|
790
|
+
const RHORIZON = R - 250.0; // far brought in 500->250 (user 2026-06-14 'bring far plane in a bit'): deck horizon ~80km->~56km = more z-precision; still clears coastal mountains
|
|
791
791
|
// UNDERWATER FAR-PLANE FIX (user 2026-06-14 'at -214m visible, at -500m it disappears'): when the
|
|
792
792
|
// camera is more than 500m below sea level, camDist < RHORIZON so the sea-level horizon is imaginary
|
|
793
793
|
// (-> 0) and alt is negative; the old max(horizon, alt*8) then collapsed the far plane to ~0 and the
|
|
@@ -797,7 +797,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
797
797
|
// MATCH render()'s near exactly (2026-06-14 jank fix): the cull frustum must use the SAME near
|
|
798
798
|
// as the draw frustum, else behind-limb/screen-AABB culling diverges from what is actually drawn
|
|
799
799
|
// at the deck (cull near was max(*0.1,0.1) while render used the <2m 0.05 branch).
|
|
800
|
-
const near = altAboveTerrain < 2.0 ? 0.
|
|
800
|
+
const near = altAboveTerrain < 2.0 ? 0.25 : Math.max(altAboveTerrain * 0.1, 0.25); // near nudged out 0.05->0.25 (user 2026-06-14 'improve on-ground'): more z-precision on the deck
|
|
801
801
|
// FAR PLANE: horizon distance tracks the visible ground edge; blends toward camDist
|
|
802
802
|
// above 500km for orbital views so the full planet is visible.
|
|
803
803
|
const _fBlend = Math.min(1.0, Math.max(0.0, (alt - 500000.0) / 4500000.0));
|
|
@@ -835,14 +835,14 @@ export async function initMapspinnerRender(gl, opts = {}) {
|
|
|
835
835
|
// out fall beyond the far plane and vanish. Dropping the horizon reference radius 500m below sea level
|
|
836
836
|
// extends the horizon to tens of km at low altitude so near-shore relief stays in view (negligible
|
|
837
837
|
// depth-precision cost: 500m vs R~6.37e6). Both the cull and the draw use this (single source).
|
|
838
|
-
const RHORIZON = R -
|
|
838
|
+
const RHORIZON = R - 250.0; // far brought in 500->250 (user 2026-06-14 'bring far plane in a bit'): deck horizon ~80km->~56km = more z-precision; still clears coastal mountains
|
|
839
839
|
// UNDERWATER FAR-PLANE FIX (user 2026-06-14 'at -214m visible, at -500m it disappears'): when the
|
|
840
840
|
// camera is more than 500m below sea level, camDist < RHORIZON so the sea-level horizon is imaginary
|
|
841
841
|
// (-> 0) and alt is negative; the old max(horizon, alt*8) then collapsed the far plane to ~0 and the
|
|
842
842
|
// whole scene vanished past -500m deep (= the 'ocean looks shallow/empty' when exploring). Floor the
|
|
843
843
|
// far reach to 60km when submerged so the seabed + the underwater view stay visible.
|
|
844
844
|
const horizon = (camDist > RHORIZON) ? Math.sqrt(camDist*camDist - RHORIZON*RHORIZON) : 60000.0;
|
|
845
|
-
const near = altAboveTerrain < 2.0 ? 0.
|
|
845
|
+
const near = altAboveTerrain < 2.0 ? 0.25 : Math.max(altAboveTerrain * 0.1, 0.25); // near nudged out 0.05->0.25 (user 2026-06-14 'improve on-ground'): more z-precision on the deck
|
|
846
846
|
const _fBlend = Math.min(1.0, Math.max(0.0, (alt - 500000.0) / 4500000.0));
|
|
847
847
|
const farGround = Math.max(horizon, alt * 8.0);
|
|
848
848
|
const far = farGround * (1.0 - _fBlend) + camDist * _fBlend;
|
package/src/shaders/terrain.glsl
CHANGED
|
@@ -631,14 +631,16 @@ highp float composeHeight(vec3 dir0, highp vec2 faceLocal, float tileM){ // W7
|
|
|
631
631
|
// whole ocean into 'almost-land everywhere', user 2026-06-14) with the flat-at-waterline curve so
|
|
632
632
|
// both sides meet the waterline at slope 0 (no crease); beyond SEABED_EASE the true bathymetry
|
|
633
633
|
// resumes so the ocean goes DEEP.
|
|
634
|
-
const highp float SEABED_EASE =
|
|
634
|
+
const highp float SEABED_EASE = 25.0; // metres of depth flattened at the shore (decoupled from the land beach)
|
|
635
635
|
highp float d0 = -h;
|
|
636
636
|
highp float d = (d0 < SEABED_EASE) ? (d0 * d0 / SEABED_EASE) * (2.0 - d0 / SEABED_EASE) : d0;
|
|
637
|
-
//
|
|
638
|
-
//
|
|
637
|
+
// NO 'SECOND BEACH' (user 2026-06-14 'shallow ring of water around land / making a second beach'):
|
|
638
|
+
// the wide flat shelf read as a shallow underwater beach ring. Shelf cut to a tiny 25m-raw lip then
|
|
639
|
+
// a STEEP 1.9 plunge so the water drops to real depth immediately off the actual beach -- no shelf.
|
|
640
|
+
// (former: narrow shelf 500->150m raw, steeper shelf 0.24->0.6, steeper continental slope 1.19->1.5 so the
|
|
639
641
|
// seabed plunges to deep water just offshore (less flat shallow shelf) and the deep bathymetry
|
|
640
642
|
// carries 1.5x the bShape relief = more dramatic underwater terrain to explore.
|
|
641
|
-
h = -(min(d,
|
|
643
|
+
h = -(min(d, 25.0) * 0.4 + max(d - 25.0, 0.0) * 1.9);
|
|
642
644
|
h = max(h, -11000.0); // cap depth at Mariana Trench (~11km)
|
|
643
645
|
} else {
|
|
644
646
|
// LAND COASTAL SHELF (user 2026-06-14: 'beaches not wide enough'): the underwater shelf above
|
|
@@ -869,10 +871,10 @@ void main() {
|
|
|
869
871
|
// shelf/slope bathymetry remap + underwater displacement -- MUST mirror composeHeight exactly
|
|
870
872
|
// (this is the FS-material running value; composeHeight is the geometry/probe height).
|
|
871
873
|
if (vH < 0.0) {
|
|
872
|
-
const highp float SEABED_EASE =
|
|
874
|
+
const highp float SEABED_EASE = 25.0; // mirror composeHeight: tiny waterline lip, steep plunge (no 'second beach')
|
|
873
875
|
highp float dSea0 = -vH;
|
|
874
876
|
highp float dSea = (dSea0 < SEABED_EASE) ? (dSea0 * dSea0 / SEABED_EASE) * (2.0 - dSea0 / SEABED_EASE) : dSea0;
|
|
875
|
-
vH = -(min(dSea,
|
|
877
|
+
vH = -(min(dSea, 25.0) * 0.4 + max(dSea - 25.0, 0.0) * 1.9); // steep drop-off (mirror composeHeight)
|
|
876
878
|
vH = max(vH, -11000.0); // cap depth at Mariana Trench (~11km)
|
|
877
879
|
} else {
|
|
878
880
|
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
|
|
@@ -1247,7 +1249,13 @@ vec3 terrainAlbedo(float h, float slope, float rockSlope, highp vec3 worldPos) {
|
|
|
1247
1249
|
} else {
|
|
1248
1250
|
c = mix(bcShore, bcLowland, smoothstep(0.0, bandEdgesLo.x, h));
|
|
1249
1251
|
c = mix(c, bcGrass, smoothstep(bandEdgesLo.x, bandEdgesLo.y, h));
|
|
1250
|
-
|
|
1252
|
+
// BIOME-BAND WARP (user 2026-06-14 'hard bands between biomes ... make that more interesting'):
|
|
1253
|
+
// the single-octave warp made smooth wavy contour lines. A 3-octave domain-warped field breaks
|
|
1254
|
+
// the rock/snow boundaries into irregular fingers + patches (height-keyed band wobbles +/-~1.1km
|
|
1255
|
+
// over 1-15km scales), so the biome edge reads natural, not a band. highp dir for the lattice.
|
|
1256
|
+
highp vec3 bwd = normalize(worldPos);
|
|
1257
|
+
highp vec3 bww = bwd + vec3(snoise3(bwd * 130.0)) * 0.004; // domain warp -> non-parallel fingers
|
|
1258
|
+
float bandWarp = (snoise3(bww * 210.0) * 1.0 + snoise3(bww * 560.0) * 0.5 + snoise3(bww * 1450.0) * 0.25) * 720.0;
|
|
1251
1259
|
c = mix(c, bcRock, smoothstep(bandEdgesHi.x + bandWarp, bandEdgesHi.y + bandWarp, h));
|
|
1252
1260
|
c = mix(c, bcSnow, smoothstep(snowEdges.x + bandWarp, snowEdges.y + bandWarp, h));
|
|
1253
1261
|
c = mix(c, bcRock, smoothstep(slopeRock.x, slopeRock.y, rockSlope) * step(0.0, h));
|
|
@@ -1776,10 +1784,19 @@ void main() {
|
|
|
1776
1784
|
// beach->land crossover). 2-oct world-dir noise, 1/4 freq (~13km + ~5km waves). Computed once
|
|
1777
1785
|
// here; the snow/rock bandWarp below reuses warpN. highp dir for the lattice precision.
|
|
1778
1786
|
highp vec3 bwDir = normalize(vWorld);
|
|
1779
|
-
|
|
1787
|
+
// 3-oct (added the ~1km octave, user 2026-06-14 'make biome bands more interesting') -> the
|
|
1788
|
+
// texture-splat rock/snow/beach edges break into finer fingers as you approach, not a hard band.
|
|
1789
|
+
float warpN = snoise3(bwDir * 3325.0) + 0.5 * snoise3(bwDir * 7750.0) + 0.35 * snoise3(bwDir * 17000.0); // ~ +/-1.8
|
|
1780
1790
|
// BEACH sand gate tied to uBeachTopM (so the sand TEXTURE scales with the wide beach, not a
|
|
1781
1791
|
// hardcoded 80m strip) + the shared warp on its LAND edge so the beach->grass line is irregular.
|
|
1782
|
-
|
|
1792
|
+
// FINE BREAK on the grass->sand line (user 2026-06-14 'still a hard straight grass-sand line up
|
|
1793
|
+
// close ... it must gain detail'): warpN breaks it at the km scale; add a high-freq (~80-200m)
|
|
1794
|
+
// octave so the line stays irregular/fingered when you walk right up to it instead of going
|
|
1795
|
+
// straight. Faded in WITH the close-up detail (detailFade-like, via pxWorld) so it never speckles
|
|
1796
|
+
// at distance where the macro band is smooth.
|
|
1797
|
+
float closeBreak = (1.0 - smoothstep(2.0, 40.0, pxWorld));
|
|
1798
|
+
float beachFine = (snoise3(bwDir * 42000.0) + 0.5 * snoise3(bwDir * 95000.0)) * uBeachTopM * 0.45 * closeBreak;
|
|
1799
|
+
float beachW = warpN * uBeachTopM * 0.30 + beachFine; // warp amplitude scales with the beach band height
|
|
1783
1800
|
float beach = (1.0 - smoothstep(uBeachTopM * 0.12 + beachW, uBeachTopM + beachW, vH))
|
|
1784
1801
|
* (1.0 - smoothstep(0.15, 0.42, slope));
|
|
1785
1802
|
// SAND BLEED (2026-06-13): patchy sand spills above the main beach line, modulated by VS
|
|
@@ -1879,6 +1896,27 @@ void main() {
|
|
|
1879
1896
|
texAlb = mix(albB, albA, bSharp);
|
|
1880
1897
|
texNrm = mix(nrmB, nrmA, bSharp);
|
|
1881
1898
|
}
|
|
1899
|
+
// FINE DETAIL OCTAVE (user 2026-06-14 'add one octave at 4x smaller -> world better scaled at
|
|
1900
|
+
// 2m'): the base photo tiles at uTexTileM (~2.4km = ~2.3m/texel, smeared at the deck). Sample the
|
|
1901
|
+
// SAME dominant material at 4x frequency (~0.6m/texel) and overlay its luminance + normal so
|
|
1902
|
+
// close-up the ground gains sub-metre structure. Faded out by ~12m px so it never moires far off.
|
|
1903
|
+
// LOW-FREQ = NORMALS ONLY, HIGH-FREQ = TEXTURE + STRONG NORMALS (user 2026-06-14): flatten the
|
|
1904
|
+
// base (2.4km) albedo to its luminance so the MACRO biome color carries the chroma -- the base
|
|
1905
|
+
// octave contributes only its NORMAL (relief), not color blotches. The 4x detail octave then
|
|
1906
|
+
// provides the albedo STRUCTURE + a strong normal.
|
|
1907
|
+
texAlb.rgb = vec3(dot(texAlb.rgb, vec3(0.299, 0.587, 0.114))); // low-freq: normals only (albedo -> flat luma)
|
|
1908
|
+
float detailFade = (1.0 - smoothstep(1.0, 12.0, pxWorld));
|
|
1909
|
+
if (detailFade > 0.01) {
|
|
1910
|
+
vec4 dA = surfTriTap(uSurfAlb, wt * 4.0, tw, lA);
|
|
1911
|
+
float dl = dot(dA.rgb, vec3(0.299, 0.587, 0.114));
|
|
1912
|
+
float bl = dot(texAlb.rgb, vec3(0.299, 0.587, 0.114));
|
|
1913
|
+
texAlb.rgb *= mix(1.0, clamp(dl / max(bl, 0.04), 0.35, 2.4), detailFade * 1.3); // HIGH-FREQ albedo structure (heavier)
|
|
1914
|
+
// detail NORMAL: surfTriNrm returns a PERTURBATION vector (texNrm feeds texDn = texNrm*uTexNrmK*k,
|
|
1915
|
+
// NOT a unit normal), so the detail is simply ADDED in the same space -- no normalize (that
|
|
1916
|
+
// scrambled magnitudes = the 'weird highest-octave normals').
|
|
1917
|
+
vec3 dN = surfTriNrm(uSurfNrm, wt * 4.0, tw, lA, n);
|
|
1918
|
+
texNrm = texNrm + dN * detailFade * 1.4; // BIGGER normal effect for the high-freq octave (user 2026-06-14)
|
|
1919
|
+
}
|
|
1882
1920
|
float k = uTexMix * texFarFade;
|
|
1883
1921
|
// macro-tinted detail (user 2026-06-10 'the textured patch must be tinted to the same shade
|
|
1884
1922
|
// as the spot its replacing'): the texture contributes STRUCTURE + relative chroma only,
|
|
@@ -46,7 +46,7 @@ const DEFAULTS = {
|
|
|
46
46
|
exposure: 1.0, skyFill: 0.45, biomeSat: 0.72, variationAmt: 0.04, colorVar: 0.5, vertexAO: 1.0, reliefShade: 2.5, // variationAmt 0.08->0.04 (user 2026-06-10 'blotchy': the ~50km value mottle painted light/dark patches across the massifs)
|
|
47
47
|
nightFloor: 0.16, termWidth: 0.25, terminatorGlow: 0.30, lookSat: 1.15, lookContrast: 1.08, // nightFloor 0.05->0.16: no black night terrain (2026-06-09)
|
|
48
48
|
detailOverlay: 6.0, hazeMul: 0.65, // 2026-06-10 'pale hazy + featureless': perlin-everywhere albedo+elevation fbm (user-tuned 6) + aerial-perspective strength cut
|
|
49
|
-
ocean: { deep: [0.008,0.025,0.06], shallow: [0.07,0.22,0.26], k: [0.
|
|
49
|
+
ocean: { deep: [0.008,0.025,0.06], shallow: [0.07,0.22,0.26], k: [0.009,0.004,0.0018] }, // k lowered again (user 2026-06-14 'water properly transparent so we see the surface under it'): clearer, the seabed shows through shallow/medium water; deep basins still opaque. OVERRIDES gl-render via window.__uOceanK.
|
|
50
50
|
},
|
|
51
51
|
// HPF band scales (multipliers on the anchor-field band base values; anchor-field.setBandScales).
|
|
52
52
|
hpf: {
|