@developmentseed/deck.gl-raster 0.7.0 → 0.8.0-beta.1

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.
Files changed (54) hide show
  1. package/dist/fp64.d.ts +18 -0
  2. package/dist/fp64.d.ts.map +1 -0
  3. package/dist/fp64.js +28 -0
  4. package/dist/fp64.js.map +1 -0
  5. package/dist/globe-grid-mesh.d.ts +30 -0
  6. package/dist/globe-grid-mesh.d.ts.map +1 -0
  7. package/dist/globe-grid-mesh.js +67 -0
  8. package/dist/globe-grid-mesh.js.map +1 -0
  9. package/dist/gpu-modules/cutline-bbox.d.ts +26 -40
  10. package/dist/gpu-modules/cutline-bbox.d.ts.map +1 -1
  11. package/dist/gpu-modules/cutline-bbox.js +24 -53
  12. package/dist/gpu-modules/cutline-bbox.js.map +1 -1
  13. package/dist/gpu-modules/index.d.ts +1 -1
  14. package/dist/gpu-modules/index.d.ts.map +1 -1
  15. package/dist/gpu-modules/index.js +1 -1
  16. package/dist/gpu-modules/index.js.map +1 -1
  17. package/dist/mesh-layer/mesh-layer-fragment.glsl.d.ts +1 -1
  18. package/dist/mesh-layer/mesh-layer-fragment.glsl.js +1 -1
  19. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts +3 -0
  20. package/dist/mesh-layer/mesh-layer-vertex.glsl.d.ts.map +1 -0
  21. package/dist/mesh-layer/mesh-layer-vertex.glsl.js +90 -0
  22. package/dist/mesh-layer/mesh-layer-vertex.glsl.js.map +1 -0
  23. package/dist/mesh-layer/mesh-layer.d.ts +27 -4
  24. package/dist/mesh-layer/mesh-layer.d.ts.map +1 -1
  25. package/dist/mesh-layer/mesh-layer.js +39 -3
  26. package/dist/mesh-layer/mesh-layer.js.map +1 -1
  27. package/dist/raster-layer.d.ts +18 -1
  28. package/dist/raster-layer.d.ts.map +1 -1
  29. package/dist/raster-layer.js +46 -19
  30. package/dist/raster-layer.js.map +1 -1
  31. package/dist/raster-tile-layer/raster-tile-layer.d.ts.map +1 -1
  32. package/dist/raster-tile-layer/raster-tile-layer.js +29 -21
  33. package/dist/raster-tile-layer/raster-tile-layer.js.map +1 -1
  34. package/dist/raster-tileset/bounding-volume-cache.d.ts +11 -4
  35. package/dist/raster-tileset/bounding-volume-cache.d.ts.map +1 -1
  36. package/dist/raster-tileset/bounding-volume-cache.js +13 -4
  37. package/dist/raster-tileset/bounding-volume-cache.js.map +1 -1
  38. package/dist/raster-tileset/raster-tile-traversal.d.ts +58 -3
  39. package/dist/raster-tileset/raster-tile-traversal.d.ts.map +1 -1
  40. package/dist/raster-tileset/raster-tile-traversal.js +235 -30
  41. package/dist/raster-tileset/raster-tile-traversal.js.map +1 -1
  42. package/dist/raster-tileset/raster-tileset-2d.d.ts +33 -0
  43. package/dist/raster-tileset/raster-tileset-2d.d.ts.map +1 -1
  44. package/dist/raster-tileset/raster-tileset-2d.js +46 -1
  45. package/dist/raster-tileset/raster-tileset-2d.js.map +1 -1
  46. package/dist/raster-tileset/web-mercator-clamp.d.ts +29 -0
  47. package/dist/raster-tileset/web-mercator-clamp.d.ts.map +1 -0
  48. package/dist/raster-tileset/web-mercator-clamp.js +54 -0
  49. package/dist/raster-tileset/web-mercator-clamp.js.map +1 -0
  50. package/package.json +7 -7
  51. package/dist/raster-tile-layer/constants.d.ts +0 -11
  52. package/dist/raster-tile-layer/constants.d.ts.map +0 -1
  53. package/dist/raster-tile-layer/constants.js +0 -11
  54. package/dist/raster-tile-layer/constants.js.map +0 -1
