mapspinner 0.1.72 → 0.1.74
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/shaders/terrain.glsl +56 -13
package/package.json
CHANGED
package/src/shaders/terrain.glsl
CHANGED
|
@@ -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),
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
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);
|
|
@@ -753,6 +760,7 @@ out float vLakeWet; // lake open-water mask (carve basin)
|
|
|
753
760
|
out float vRiverWet; // river thalweg wet line
|
|
754
761
|
out float vWaterDepth; // metres the flat inland-water plane sits ABOVE the local terrain floor (>0 = submerged)
|
|
755
762
|
out float vCanyonDep; // canyon gorge depth [0,1]
|
|
763
|
+
out float vConcavity; // height-field Laplacian / step^2 (1/m, +ve = concave valley/pit) -- ELEVATION AO signal (free from the normal central-diff taps)
|
|
756
764
|
out float vCliffFace; // cliff/escarpment riser face [0,1] (1 = steep terrace face)
|
|
757
765
|
out float vDuneCrest; // dune crest [0,1]
|
|
758
766
|
out float vLevel; // quad LOD level (per-instance iOffset.w) for the patches debug view
|
|
@@ -938,12 +946,14 @@ void main() {
|
|
|
938
946
|
// water level + suppress the micro-displacement on the wet line. riverWetMask is the thalweg mask.
|
|
939
947
|
float riverWetLine = riverWetMask * riverWet * step(0.0, vH);
|
|
940
948
|
if (riverWetLine > 0.0) {
|
|
941
|
-
|
|
949
|
+
// MIRROR of composeHeight (deeper 20->70m channel + pow(.,0.6) gentler concave approach)
|
|
950
|
+
float rw = pow(riverWetLine, 0.6);
|
|
951
|
+
highp float rWaterLevel = vH - 70.0; // W7: metres
|
|
942
952
|
highp float rFloorBefore = vH;
|
|
943
|
-
vH = mix(vH, rWaterLevel,
|
|
944
|
-
vDisp *= (1.0 -
|
|
953
|
+
vH = mix(vH, rWaterLevel, rw);
|
|
954
|
+
vDisp *= (1.0 - rw); // no micro-bumps on the river surface
|
|
945
955
|
// record the deeper/stronger of lake|river as the water surface for vWaterDepth
|
|
946
|
-
if (
|
|
956
|
+
if (rw > haveWater) { waterPlane = rWaterLevel; floorBefore = rFloorBefore; haveWater = rw; }
|
|
947
957
|
}
|
|
948
958
|
// DUNES on the SAND DESERT (very dry + warm + LOW land): rolling dune relief replaces harsh rock
|
|
949
959
|
// here (ref: webgl-dunes). Gated opposite to canyons (which want elevated arid plateaus) -- dunes
|
|
@@ -994,6 +1004,7 @@ void main() {
|
|
|
994
1004
|
// sides of a seam share the same dir0/tangent frame -> consistent normals, no row artifact.
|
|
995
1005
|
highp float hN0 = 0.0;
|
|
996
1006
|
highp vec3 vN = dir0;
|
|
1007
|
+
highp float concavRaw = 0.0; // height Laplacian / step^2 (+ve = concave) -- set in the land branches, free from the normal taps
|
|
997
1008
|
if (uIsWater < 0.5 && uThc > 0.5) {
|
|
998
1009
|
// THC FAST PATH: height + symmetric central-diff normal from the baked pool. 5 bilinear texture
|
|
999
1010
|
// taps replace 5 full composeHeight evals (the VS-bound cost). The 4 normal taps use the SAME
|
|
@@ -1049,6 +1060,23 @@ void main() {
|
|
|
1049
1060
|
vN = normalize(cross(wPU - wMU, wPV - wMV));
|
|
1050
1061
|
if (dot(vN, dir0) < 0.0) vN = -vN; // keep it outward (terrain has no overhangs)
|
|
1051
1062
|
}
|
|
1063
|
+
// ELEVATION-AO CONCAVITY at LARGE scale (user 2026-06-14 'AO is focused on features too small, must
|
|
1064
|
+
// AO the larger features'): the 300m normal-step Laplacian keyed on small/sharp relief (canyons). Take
|
|
1065
|
+
// the Laplacian of broadShapeLowM (the cheap 8-oct LARGE-SCALE shape, no small carves) over a WIDE ~2km
|
|
1066
|
+
// step instead, so the AO darkens broad valleys/basins. broadShapeLowM is the same field the mesa
|
|
1067
|
+
// slope gate uses at a 1.2km step -> a known-cheap large-feature probe. Land only (water needs none).
|
|
1068
|
+
if (uIsWater < 0.5) {
|
|
1069
|
+
const highp float ecM = 2000.0; // wide finite-diff step = large-feature scale
|
|
1070
|
+
highp vec3 ux = normalize(cross(abs(dir0.y) < 0.99 ? vec3(0.0,1.0,0.0) : vec3(1.0,0.0,0.0), dir0));
|
|
1071
|
+
highp vec3 uy = cross(dir0, ux);
|
|
1072
|
+
highp float h0c = broadShapeLowM(dir0);
|
|
1073
|
+
highp float hxp = broadShapeLowM(normalize(dir0 + ux * (ecM / defRadius)));
|
|
1074
|
+
highp float hxm = broadShapeLowM(normalize(dir0 - ux * (ecM / defRadius)));
|
|
1075
|
+
highp float hyp = broadShapeLowM(normalize(dir0 + uy * (ecM / defRadius)));
|
|
1076
|
+
highp float hym = broadShapeLowM(normalize(dir0 - uy * (ecM / defRadius)));
|
|
1077
|
+
concavRaw = (hxp + hxm + hyp + hym - 4.0 * h0c) / (ecM * ecM); // 1/m large-scale curvature, +ve = broad valley/basin
|
|
1078
|
+
}
|
|
1079
|
+
vConcavity = concavRaw;
|
|
1052
1080
|
highp float h = hN0;
|
|
1053
1081
|
// OCEAN TOP = A SEPARATE, ELEVATION-BASED SURFACE (user 2026-06-10: 'terrain should extend into
|
|
1054
1082
|
// the ocean, the ocean top separate and elevation based'). composeHeight keeps carrying the TRUE
|
|
@@ -1126,6 +1154,7 @@ in float vLakeWet; // carve masks computed in the VS, interpolated (no per-pi
|
|
|
1126
1154
|
in float vRiverWet;
|
|
1127
1155
|
in float vWaterDepth; // metres of submerged water (>0 = real open inland water at the flat plane)
|
|
1128
1156
|
in float vCanyonDep;
|
|
1157
|
+
in float vConcavity; // elevation-AO concavity (1/m, +ve = valley/pit)
|
|
1129
1158
|
in float vCliffFace;
|
|
1130
1159
|
in float vDuneCrest;
|
|
1131
1160
|
in float vLevel; // quad LOD level (patches view)
|
|
@@ -1912,7 +1941,7 @@ void main() {
|
|
|
1912
1941
|
// 3 normal octaves (user 2026-06-14 'add an even lower freq octave, displacement/normals only,
|
|
1913
1942
|
// 4x less frequent'): wt4 high (detail) + wt low (2.4km) + wt*0.25 VERY-low (9.6km) -- the very-
|
|
1914
1943
|
// low one breaks the far repetition even more. Normals/displacement only (no albedo).
|
|
1915
|
-
vec3 nA = surfTriNrm(uSurfNrm, wt4, tw, lA, n) *
|
|
1944
|
+
vec3 nA = surfTriNrm(uSurfNrm, wt4, tw, lA, n) * 2.0 + surfTriNrm(uSurfNrm, wt, tw, lA, n) * 0.9 + surfTriNrm(uSurfNrm, wt * 0.25, tw, lA, n) * 1.1; // REBALANCED (user 2026-06-14 'higher octaves appear gone'): very-low 2.4 swamped the detail -> high (wt4) UP to 2.0 (dominant detail), very-low DOWN to 1.1 (still visible broad) (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
|
|
1916
1945
|
float dispA = albA.a;
|
|
1917
1946
|
// NO BIOME COLOR INHERITANCE (user 2026-06-14 'take away all biome color inheritance, it will
|
|
1918
1947
|
// speed it up' -- and fixes 'sand near grass tinted green'): each layer wears its OWN material
|
|
@@ -1924,7 +1953,7 @@ void main() {
|
|
|
1924
1953
|
if (wB > 0.02) { // second layer only where a real transition exists
|
|
1925
1954
|
vec4 albB = surfTriTap(uSurfAlb, wt4, tw, lB);
|
|
1926
1955
|
vec3 cB = vec3(dot(albB.rgb, LUMA));
|
|
1927
|
-
vec3 nB = surfTriNrm(uSurfNrm, wt4, tw, lB, n) *
|
|
1956
|
+
vec3 nB = surfTriNrm(uSurfNrm, wt4, tw, lB, n) * 2.0 + surfTriNrm(uSurfNrm, wt, tw, lB, n) * 0.9 + surfTriNrm(uSurfNrm, wt * 0.25, tw, lB, n) * 1.1; // REBALANCED (match nA)
|
|
1928
1957
|
float dispB = albB.a;
|
|
1929
1958
|
// HEIGHT-BLEND POKE-THROUGH (user 'each texture's higher areas should poke through the other,
|
|
1930
1959
|
// offset by the ramp'): height = displacement + a weight-ramp offset (gate positions the
|
|
@@ -2012,13 +2041,27 @@ void main() {
|
|
|
2012
2041
|
// base = flat MATERIAL color (far/low-k); near = structured detail. The macro biome albedo is no
|
|
2013
2042
|
// longer the base, so NO biome color bleeds into the ground (user 'take away all biome inheritance').
|
|
2014
2043
|
albedo = clamp(mix(texMatColor, detail, k), 0.0, 1.0);
|
|
2015
|
-
albedo = mix(albedo, biomeC, 0.
|
|
2044
|
+
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')
|
|
2016
2045
|
// FAKE MIDDAY AO from the displacement (user 2026-06-14 'darken the deepest parts of the
|
|
2017
2046
|
// displacement textures a little'): the texture's LOWEST displacement = crevices/pits; darken
|
|
2018
2047
|
// them ~18% so the surface reads as sunlit-from-above with soft self-occlusion in the lows.
|
|
2019
2048
|
// Faded by k so the far field (where the texture mips out) is untouched.
|
|
2020
|
-
|
|
2049
|
+
// STRONGER fake-midday AO (user 2026-06-14 'should be more intense, we dont really see it'):
|
|
2050
|
+
// darken the recesses harder (0.82->0.5 = up to 50%) over a wider low-displacement range so the
|
|
2051
|
+
// crevices/pits read clearly. Still faded by k so the mipped far field is untouched.
|
|
2052
|
+
float texAO = mix(1.0, mix(0.5, 1.0, smoothstep(0.05, 0.6, texAlb.a)), k);
|
|
2021
2053
|
albedo *= texAO;
|
|
2054
|
+
// ELEVATION AO (user 2026-06-14 x3 'similar AO on elevation / still not visible'): the screen-space
|
|
2055
|
+
// curvature of vNrm was ~0 (vNrm is a per-vertex analytic normal, linearly interpolated -> its
|
|
2056
|
+
// fwidth is tiny on the coarse grid = invisible). Replaced with vConcavity = the height-field
|
|
2057
|
+
// LAPLACIAN computed FREE from the VS normal central-diff taps (1/m, +ve = concave valley/pit),
|
|
2058
|
+
// a real object-space relief signal that survives interpolation. Darken concavities up to 65%.
|
|
2059
|
+
// VERY GRADUAL response (user 2026-06-14 'ao works but not gradiated, must be very gradual'): the
|
|
2060
|
+
// hard clamp(.,0.6) flat-topped every valley past a threshold = a visible AO edge + no gradation
|
|
2061
|
+
// between medium and deep concavity. Exponential SOFT saturation instead -- monotonic, smooth
|
|
2062
|
+
// onset AND smooth approach to the 0.6 floor, so darkening grades continuously with depth, no edge.
|
|
2063
|
+
float elevAO = 1.0 - 0.6 * (1.0 - exp(-max(vConcavity, 0.0) * 2500.0)); // concavRaw ~=1/Rc of the LARGE shape (~3-7e-4 for km-scale basins): broad valley eases in, asymptotes to -60%
|
|
2064
|
+
albedo *= elevAO;
|
|
2022
2065
|
// displacement-normal relief: WORLD-SPACE UDN perturbation from surfTriNrm (each projection
|
|
2023
2066
|
// plane's tangent axes, not the radial frame). Amplitude capped low (scramble lesson d262b5e);
|
|
2024
2067
|
// applied AFTER the uReliefShade exaggeration below so the exaggeration never amplifies it.
|