mapspinner 0.1.35 → 0.1.36

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.35",
3
+ "version": "0.1.36",
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
@@ -49,7 +49,7 @@ export async function initMapspinnerRender(gl, opts = {}) {
49
49
  // (-52%) and tris/quad 1152->512 (-55%), so the per-vertex 14-oct broadShapeM VS (browser-9: 95% of
50
50
  // the low-alt frame) runs on ~half the vertices. median scales ~24/16 -> ~3.6px, far closer to the
51
51
  // band; the fine relief is carried per-pixel by the FS dFdx normal, not the mesh tessellation.
52
- const GRID = opts.gridMeshSize || 11; // mesh quads per edge. 16->11 (user 2026-06-14): FPS is TRIANGLE-THROUGHPUT bound, not broadShapeM ALU (octMax 12->3 left frame time flat; GRID is ~linear). GRID 8 was faster (-50%) but made BIOME CROSSOVER LINES JAGGED (climate varying interpolated across coarse triangles steps along edges) -- reverted to 11 (-37%). Proper fix to reclaim GRID 8 = per-pixel biome sampling in the FS. Override via ?grid=N.
52
+ const GRID = opts.gridMeshSize || 8; // mesh quads per edge. FPS is TRIANGLE/VERTEX-throughput bound (not ALU). 16->11->8 (user 2026-06-14 144fps push): GRID 8 reclaimed once the biome bands were WARPED (warpN, no longer straight contours) and the relief-faceting (dFdx(vH)) was removed, so the earlier GRID-8 jaggedness is gone. Override via ?grid=N.
53
53
  // Expose the LIVE mesh grid so screen-space-error diagnostics (planet.html __diag.pxPerPoly)
54
54
  // divide by the real polys/tile instead of a stale literal. Any future GRID change self-corrects
55
55
  // the metric (the 24->16 lever left pxPerPoly defaulting to 24 = 1.5x wrong band fraction).
@@ -177,7 +177,7 @@ export async function initMapspinnerPlanet(gl, opts = {}) {
177
177
  // count (orbit 860->20, lowalt 1272->328). 1.0 is the calibrated default; override live
178
178
  // via window.__splitFactor.
179
179
  const splitFactor = opts.splitFactor ?? 1.0;
180
- const gridMeshSize = opts.gridMeshSize || 11; // 16->11 FPS lever (triangle-throughput bound, not ALU; GRID 8 jagged biome crossovers, see gl-render.js GRID)
180
+ const gridMeshSize = opts.gridMeshSize || 8; // 16->11 FPS lever (triangle-throughput bound, not ALU; GRID 8 jagged biome crossovers, see gl-render.js GRID)
181
181
 
182
182
  gl.getExtension('EXT_color_buffer_float'); // RGBA32F atlas render targets
183
183
  // OES_texture_float_linear lets the driver LINEAR-filter the RGBA32F HPF/elevation textures. When
@@ -964,20 +964,24 @@ void main() {
964
964
  // so it never drops below the mesh cell (would re-alias) nor exceeds ~1/3 the tile.
965
965
  highp float nStepM = (uNrmStepM > 0.0) ? uNrmStepM : 300.0;
966
966
  highp float duP = clamp(nStepM / max(defOffset.z, 1.0), 1.0 / ((uGrid > 0.0) ? uGrid : 16.0), 0.34);
967
- highp float hPU = 0.0, hMU = 0.0, hPV = 0.0, hMV = 0.0;
968
- highp vec3 dPU = dir0, dMU = dir0, dPV = dir0, dMV = dir0;
969
- int fdIters = (uGrid >= 0.0) ? 4 : 1; // 4 offset taps; runtime-bounded (FXC unroll-defeat, see uOctMax)
967
+ // 3-TAP FORWARD (FPS push 2026-06-14: target 144fps): center + 2 FORWARD offsets, NOT the 5-tap
968
+ // central. The central was added for jaggedness, but the actual jaggedness root was the dFdx(vH)
969
+ // relief term (now removed) -- at the LOW-PASS step (duP ~300m >> vertex spacing) the forward vs
970
+ // central asymmetry is negligible while it costs 3 composeHeight/vertex instead of 5 (-40% of the
971
+ // dominant VS cost). Still captures vtxDisplace (faceWarp shifts both dir+faceLocal per tap).
972
+ highp float hPU = 0.0, hPV = 0.0;
973
+ highp vec3 dPU = dir0, dPV = dir0;
974
+ int fdIters = (uGrid >= 0.0) ? 2 : 1; // 2 forward offset taps (+ center hN0) = 3-tap normal; runtime-bounded (FXC unroll-defeat)
970
975
  for (int i = 0; i < fdIters; i++) {
971
- highp vec2 off = (i == 0) ? vec2(duP, 0.0) : (i == 1) ? vec2(-duP, 0.0) : (i == 2) ? vec2(0.0, duP) : vec2(0.0, -duP);
976
+ highp vec2 off = (i == 0) ? vec2(duP, 0.0) : vec2(0.0, duP);
972
977
  highp vec2 fl = faceWarp((vertex.xy + off) * defOffset.z + defOffset.xy);
973
978
  highp vec3 dd = normalize(defLocalToWorld * vec3(fl, defRadius));
974
979
  highp float hh = composeHeight(dd, fl, defOffset.z);
975
- if (i == 0) { hPU = hh; dPU = dd; } else if (i == 1) { hMU = hh; dMU = dd; }
976
- else if (i == 2) { hPV = hh; dPV = dd; } else { hMV = hh; dMV = dd; }
980
+ if (i == 0) { hPU = hh; dPU = dd; } else { hPV = hh; dPV = dd; }
977
981
  }
978
- highp vec3 wPU = dPU * (defRadius + hPU), wMU = dMU * (defRadius + hMU);
979
- highp vec3 wPV = dPV * (defRadius + hPV), wMV = dMV * (defRadius + hMV);
980
- vN = normalize(cross(wPU - wMU, wPV - wMV));
982
+ highp vec3 wC = dir0 * (defRadius + hN0);
983
+ highp vec3 wU = dPU * (defRadius + hPU), wV = dPV * (defRadius + hPV);
984
+ vN = normalize(cross(wU - wC, wV - wC));
981
985
  if (dot(vN, dir0) < 0.0) vN = -vN; // keep it outward (terrain has no overhangs)
982
986
  }
983
987
  highp float h = hN0;