package/dist/fp64.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Split a Float64Array into the high + low Float32 component arrays used for
3
+ * fp64-emulated positions on the GPU.
4
+ *
5
+ * For each element `v`, the high part is `Math.fround(v)` (the nearest
6
+ * float32) and the low part is the residual `v - Math.fround(v)` (also exactly
7
+ * representable as a float32, since `|residual| <= ulp_f32(v) / 2`). Summed in
8
+ * the shader, the pair carries float64-equivalent precision — deck.gl's
9
+ * projection shader takes both via its `position64Low` parameter and adds
10
+ * `modelMatrix * low` back after the main computation.
11
+ *
12
+ * @returns `[low, high]` — both `Float32Array`s the same length as `values`.
13
+ *
14
+ * See `dev-docs/coordinate-systems.md` and
15
+ * `dev-docs/specs/2026-05-19-high-zoom-precision-design.md`.
16
+ */
17
+ export declare function splitFloat64Array(values: Float64Array): [low: Float32Array, high: Float32Array];
18
+ //# sourceMappingURL=fp64.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fp64.d.ts","sourceRoot":"","sources":["../src/fp64.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,GACnB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,CAAC,CAUzC"}
package/dist/fp64.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Split a Float64Array into the high + low Float32 component arrays used for
3
+ * fp64-emulated positions on the GPU.
4
+ *
5
+ * For each element `v`, the high part is `Math.fround(v)` (the nearest
6
+ * float32) and the low part is the residual `v - Math.fround(v)` (also exactly
7
+ * representable as a float32, since `|residual| <= ulp_f32(v) / 2`). Summed in
8
+ * the shader, the pair carries float64-equivalent precision — deck.gl's
9
+ * projection shader takes both via its `position64Low` parameter and adds
10
+ * `modelMatrix * low` back after the main computation.
11
+ *
12
+ * @returns `[low, high]` — both `Float32Array`s the same length as `values`.
13
+ *
14
+ * See `dev-docs/coordinate-systems.md` and
15
+ * `dev-docs/specs/2026-05-19-high-zoom-precision-design.md`.
16
+ */
17
+ export function splitFloat64Array(values) {
18
+ const low = new Float32Array(values.length);
19
+ const high = new Float32Array(values.length);
20
+ for (let i = 0; i < values.length; i++) {
21
+ const v = values[i];
22
+ const hi = Math.fround(v);
23
+ high[i] = hi;
24
+ low[i] = v - hi;
25
+ }
26
+ return [low, high];
27
+ }
28
+ //# sourceMappingURL=fp64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fp64.js","sourceRoot":"","sources":["../src/fp64.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACrB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ReprojectionFns } from "@developmentseed/raster-reproject";
2
+ /**
3
+ * Default per-tile grid resolution for the globe scaffold. An `n × n` grid of
4
+ * cells (so `(n+1)²` vertices). 32 keeps low-zoom tiles smooth on the sphere
5
+ * while staying cheap (≈1089 verts / 2048 triangles per tile).
6
+ */
7
+ export declare const GLOBE_GRID_SIZE = 32;
8
+ /**
9
+ * THROWAWAY globe scaffold. Builds a uniform `gridSize × gridSize` triangle
10
+ * grid over a tile in UV space and reprojects each vertex through the same
11
+ * `forwardTransform` → `forwardReproject` chain {@link RasterReprojector} uses,
12
+ * producing output positions in the layer's output CRS (lng/lat in globe mode).
13
+ *
14
+ * Why this exists: the adaptive Delatin mesh subdivides on *reprojection*
15
+ * error, which is ~0 for an EPSG:4326 source, so it emits 2 triangles that
16
+ * chord straight through the sphere and visibly facet at low zoom. A uniform
17
+ * grid is a stopgap so the prototype is legible. It is NOT the real fix —
18
+ * remove it once sphere-aware reprojection lands. See
19
+ * `dev-docs/specs/2026-05-21-globe-view-design.md`.
20
+ *
21
+ * `width`/`height` match {@link RasterReprojector}'s convention (pass the
22
+ * image dimensions + 1); pixel coordinates span `[0, width-1] × [0, height-1]`.
23
+ */
24
+ export declare function buildUniformGridMesh(reprojectionFns: ReprojectionFns, width: number, height: number, gridSize?: number): {
25
+ indices: Uint32Array;
26
+ positions64High: Float32Array;
27
+ positions64Low: Float32Array;
28
+ texCoords: Float32Array;
29
+ };
30
+ //# sourceMappingURL=globe-grid-mesh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globe-grid-mesh.d.ts","sourceRoot":"","sources":["../src/globe-grid-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE;;;;GAIG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAwB,GACjC;IACD,OAAO,EAAE,WAAW,CAAC;IACrB,eAAe,EAAE,YAAY,CAAC;IAC9B,cAAc,EAAE,YAAY,CAAC;IAC7B,SAAS,EAAE,YAAY,CAAC;CACzB,CA+CA"}
@@ -0,0 +1,67 @@
1
+ import { splitFloat64Array } from "./fp64.js";
2
+ /**
3
+ * Default per-tile grid resolution for the globe scaffold. An `n × n` grid of
4
+ * cells (so `(n+1)²` vertices). 32 keeps low-zoom tiles smooth on the sphere
5
+ * while staying cheap (≈1089 verts / 2048 triangles per tile).
6
+ */
7
+ export const GLOBE_GRID_SIZE = 32;
8
+ /**
9
+ * THROWAWAY globe scaffold. Builds a uniform `gridSize × gridSize` triangle
10
+ * grid over a tile in UV space and reprojects each vertex through the same
11
+ * `forwardTransform` → `forwardReproject` chain {@link RasterReprojector} uses,
12
+ * producing output positions in the layer's output CRS (lng/lat in globe mode).
13
+ *
14
+ * Why this exists: the adaptive Delatin mesh subdivides on *reprojection*
15
+ * error, which is ~0 for an EPSG:4326 source, so it emits 2 triangles that
16
+ * chord straight through the sphere and visibly facet at low zoom. A uniform
17
+ * grid is a stopgap so the prototype is legible. It is NOT the real fix —
18
+ * remove it once sphere-aware reprojection lands. See
19
+ * `dev-docs/specs/2026-05-21-globe-view-design.md`.
20
+ *
21
+ * `width`/`height` match {@link RasterReprojector}'s convention (pass the
22
+ * image dimensions + 1); pixel coordinates span `[0, width-1] × [0, height-1]`.
23
+ */
24
+ export function buildUniformGridMesh(reprojectionFns, width, height, gridSize = GLOBE_GRID_SIZE) {
25
+ const { forwardTransform, forwardReproject } = reprojectionFns;
26
+ const cols = gridSize;
27
+ const rows = gridSize;
28
+ const numVerts = (cols + 1) * (rows + 1);
29
+ const positions = new Float64Array(numVerts * 3);
30
+ const texCoords = new Float32Array(numVerts * 2);
31
+ let vi = 0;
32
+ for (let r = 0; r <= rows; r++) {
33
+ for (let c = 0; c <= cols; c++) {
34
+ const u = c / cols;
35
+ const v = r / rows;
36
+ const pixelX = u * (width - 1);
37
+ const pixelY = v * (height - 1);
38
+ const [inputX, inputY] = forwardTransform(pixelX, pixelY);
39
+ const [outX, outY] = forwardReproject(inputX, inputY);
40
+ positions[vi * 3] = outX;
41
+ positions[vi * 3 + 1] = outY;
42
+ positions[vi * 3 + 2] = 0;
43
+ texCoords[vi * 2] = u;
44
+ texCoords[vi * 2 + 1] = v;
45
+ vi++;
46
+ }
47
+ }
48
+ const [positions64Low, positions64High] = splitFloat64Array(positions);
49
+ const indices = new Uint32Array(cols * rows * 6);
50
+ let ii = 0;
51
+ for (let r = 0; r < rows; r++) {
52
+ for (let c = 0; c < cols; c++) {
53
+ const i0 = r * (cols + 1) + c;
54
+ const i1 = i0 + 1;
55
+ const i2 = i0 + (cols + 1);
56
+ const i3 = i2 + 1;
57
+ indices[ii++] = i0;
58
+ indices[ii++] = i2;
59
+ indices[ii++] = i1;
60
+ indices[ii++] = i1;
61
+ indices[ii++] = i2;
62
+ indices[ii++] = i3;
63
+ }
64
+ }
65
+ return { indices, positions64High, positions64Low, texCoords };
66
+ }
67
+ //# sourceMappingURL=globe-grid-mesh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globe-grid-mesh.js","sourceRoot":"","sources":["../src/globe-grid-mesh.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,23 @@
1
1
  /** Props for the {@link CutlineBbox} shader module. */
2
2
  export type CutlineBboxProps = {
3
3
  /**
4
- * Axis-aligned bbox in **EPSG:3857 meters**, packed as
5
- * `[minX, minY, maxX, maxY]`. This must be in the same coordinate space
6
- * as the layer's mesh `positions` attribute — for `COGLayer` /
7
- * `RasterLayer`'s Web Mercator rendering path, that is raw 3857 meters.
4
+ * Axis-aligned clip region in deck.gl **common space** (world units),
5
+ * packed as `[minX, minY, maxX, maxY]`. This must be in the same coordinate
6
+ * space as the layer's mesh `positions` attribute — for `COGLayer` /
7
+ * `RasterLayer`'s Web Mercator rendering path, that is deck.gl common space.
8
8
  *
9
- * Use {@link lngLatToMercator} to project a WGS84 lng/lat bbox once
10
- * at bbox definition time.
9
+ * Project a WGS84 lng/lat bbox to common space **once at bbox definition
10
+ * time** with deck.gl's `WebMercatorViewport.projectPosition` (or
11
+ * `@math.gl/web-mercator`'s `lngLatToWorld`). Do *not* convert per frame:
12
+ * `getUniforms` here is a pass-through, but luma.gl calls it on every
13
+ * `setProps` (i.e. every draw), so any projection placed in it would run
14
+ * each animation frame.
11
15
  */
12
- bbox: [number, number, number, number];
16
+ bbox: [minX: number, minY: number, maxX: number, maxY: number];
13
17
  };
14
18
  /**
15
- * A shader module that discards fragments whose position falls outside a
16
- * Web Mercator (EPSG:3857) axis-aligned bbox.
19
+ * A shader module that discards fragments whose position falls outside an
20
+ * axis-aligned common-space bbox.
17
21
  *
18
22
  * Intended for rendering rasters with a "map collar" (e.g. USGS historical
19
23
  * topographic maps) where the valid data area is described as a bbox but
@@ -23,49 +27,31 @@ export type CutlineBboxProps = {
23
27
  * responsible for enforcing this in application code; the module itself
24
28
  * does not have viewport access.
25
29
  *
26
- * This module assumes the layer's mesh `positions` attribute is in EPSG:3857
27
- * meters — the convention used by `COGLayer` / `RasterLayer` in Web Mercator
28
- * rendering mode. It injects a vertex shader varying that passes each
29
- * vertex's 3857 meters through to the fragment shader, and compares against
30
- * a uniform bbox also in 3857 meters. This avoids deck.gl's common space and
31
- * its viewport-anchored precision translation, which would otherwise cause
32
- * the test to drift at higher zoom levels.
30
+ * The module assumes the layer's mesh `positions` attribute is in deck.gl
31
+ * **common space** (world units) — the convention used by `COGLayer` /
32
+ * `RasterLayer` in the Web Mercator rendering path. It injects a vertex
33
+ * shader varying that passes each vertex's common-space position through to
34
+ * the fragment shader, and compares against a uniform bbox also in common
35
+ * space. Capturing the raw `positions` attribute (rather than deck.gl's
36
+ * viewport-anchored, camera-relative `position_commonspace`) keeps the test
37
+ * stable across zoom levels.
33
38
  */
34
39
  export declare const CutlineBbox: {
35
40
  readonly name: "cutlineBbox";
36
41
  readonly fs: "uniform cutlineBboxUniforms {\n vec4 bbox;\n} cutlineBbox;\n";
37
42
  readonly inject: {
38
- readonly "vs:#decl": "out vec2 v_cutlineBboxMercator;";
39
- readonly "vs:#main-start": "\n v_cutlineBboxMercator = positions.xy;\n ";
40
- readonly "fs:#decl": "in vec2 v_cutlineBboxMercator;";
41
- readonly "fs:#main-start": "\n {\n if (v_cutlineBboxMercator.x < cutlineBbox.bbox.x ||\n v_cutlineBboxMercator.x > cutlineBbox.bbox.z ||\n v_cutlineBboxMercator.y < cutlineBbox.bbox.y ||\n v_cutlineBboxMercator.y > cutlineBbox.bbox.w) {\n discard;\n }\n }\n ";
43
+ readonly "vs:#decl": "out vec2 v_cutlineBboxCommon;";
44
+ readonly "vs:#main-start": "\n v_cutlineBboxCommon = positions.xy;\n ";
45
+ readonly "fs:#decl": "in vec2 v_cutlineBboxCommon;";
46
+ readonly "fs:#main-start": "\n {\n if (v_cutlineBboxCommon.x < cutlineBbox.bbox.x ||\n v_cutlineBboxCommon.x > cutlineBbox.bbox.z ||\n v_cutlineBboxCommon.y < cutlineBbox.bbox.y ||\n v_cutlineBboxCommon.y > cutlineBbox.bbox.w) {\n discard;\n }\n }\n ";
42
47
  };
43
48
  readonly uniformTypes: {
44
49
  readonly bbox: "vec4<f32>";
45
50
  };
46
51
  readonly getUniforms: (props: Partial<CutlineBboxProps>) => {
47
- bbox: [number, number, number, number];
52
+ bbox: [minX: number, minY: number, maxX: number, maxY: number];
48
53
  } | {
49
54
  bbox?: undefined;
50
55
  };
51
56
  };
52
- /**
53
- * Project a single WGS84 lng/lat point (degrees) to EPSG:3857 meters.
54
- *
55
- * Throws if the latitude falls outside the Web Mercator projection's valid
56
- * range (±85.051129°).
57
- *
58
- * This is intended to be used with the {@link CutlineBbox} module, which
59
- * expects a bbox in 3857 meters. The conversion from WGS84 to 3857 is a
60
- * one-time cost that can be done at bbox definition time, rather than per frame
61
- * in the shader.
62
- *
63
- * @example
64
- * ```ts
65
- * const [west, south] = lngLatToMercator(-120.75, 39.25);
66
- * const [east, north] = lngLatToMercator(-120.5, 39.5);
67
- * const bbox = [west, south, east, north];
68
- * ```
69
- */
70
- export declare function lngLatToMercator(lng: number, lat: number): [number, number];
71
57
  //# sourceMappingURL=cutline-bbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cutline-bbox.d.ts","sourceRoot":"","sources":["../../src/gpu-modules/cutline-bbox.ts"],"names":[],"mappings":"AAQA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;;OAQG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAUF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;kCAyCD,OAAO,CAAC,gBAAgB,CAAC;;;;;CAEG,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAU3E"}
1
+ {"version":3,"file":"cutline-bbox.d.ts","sourceRoot":"","sources":["../../src/gpu-modules/cutline-bbox.ts"],"names":[],"mappings":"AAEA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAUF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;kCAyCD,OAAO,CAAC,gBAAgB,CAAC;;;;;CAEG,CAAC"}
@@ -1,7 +1,3 @@
1
- /** Earth equatorial radius used by Web Mercator (WGS84 / EPSG:3857). */
2
- const EARTH_RADIUS = 6378137.0;
3
- /** Web Mercator latitude limit in degrees. */
4
- const MERCATOR_LAT_LIMIT = 85.051129;
5
1
  const MODULE_NAME = "cutlineBbox";
6
2
  const uniformBlock = `\
7
3
  uniform ${MODULE_NAME}Uniforms {
@@ -9,8 +5,8 @@ uniform ${MODULE_NAME}Uniforms {
9
5
  } ${MODULE_NAME};
10
6
  `;
11
7
  /**
12
- * A shader module that discards fragments whose position falls outside a
13
- * Web Mercator (EPSG:3857) axis-aligned bbox.
8
+ * A shader module that discards fragments whose position falls outside an
9
+ * axis-aligned common-space bbox.
14
10
  *
15
11
  * Intended for rendering rasters with a "map collar" (e.g. USGS historical
16
12
  * topographic maps) where the valid data area is described as a bbox but
@@ -20,28 +16,29 @@ uniform ${MODULE_NAME}Uniforms {
20
16
  * responsible for enforcing this in application code; the module itself
21
17
  * does not have viewport access.
22
18
  *
23
- * This module assumes the layer's mesh `positions` attribute is in EPSG:3857
24
- * meters — the convention used by `COGLayer` / `RasterLayer` in Web Mercator
25
- * rendering mode. It injects a vertex shader varying that passes each
26
- * vertex's 3857 meters through to the fragment shader, and compares against
27
- * a uniform bbox also in 3857 meters. This avoids deck.gl's common space and
28
- * its viewport-anchored precision translation, which would otherwise cause
29
- * the test to drift at higher zoom levels.
19
+ * The module assumes the layer's mesh `positions` attribute is in deck.gl
20
+ * **common space** (world units) — the convention used by `COGLayer` /
21
+ * `RasterLayer` in the Web Mercator rendering path. It injects a vertex
22
+ * shader varying that passes each vertex's common-space position through to
23
+ * the fragment shader, and compares against a uniform bbox also in common
24
+ * space. Capturing the raw `positions` attribute (rather than deck.gl's
25
+ * viewport-anchored, camera-relative `position_commonspace`) keeps the test
26
+ * stable across zoom levels.
30
27
  */
31
28
  export const CutlineBbox = {
32
29
  name: MODULE_NAME,
33
30
  fs: uniformBlock,
34
31
  inject: {
35
- // Declare the mercator-meters varying on both sides of the pipeline.
36
- "vs:#decl": `out vec2 v_cutlineBboxMercator;`,
32
+ // Declare the common-space varying on both sides of the pipeline.
33
+ "vs:#decl": `out vec2 v_cutlineBboxCommon;`,
37
34
  // `positions` is the per-vertex attribute the SimpleMeshLayer vertex
38
35
  // shader reads (see @deck.gl/mesh-layers simple-mesh-layer-vertex.glsl).
39
- // In COGLayer's CARTESIAN + web-mercator path this attribute is already
40
- // in EPSG:3857 meters. We capture it before any projection is applied.
36
+ // In COGLayer's CARTESIAN + web-mercator path this attribute is in deck.gl
37
+ // common space. We capture it before any projection is applied.
41
38
  "vs:#main-start": /* glsl */ `
42
- v_cutlineBboxMercator = positions.xy;
39
+ v_cutlineBboxCommon = positions.xy;
43
40
  `,
44
- "fs:#decl": `in vec2 v_cutlineBboxMercator;`,
41
+ "fs:#decl": `in vec2 v_cutlineBboxCommon;`,
45
42
  // Injects at fs:#main-start (not fs:DECKGL_FILTER_COLOR). The
46
43
  // DECKGL_FILTER_COLOR hook is a generated function whose body is assembled
47
44
  // before the main FS source; top-level FS varyings declared in the main
@@ -49,15 +46,15 @@ export const CutlineBbox = {
49
46
  // inside main() where the varying is visible and discard still works.
50
47
  //
51
48
  // Globe support: when rendering in a GlobeView, the mesh positions are in
52
- // 4326 lng/lat rather than 3857 meters, so this exact varying is no
49
+ // 4326 lng/lat rather than common space, so this exact varying is no
53
50
  // longer meaningful. A future globe code path would need a different
54
51
  // varying (e.g. lng/lat pair) and matching uniform layout.
55
52
  "fs:#main-start": /* glsl */ `
56
53
  {
57
- if (v_cutlineBboxMercator.x < ${MODULE_NAME}.bbox.x ||
58
- v_cutlineBboxMercator.x > ${MODULE_NAME}.bbox.z ||
59
- v_cutlineBboxMercator.y < ${MODULE_NAME}.bbox.y ||
60
- v_cutlineBboxMercator.y > ${MODULE_NAME}.bbox.w) {
54
+ if (v_cutlineBboxCommon.x < ${MODULE_NAME}.bbox.x ||
55
+ v_cutlineBboxCommon.x > ${MODULE_NAME}.bbox.z ||
56
+ v_cutlineBboxCommon.y < ${MODULE_NAME}.bbox.y ||
57
+ v_cutlineBboxCommon.y > ${MODULE_NAME}.bbox.w) {
61
58
  discard;
62
59
  }
63
60
  }
@@ -66,35 +63,9 @@ export const CutlineBbox = {
66
63
  uniformTypes: {
67
64
  bbox: "vec4<f32>",
68
65
  },
69
- // Pass-through: the bbox is expected to already be in 3857 meters. The
70
- // conversion from WGS84 is done by `lngLatBboxToMercator` at bbox
71
- // definition time so it does not run in the per-frame render loop.
66
+ // Pass-through: the bbox is expected to already be in common space. Projection
67
+ // from WGS84 is done once at bbox definition time (see the prop docs), not
68
+ // here luma.gl calls getUniforms on every setProps / draw.
72
69
  getUniforms: (props) => props.bbox ? { bbox: props.bbox } : {},
73
70
  };
74
- /**
75
- * Project a single WGS84 lng/lat point (degrees) to EPSG:3857 meters.
76
- *
77
- * Throws if the latitude falls outside the Web Mercator projection's valid
78
- * range (±85.051129°).
79
- *
80
- * This is intended to be used with the {@link CutlineBbox} module, which
81
- * expects a bbox in 3857 meters. The conversion from WGS84 to 3857 is a
82
- * one-time cost that can be done at bbox definition time, rather than per frame
83
- * in the shader.
84
- *
85
- * @example
86
- * ```ts
87
- * const [west, south] = lngLatToMercator(-120.75, 39.25);
88
- * const [east, north] = lngLatToMercator(-120.5, 39.5);
89
- * const bbox = [west, south, east, north];
90
- * ```
91
- */
92
- export function lngLatToMercator(lng, lat) {
93
- if (lat < -MERCATOR_LAT_LIMIT || lat > MERCATOR_LAT_LIMIT) {
94
- throw new Error(`lngLatToMercator: latitude must be within Web Mercator limits (±${MERCATOR_LAT_LIMIT}°); got lat=${lat}`);
95
- }
96
- const x = (EARTH_RADIUS * lng * Math.PI) / 180;
97
- const y = EARTH_RADIUS * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
98
- return [x, y];
99
- }
100
71
  //# sourceMappingURL=cutline-bbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cutline-bbox.js","sourceRoot":"","sources":["../../src/gpu-modules/cutline-bbox.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,MAAM,YAAY,GAAG,SAAS,CAAC;AAE/B,8CAA8C;AAC9C,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAgBrC,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,MAAM,YAAY,GAAG;UACX,WAAW;;IAEjB,WAAW;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,WAAW;IACjB,EAAE,EAAE,YAAY;IAChB,MAAM,EAAE;QACN,qEAAqE;QACrE,UAAU,EAAE,iCAAiC;QAC7C,qEAAqE;QACrE,yEAAyE;QACzE,wEAAwE;QACxE,uEAAuE;QACvE,gBAAgB,EAAE,UAAU,CAAC;;KAE5B;QACD,UAAU,EAAE,gCAAgC;QAC5C,8DAA8D;QAC9D,2EAA2E;QAC3E,wEAAwE;QACxE,yEAAyE;QACzE,sEAAsE;QACtE,EAAE;QACF,0EAA0E;QAC1E,oEAAoE;QACpE,qEAAqE;QACrE,2DAA2D;QAC3D,gBAAgB,EAAE,UAAU,CAAC;;wCAEO,WAAW;wCACX,WAAW;wCACX,WAAW;wCACX,WAAW;;;;KAI9C;KACF;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,WAAW;KAClB;IACD,uEAAuE;IACvE,kEAAkE;IAClE,mEAAmE;IACnE,WAAW,EAAE,CAAC,KAAgC,EAAE,EAAE,CAChD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;CACS,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,GAAW;IACvD,IAAI,GAAG,GAAG,CAAC,kBAAkB,IAAI,GAAG,GAAG,kBAAkB,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,mEAAmE,kBAAkB,eAAe,GAAG,EAAE,CAC1G,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IAC/C,MAAM,CAAC,GACL,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"cutline-bbox.js","sourceRoot":"","sources":["../../src/gpu-modules/cutline-bbox.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,MAAM,YAAY,GAAG;UACX,WAAW;;IAEjB,WAAW;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,WAAW;IACjB,EAAE,EAAE,YAAY;IAChB,MAAM,EAAE;QACN,kEAAkE;QAClE,UAAU,EAAE,+BAA+B;QAC3C,qEAAqE;QACrE,yEAAyE;QACzE,2EAA2E;QAC3E,gEAAgE;QAChE,gBAAgB,EAAE,UAAU,CAAC;;KAE5B;QACD,UAAU,EAAE,8BAA8B;QAC1C,8DAA8D;QAC9D,2EAA2E;QAC3E,wEAAwE;QACxE,yEAAyE;QACzE,sEAAsE;QACtE,EAAE;QACF,0EAA0E;QAC1E,qEAAqE;QACrE,qEAAqE;QACrE,2DAA2D;QAC3D,gBAAgB,EAAE,UAAU,CAAC;;sCAEK,WAAW;sCACX,WAAW;sCACX,WAAW;sCACX,WAAW;;;;KAI5C;KACF;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,WAAW;KAClB;IACD,+EAA+E;IAC/E,2EAA2E;IAC3E,6DAA6D;IAC7D,WAAW,EAAE,CAAC,KAAgC,EAAE,EAAE,CAChD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;CACS,CAAC"}
@@ -7,7 +7,7 @@ export { buildCompositeBandsProps, CompositeBands, } from "./composite-bands.js"
7
7
  export { createColormapTexture } from "./create-colormap-texture.js";
8
8
  export { CreateTexture } from "./create-texture.js";
9
9
  export type { CutlineBboxProps } from "./cutline-bbox.js";
10
- export { CutlineBbox, lngLatToMercator } from "./cutline-bbox.js";
10
+ export { CutlineBbox } from "./cutline-bbox.js";
11
11
  export type { ColormapSpriteSource } from "./decode-colormap-sprite.js";
12
12
  export { decodeColormapSprite } from "./decode-colormap-sprite.js";
13
13
  export { FilterNoDataVal } from "./filter-nodata.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gpu-modules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gpu-modules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -4,7 +4,7 @@ export { COLORMAP_INDEX, } from "./colormap-names.js";
4
4
  export { buildCompositeBandsProps, CompositeBands, } from "./composite-bands.js";
5
5
  export { createColormapTexture } from "./create-colormap-texture.js";
6
6
  export { CreateTexture } from "./create-texture.js";
7
- export { CutlineBbox, lngLatToMercator } from "./cutline-bbox.js";
7
+ export { CutlineBbox } from "./cutline-bbox.js";
8
8
  export { decodeColormapSprite } from "./decode-colormap-sprite.js";
9
9
  export { FilterNoDataVal } from "./filter-nodata.js";
10
10
  export { LinearRescale } from "./linear-rescale.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gpu-modules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gpu-modules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -7,6 +7,6 @@
7
7
  * support integer and signed integer textures, not only normalized unsigned
8
8
  * textures.
9
9
  */
10
- declare const _default: "#version 300 es\n#define SHADER_NAME simple-mesh-layer-fs\n\nprecision highp float;\n\nin vec2 vTexCoord;\nin vec3 cameraPosition;\nin vec3 normals_commonspace;\nin vec4 position_commonspace;\nin vec4 vColor;\n\nout vec4 fragColor;\n\nvoid main(void) {\n geometry.uv = vTexCoord;\n\n vec3 normal;\n if (simpleMesh.flatShading) {\n\n normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz)));\n } else {\n normal = normals_commonspace;\n }\n\n // We initialize color here before passing into DECKGL_FILTER_COLOR\n vec4 color;\n DECKGL_FILTER_COLOR(color, geometry);\n\n vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);\n fragColor = vec4(lightColor, color.a * layer.opacity);\n}\n";
10
+ declare const _default: "#version 300 es\n#define SHADER_NAME mesh-texture-layer-fs\n\nprecision highp float;\n\nin vec2 vTexCoord;\nin vec3 cameraPosition;\nin vec3 normals_commonspace;\nin vec4 position_commonspace;\nin vec4 vColor;\n\nout vec4 fragColor;\n\nvoid main(void) {\n geometry.uv = vTexCoord;\n\n vec3 normal;\n if (simpleMesh.flatShading) {\n\n normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz)));\n } else {\n normal = normals_commonspace;\n }\n\n // We initialize color here before passing into DECKGL_FILTER_COLOR\n vec4 color;\n DECKGL_FILTER_COLOR(color, geometry);\n\n vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);\n fragColor = vec4(lightColor, color.a * layer.opacity);\n}\n";
11
11
  export default _default;
12
12
  //# sourceMappingURL=mesh-layer-fragment.glsl.d.ts.map
@@ -8,7 +8,7 @@
8
8
  * textures.
9
9
  */
10
10
  export default /* glsl */ `#version 300 es
11
- #define SHADER_NAME simple-mesh-layer-fs
11
+ #define SHADER_NAME mesh-texture-layer-fs
12
12
 
13
13
  precision highp float;
14
14
 
@@ -0,0 +1,3 @@
1
+ declare const _default: "#version 300 es\n#define SHADER_NAME mesh-texture-layer-vs\n\n// Primitive attributes\nin vec3 positions;\nin vec3 positions64Low;\nin vec3 normals;\nin vec3 colors;\nin vec2 texCoords;\n\n// Instance attributes\nin vec3 instancePositions;\nin vec3 instancePositions64Low;\nin vec4 instanceColors;\nin vec3 instancePickingColors;\nin vec3 instanceModelMatrixCol0;\nin vec3 instanceModelMatrixCol1;\nin vec3 instanceModelMatrixCol2;\nin vec3 instanceTranslation;\n\n// Outputs to fragment shader\nout vec2 vTexCoord;\nout vec3 cameraPosition;\nout vec3 normals_commonspace;\nout vec4 position_commonspace;\nout vec4 vColor;\n\nvoid main(void) {\n geometry.worldPosition = instancePositions;\n geometry.uv = texCoords;\n geometry.pickingColor = instancePickingColors;\n\n vTexCoord = texCoords;\n cameraPosition = project.cameraPosition;\n vColor = vec4(colors * instanceColors.rgb, instanceColors.a);\n\n mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2);\n vec3 pos = (instanceModelMatrix * positions) * simpleMesh.sizeScale + instanceTranslation;\n\n DECKGL_FILTER_SIZE(pos, geometry);\n // Call project_normal before project_position so the normal isn't affected by\n // a position offset (unused for unlit raster, kept for parity with upstream).\n normals_commonspace = project_normal(instanceModelMatrix * normals);\n geometry.worldPosition += pos;\n\n // No composeModelMatrix branch: that flag only matters when placing an\n // instanced model offset from an anchor. MeshTextureLayer always draws one\n // mesh at instancePositions = [0,0,0] with identity transforms, so we project\n // the mesh vertex directly (with its fp64 low part). This is correct for both\n // cartesian (common-space, Web Mercator) and lnglat (degrees, GlobeView) \u2014\n // project_position_to_clipspace handles each coordinate system.\n gl_Position = project_position_to_clipspace(pos + instancePositions, positions64Low + instancePositions64Low, vec3(0.0), position_commonspace);\n geometry.position = position_commonspace;\n\n geometry.normal = normals_commonspace;\n DECKGL_FILTER_GL_POSITION(gl_Position, geometry);\n\n DECKGL_FILTER_COLOR(vColor, geometry);\n}\n";
2
+ export default _default;
3
+ //# sourceMappingURL=mesh-layer-vertex.glsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-layer-vertex.glsl.d.ts","sourceRoot":"","sources":["../../src/mesh-layer/mesh-layer-vertex.glsl.ts"],"names":[],"mappings":";AA8BA,wBA2DE"}
@@ -0,0 +1,90 @@
1
+ // Vertex shader for MeshTextureLayer. Override of upstream's
2
+ // simple-mesh-layer-vertex.glsl.ts (deck.gl 9.3 @
3
+ // 09af8de8d18a9cb9a31d064cae8f9e7239df7f53):
4
+ // https://github.com/visgl/deck.gl/blob/09af8de8d18a9cb9a31d064cae8f9e7239df7f53/modules/mesh-layers/src/simple-mesh-layer/simple-mesh-layer-vertex.glsl.ts
5
+ //
6
+ // Differences from upstream:
7
+ // 1. Adds `in vec3 positions64Low;` — per-vertex low part of the
8
+ // fp64-split mesh position. Supplied by MeshTextureLayer via
9
+ // attributeManager.add (non-instanced).
10
+ // 2. Passes `positions64Low + instancePositions64Low` to
11
+ // project_position_to_clipspace, so the shader's fp64 path recovers the
12
+ // mesh-vertex precision lost by the float32 attribute pipeline.
13
+ // 3. Collapses upstream's `composeModelMatrix` branch to a single
14
+ // direct-projection path. MeshTextureLayer always draws ONE
15
+ // non-instanced, identity-transform mesh anchored at the origin
16
+ // (instancePositions = [0,0,0], identity instanceModelMatrix, sizeScale =
17
+ // 1), so the instanced / meters-offset (upstream's `else`) branch never
18
+ // applied. Projecting `pos` directly is correct for BOTH cartesian
19
+ // (common-space mesh, Web Mercator) and lnglat (degrees, GlobeView):
20
+ // project_position_to_clipspace handles each coordinate system. This is
21
+ // what makes GlobeView render correctly — upstream's `else` branch ran
22
+ // project_size(pos) on lng/lat degrees, which is meaningless. See
23
+ // dev-docs/specs/2026-05-21-globe-view-design.md.
24
+ //
25
+ // The fp64 correction is only valid when the per-instance transforms are
26
+ // identity. MeshTextureLayer enforces that by fixing those props and omitting
27
+ // them from its public prop type (see MeshTextureLayer's class doc). See
28
+ // dev-docs/specs/2026-05-19-high-zoom-precision-design.md and
29
+ // dev-docs/coordinate-systems.md.
30
+ export default /* glsl */ `#version 300 es
31
+ #define SHADER_NAME mesh-texture-layer-vs
32
+
33
+ // Primitive attributes
34
+ in vec3 positions;
35
+ in vec3 positions64Low;
36
+ in vec3 normals;
37
+ in vec3 colors;
38
+ in vec2 texCoords;
39
+
40
+ // Instance attributes
41
+ in vec3 instancePositions;
42
+ in vec3 instancePositions64Low;
43
+ in vec4 instanceColors;
44
+ in vec3 instancePickingColors;
45
+ in vec3 instanceModelMatrixCol0;
46
+ in vec3 instanceModelMatrixCol1;
47
+ in vec3 instanceModelMatrixCol2;
48
+ in vec3 instanceTranslation;
49
+
50
+ // Outputs to fragment shader
51
+ out vec2 vTexCoord;
52
+ out vec3 cameraPosition;
53
+ out vec3 normals_commonspace;
54
+ out vec4 position_commonspace;
55
+ out vec4 vColor;
56
+
57
+ void main(void) {
58
+ geometry.worldPosition = instancePositions;
59
+ geometry.uv = texCoords;
60
+ geometry.pickingColor = instancePickingColors;
61
+
62
+ vTexCoord = texCoords;
63
+ cameraPosition = project.cameraPosition;
64
+ vColor = vec4(colors * instanceColors.rgb, instanceColors.a);
65
+
66
+ mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2);
67
+ vec3 pos = (instanceModelMatrix * positions) * simpleMesh.sizeScale + instanceTranslation;
68
+
69
+ DECKGL_FILTER_SIZE(pos, geometry);
70
+ // Call project_normal before project_position so the normal isn't affected by
71
+ // a position offset (unused for unlit raster, kept for parity with upstream).
72
+ normals_commonspace = project_normal(instanceModelMatrix * normals);
73
+ geometry.worldPosition += pos;
74
+
75
+ // No composeModelMatrix branch: that flag only matters when placing an
76
+ // instanced model offset from an anchor. MeshTextureLayer always draws one
77
+ // mesh at instancePositions = [0,0,0] with identity transforms, so we project
78
+ // the mesh vertex directly (with its fp64 low part). This is correct for both
79
+ // cartesian (common-space, Web Mercator) and lnglat (degrees, GlobeView) —
80
+ // project_position_to_clipspace handles each coordinate system.
81
+ gl_Position = project_position_to_clipspace(pos + instancePositions, positions64Low + instancePositions64Low, vec3(0.0), position_commonspace);
82
+ geometry.position = position_commonspace;
83
+
84
+ geometry.normal = normals_commonspace;
85
+ DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
86
+
87
+ DECKGL_FILTER_COLOR(vColor, geometry);
88
+ }
89
+ `;
90
+ //# sourceMappingURL=mesh-layer-vertex.glsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-layer-vertex.glsl.js","sourceRoot":"","sources":["../../src/mesh-layer/mesh-layer-vertex.glsl.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,kDAAkD;AAClD,6CAA6C;AAC7C,4JAA4J;AAC5J,EAAE;AACF,6BAA6B;AAC7B,mEAAmE;AACnE,kEAAkE;AAClE,6CAA6C;AAC7C,2DAA2D;AAC3D,6EAA6E;AAC7E,qEAAqE;AACrE,oEAAoE;AACpE,iEAAiE;AACjE,qEAAqE;AACrE,+EAA+E;AAC/E,6EAA6E;AAC7E,wEAAwE;AACxE,0EAA0E;AAC1E,6EAA6E;AAC7E,4EAA4E;AAC5E,uEAAuE;AACvE,uDAAuD;AACvD,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,yEAAyE;AACzE,8DAA8D;AAC9D,kCAAkC;AAElC,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DzB,CAAC"}
@@ -2,6 +2,16 @@ import type { DefaultProps, TextureSource, UpdateParameters } from "@deck.gl/cor
2
2
  import type { SimpleMeshLayerProps } from "@deck.gl/mesh-layers";
3
3
  import { SimpleMeshLayer } from "@deck.gl/mesh-layers";
4
4
  import type { RasterModule } from "../gpu-modules/types.js";
5
+ /**
6
+ * `SimpleMeshLayer` props that `MeshTextureLayer` deliberately does not
7
+ * support. They configure per-instance 3D-model placement, which is
8
+ * meaningless for our single-mesh-at-the-origin use case — and a non-identity
9
+ * value would silently break the fp64 mesh-vertex precision correction (the
10
+ * `positions64Low` low part is the residual of `positions`, not of a
11
+ * transformed `pos`). They are fixed internally (see `defaultProps`) and
12
+ * omitted from the public prop type so they can't be set.
13
+ */
14
+ type ExcludedSimpleMeshProps = "_instanced" | "getPosition" | "getOrientation" | "getScale" | "getTranslation" | "getTransformMatrix" | "sizeScale";
5
15
  type _MeshTextureLayerProps = {
6
16
  image: TextureSource;
7
17
  renderPipeline?: RasterModule[];
@@ -9,20 +19,33 @@ type _MeshTextureLayerProps = {
9
19
  renderPipeline: RasterModule[];
10
20
  image?: TextureSource;
11
21
  };
12
- export type MeshTextureLayerProps = SimpleMeshLayerProps & _MeshTextureLayerProps;
22
+ export type MeshTextureLayerProps = Omit<SimpleMeshLayerProps, ExcludedSimpleMeshProps> & _MeshTextureLayerProps;
13
23
  declare const defaultProps: DefaultProps<SimpleMeshLayerProps & {
14
24
  image: TextureSource | null;
15
25
  renderPipeline: RasterModule[];
16
26
  }>;
17
27
  /**
18
- * A small subclass of the SimpleMeshLayer to allow dynamic shader injections.
28
+ * A specialized raster-rendering layer, spiritually based on deck.gl's
29
+ * `SimpleMeshLayer` but with a narrower purpose: it draws **one** texture-mapped
30
+ * mesh anchored at the coordinate origin, not instanced 3D models.
19
31
  *
20
- * In the future this may expand to diverge more from the SimpleMeshLayer, such
21
- * as allowing the texture to be a 2D _array_.
32
+ * Differences from `SimpleMeshLayer`:
33
+ * - Allows dynamic shader injection (a render pipeline of `RasterModule`s) and
34
+ * overrides the vertex/fragment shaders.
35
+ * - Provides fp64 mesh-vertex precision via a `positions64Low` attribute paired
36
+ * with the geometry's `positions` (supplied by the caller through
37
+ * `data.attributes.positions64Low`).
38
+ * - The per-instance placement props (`_instanced`, `getPosition`,
39
+ * `getOrientation`, `getScale`, `getTranslation`, `getTransformMatrix`,
40
+ * `sizeScale`) are intentionally unsupported and fixed at identity — see
41
+ * {@link ExcludedSimpleMeshProps}. This is what keeps the fp64 correction
42
+ * valid (the low part is the residual of `positions`, not of a transformed
43
+ * vertex).
22
44
  */
23
45
  export declare class MeshTextureLayer extends SimpleMeshLayer<null, MeshTextureLayerProps> {
24
46
  static layerName: string;
25
47
  static defaultProps: typeof defaultProps;
48
+ initializeState(): void;
26
49
  _resolveRenderPipeline(): RasterModule[];
27
50
  updateState(params: UpdateParameters<this>): void;
28
51
  /** Returns true if the render pipeline has changed between the old and new props. */