@deck.gl/core 9.3.0-alpha.5 → 9.3.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 (64) hide show
  1. package/dist/dist.dev.js +876 -315
  2. package/dist/index.cjs +145 -67
  3. package/dist/index.cjs.map +3 -3
  4. package/dist/lib/attribute/attribute.d.ts +2 -0
  5. package/dist/lib/attribute/attribute.d.ts.map +1 -1
  6. package/dist/lib/attribute/attribute.js +57 -27
  7. package/dist/lib/attribute/attribute.js.map +1 -1
  8. package/dist/lib/constants.d.ts +11 -6
  9. package/dist/lib/constants.d.ts.map +1 -1
  10. package/dist/lib/constants.js +8 -9
  11. package/dist/lib/constants.js.map +1 -1
  12. package/dist/lib/deck.d.ts.map +1 -1
  13. package/dist/lib/deck.js +1 -1
  14. package/dist/lib/deck.js.map +1 -1
  15. package/dist/lib/init.js +2 -2
  16. package/dist/lib/init.js.map +1 -1
  17. package/dist/lib/layer.d.ts.map +1 -1
  18. package/dist/lib/layer.js +4 -6
  19. package/dist/lib/layer.js.map +1 -1
  20. package/dist/passes/layers-pass.d.ts.map +1 -1
  21. package/dist/passes/layers-pass.js +13 -0
  22. package/dist/passes/layers-pass.js.map +1 -1
  23. package/dist/shaderlib/index.d.ts +1 -2
  24. package/dist/shaderlib/index.d.ts.map +1 -1
  25. package/dist/shaderlib/index.js +1 -2
  26. package/dist/shaderlib/index.js.map +1 -1
  27. package/dist/shaderlib/picking/picking.d.ts +4 -4
  28. package/dist/shaderlib/picking/picking.js +4 -4
  29. package/dist/shaderlib/picking/picking.js.map +1 -1
  30. package/dist/shaderlib/project/project-functions.d.ts.map +1 -1
  31. package/dist/shaderlib/project/project-functions.js +19 -10
  32. package/dist/shaderlib/project/project-functions.js.map +1 -1
  33. package/dist/shaderlib/project/project.glsl.d.ts.map +1 -1
  34. package/dist/shaderlib/project/project.glsl.js +10 -5
  35. package/dist/shaderlib/project/project.glsl.js.map +1 -1
  36. package/dist/shaderlib/project/project.wgsl.d.ts.map +1 -1
  37. package/dist/shaderlib/project/project.wgsl.js +10 -5
  38. package/dist/shaderlib/project/project.wgsl.js.map +1 -1
  39. package/dist/shaderlib/project/viewport-uniforms.d.ts +1 -0
  40. package/dist/shaderlib/project/viewport-uniforms.d.ts.map +1 -1
  41. package/dist/shaderlib/project/viewport-uniforms.js +28 -17
  42. package/dist/shaderlib/project/viewport-uniforms.js.map +1 -1
  43. package/dist/shaderlib/shadow/shadow.d.ts +1 -1
  44. package/dist/shaderlib/shadow/shadow.d.ts.map +1 -1
  45. package/dist/shaderlib/shadow/shadow.js +3 -2
  46. package/dist/shaderlib/shadow/shadow.js.map +1 -1
  47. package/dist/utils/texture.d.ts.map +1 -1
  48. package/dist/utils/texture.js +3 -0
  49. package/dist/utils/texture.js.map +1 -1
  50. package/dist.min.js +162 -99
  51. package/package.json +8 -8
  52. package/src/lib/attribute/attribute.ts +70 -27
  53. package/src/lib/constants.ts +18 -12
  54. package/src/lib/deck.ts +1 -1
  55. package/src/lib/layer.ts +4 -6
  56. package/src/passes/layers-pass.ts +21 -1
  57. package/src/shaderlib/index.ts +1 -3
  58. package/src/shaderlib/picking/picking.ts +4 -4
  59. package/src/shaderlib/project/project-functions.ts +20 -10
  60. package/src/shaderlib/project/project.glsl.ts +15 -6
  61. package/src/shaderlib/project/project.wgsl.ts +15 -6
  62. package/src/shaderlib/project/viewport-uniforms.ts +30 -21
  63. package/src/shaderlib/shadow/shadow.ts +6 -2
  64. package/src/utils/texture.ts +2 -0
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "deck.gl core library",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "version": "9.3.0-alpha.5",
6
+ "version": "9.3.0-beta.1",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -40,12 +40,12 @@
40
40
  "prepublishOnly": "npm run build-debugger && npm run build-bundle && npm run build-bundle -- --env=dev"
41
41
  },
42
42
  "dependencies": {
43
- "@loaders.gl/core": "^4.4.0-alpha.18",
44
- "@loaders.gl/images": "^4.4.0-alpha.18",
45
- "@luma.gl/core": "^9.3.0-alpha.10",
46
- "@luma.gl/engine": "^9.3.0-alpha.10",
47
- "@luma.gl/shadertools": "^9.3.0-alpha.10",
48
- "@luma.gl/webgl": "^9.3.0-alpha.10",
43
+ "@loaders.gl/core": "^4.4.1",
44
+ "@loaders.gl/images": "^4.4.1",
45
+ "@luma.gl/core": "^9.3.2",
46
+ "@luma.gl/engine": "^9.3.2",
47
+ "@luma.gl/shadertools": "^9.3.2",
48
+ "@luma.gl/webgl": "^9.3.2",
49
49
  "@math.gl/core": "^4.1.0",
50
50
  "@math.gl/sun": "^4.1.0",
51
51
  "@math.gl/types": "^4.1.0",
@@ -57,5 +57,5 @@
57
57
  "gl-matrix": "^3.0.0",
58
58
  "mjolnir.js": "^3.0.0"
59
59
  },
60
- "gitHead": "c3ad1cee357af674cc31df37979d61325baf9d7a"
60
+ "gitHead": "a8b482631c7b10460411b08c8c674b86176ec191"
61
61
  }
@@ -222,10 +222,16 @@ export default class Attribute extends DataColumn<AttributeOptions, AttributeInt
222
222
  !this.buffer ||
223
223
  this.buffer.byteLength < (this.value as TypedArray).byteLength + this.byteOffset
224
224
  ) {
225
- this.setData({
226
- value: this.value,
227
- constant: this.constant
228
- });
225
+ if (this.constant) {
226
+ // Route constant updater output through the same path used by constant accessors
227
+ // so WebGPU can materialize a real buffer while WebGL keeps a constant attribute.
228
+ this.setConstantValue(context, this.value);
229
+ } else {
230
+ this.setData({
231
+ value: this.value,
232
+ constant: this.constant
233
+ });
234
+ }
229
235
  // Setting attribute.constant in updater is a legacy approach that interferes with allocation in the next cycle
230
236
  // Respect it here but reset after use
231
237
  this.constant = false;
@@ -255,23 +261,20 @@ export default class Attribute extends DataColumn<AttributeOptions, AttributeInt
255
261
  // Use generic value
256
262
  // Returns true if successful
257
263
  setConstantValue(context: any, value?: any): boolean {
258
- // TODO(ibgreen): WebGPU does not support constant values,
259
- // they will be emulated as buffers instead for now.
260
- const isWebGPU = this.device.type === 'webgpu';
261
- if (isWebGPU || value === undefined || typeof value === 'function') {
262
- if (isWebGPU && typeof value !== 'function') {
263
- const normalisedValue = this._normalizeValue(value, [], 0);
264
- // ensure we trigger an update for the attribute's emulated buffer
265
- // where webgl would perform the update here
266
- if (!this._areValuesEqual(normalisedValue, this.value)) {
267
- this.setNeedsUpdate('WebGPU constant updated');
268
- }
269
- }
264
+ if (value === undefined || typeof value === 'function') {
270
265
  return false;
271
266
  }
272
267
 
273
268
  const transformedValue =
274
269
  this.settings.transform && context ? this.settings.transform.call(context, value) : value;
270
+
271
+ if (this.device.type === 'webgpu') {
272
+ // WebGPU has no equivalent of WebGL constant vertex attributes, so we expand the
273
+ // constant into a full per-instance buffer before passing it to luma.gl.
274
+ return this.setConstantBufferValue(transformedValue, this.numInstances);
275
+ }
276
+
277
+ // WebGL can bind the normalized/transformed value directly as a constant attribute.
275
278
  const hasChanged = this.setData({constant: true, value: transformedValue});
276
279
 
277
280
  if (hasChanged) {
@@ -281,6 +284,56 @@ export default class Attribute extends DataColumn<AttributeOptions, AttributeInt
281
284
  return true;
282
285
  }
283
286
 
287
+ setConstantBufferValue(value: any, numInstances: number): boolean {
288
+ const ArrayType = this.settings.defaultType;
289
+ const constantValue = this._normalizeValue(value, new ArrayType(this.size), 0) as TypedArray;
290
+ if (this._hasConstantBufferValue(constantValue, numInstances)) {
291
+ // The emulated buffer already matches this constant, so avoid a redundant upload.
292
+ this.constant = false;
293
+ this.clearNeedsUpdate();
294
+ return false;
295
+ }
296
+
297
+ const repeatedValue = new ArrayType(Math.max(numInstances, 1) * this.size);
298
+
299
+ for (let i = 0; i < repeatedValue.length; i += this.size) {
300
+ repeatedValue.set(constantValue, i);
301
+ }
302
+
303
+ const hasChanged = this.setData({value: repeatedValue});
304
+ this.constant = false;
305
+ this.clearNeedsUpdate();
306
+
307
+ if (hasChanged) {
308
+ this.setNeedsRedraw();
309
+ }
310
+
311
+ return hasChanged;
312
+ }
313
+
314
+ private _hasConstantBufferValue(value: NumericArray, numInstances: number): boolean {
315
+ const currentValue = this.value;
316
+ const expectedLength = Math.max(numInstances, 1) * this.size;
317
+
318
+ if (
319
+ !ArrayBuffer.isView(currentValue) ||
320
+ currentValue.length !== expectedLength ||
321
+ currentValue.length % this.size !== 0
322
+ ) {
323
+ return false;
324
+ }
325
+
326
+ for (let i = 0; i < currentValue.length; i += this.size) {
327
+ for (let j = 0; j < this.size; j++) {
328
+ if (currentValue[i + j] !== value[j]) {
329
+ return false;
330
+ }
331
+ }
332
+ }
333
+
334
+ return true;
335
+ }
336
+
284
337
  // Use external buffer
285
338
  // Returns true if successful
286
339
  // eslint-disable-next-line max-statements
@@ -432,23 +485,13 @@ export default class Attribute extends DataColumn<AttributeOptions, AttributeInt
432
485
  numInstances: number;
433
486
  }
434
487
  ): void {
435
- if (attribute.constant) {
436
- // @ts-ignore TODO(ibgreen) declare context?
437
- if (this.context.device.type !== 'webgpu') {
438
- return;
439
- }
440
- }
441
488
  const {settings, state, value, size, startIndices} = attribute;
442
489
 
443
490
  const {accessor, transform} = settings;
444
- let accessorFunc: Accessor<any, any> =
491
+ const accessorFunc: Accessor<any, any> =
445
492
  state.binaryAccessor ||
446
493
  // @ts-ignore
447
494
  (typeof accessor === 'function' ? accessor : props[accessor]);
448
- // TODO(ibgreen) WebGPU needs buffers, generate an accessor function from a constant
449
- if (typeof accessorFunc !== 'function' && typeof accessor === 'string') {
450
- accessorFunc = () => props[accessor];
451
- }
452
495
  assert(typeof accessorFunc === 'function', `accessor "${accessor}" is not a function`);
453
496
 
454
497
  let i = attribute.getVertexOffset(startRow);
@@ -2,9 +2,6 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- // Note: The numeric values here are matched by shader code in the
6
- // "project" and "project64" shader modules. Both places need to be
7
- // updated.
8
5
  import log from '../utils/log';
9
6
  import {Pan, InputDirection, Pinch, Tap} from 'mjolnir.js';
10
7
  import type {PanRecognizerOptions, PinchRecognizerOptions, TapRecognizerOptions} from 'mjolnir.js';
@@ -12,46 +9,55 @@ import type {PanRecognizerOptions, PinchRecognizerOptions, TapRecognizerOptions}
12
9
  /**
13
10
  * The coordinate system that positions/dimensions are defined in.
14
11
  */
12
+ export type CoordinateSystem =
13
+ | 'default'
14
+ | 'lnglat'
15
+ | 'meter-offsets'
16
+ | 'lnglat-offsets'
17
+ | 'cartesian';
18
+
19
+ /**
20
+ * The coordinate system that positions/dimensions are defined in.
21
+ * String constants are the public API.
22
+ * @deprecated Use string constants directly.
23
+ */
15
24
  export const COORDINATE_SYSTEM = {
16
25
  /**
17
26
  * `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise
18
27
  */
19
- DEFAULT: -1,
28
+ DEFAULT: 'default',
20
29
  /**
21
30
  * Positions are interpreted as [longitude, latitude, elevation]
22
31
  * longitude/latitude are in degrees, elevation is in meters.
23
32
  * Dimensions are in meters.
24
33
  */
25
- LNGLAT: 1,
34
+ LNGLAT: 'lnglat',
26
35
 
27
36
  /**
28
37
  * Positions are interpreted as [x, y, z] in meter offsets from the coordinate origin.
29
38
  * Dimensions are in meters.
30
39
  */
31
- METER_OFFSETS: 2,
40
+ METER_OFFSETS: 'meter-offsets',
32
41
 
33
42
  /**
34
43
  * Positions are interpreted as [deltaLng, deltaLat, elevation] from the coordinate origin.
35
44
  * deltaLng/deltaLat are in degrees, elevation is in meters.
36
45
  * Dimensions are in meters.
37
46
  */
38
- LNGLAT_OFFSETS: 3,
47
+ LNGLAT_OFFSETS: 'lnglat-offsets',
39
48
 
40
49
  /**
41
50
  * Positions and dimensions are in the common units of the viewport.
42
51
  */
43
- CARTESIAN: 0
52
+ CARTESIAN: 'cartesian'
44
53
  } as const;
45
54
 
46
- // Enums cannot be directly exported as they are not transpiled correctly into ES5, see https://github.com/visgl/deck.gl/issues/7130
47
- export type CoordinateSystem = -1 | 0 | 1 | 2 | 3;
48
-
49
55
  // Deprecated
50
56
  /* eslint-disable accessor-pairs */
51
57
  Object.defineProperty(COORDINATE_SYSTEM, 'IDENTITY', {
52
58
  get: () => {
53
59
  log.deprecated('COORDINATE_SYSTEM.IDENTITY', 'COORDINATE_SYSTEM.CARTESIAN')();
54
- return 0;
60
+ return COORDINATE_SYSTEM.CARTESIAN;
55
61
  }
56
62
  });
57
63
  /* eslint-enable accessor-pairs */
package/src/lib/deck.ts CHANGED
@@ -18,9 +18,9 @@ import {VERSION} from './init';
18
18
 
19
19
  import {luma} from '@luma.gl/core';
20
20
  import {webgl2Adapter} from '@luma.gl/webgl';
21
+ import {GL} from '@luma.gl/webgl/constants';
21
22
  import {Timeline} from '@luma.gl/engine';
22
23
  import {AnimationLoop} from '@luma.gl/engine';
23
- import {GL} from '@luma.gl/webgl/constants';
24
24
  import type {CanvasContextProps, Device, DeviceProps, Framebuffer, Parameters} from '@luma.gl/core';
25
25
  import type {ShaderModule} from '@luma.gl/shadertools';
26
26
 
package/src/lib/layer.ts CHANGED
@@ -5,7 +5,6 @@
5
5
  /* eslint-disable react/no-direct-mutation-state */
6
6
  import {Buffer, Parameters as LumaParameters, TypedArray} from '@luma.gl/core';
7
7
  import {WebGLDevice} from '@luma.gl/webgl';
8
- import {COORDINATE_SYSTEM} from './constants';
9
8
  import AttributeManager from './attribute/attribute-manager';
10
9
  import UniformTransitionManager from './uniform-transition-manager';
11
10
  import {diffProps, validateProps} from '../lifecycle/props';
@@ -138,7 +137,7 @@ const defaultProps: DefaultProps<LayerProps> = {
138
137
  onDrag: {type: 'function', value: null, optional: true},
139
138
  onDragEnd: {type: 'function', value: null, optional: true},
140
139
 
141
- coordinateSystem: COORDINATE_SYSTEM.DEFAULT,
140
+ coordinateSystem: 'default',
142
141
  coordinateOrigin: {type: 'array', value: [0, 0, 0], compare: true},
143
142
  modelMatrix: {type: 'array', value: null, compare: true, optional: true},
144
143
  wrapLongitude: false,
@@ -358,9 +357,9 @@ export default abstract class Layer<PropsT extends {} = {}> extends Component<
358
357
  use64bitPositions(): boolean {
359
358
  const {coordinateSystem} = this.props;
360
359
  return (
361
- coordinateSystem === COORDINATE_SYSTEM.DEFAULT ||
362
- coordinateSystem === COORDINATE_SYSTEM.LNGLAT ||
363
- coordinateSystem === COORDINATE_SYSTEM.CARTESIAN
360
+ coordinateSystem === 'default' ||
361
+ coordinateSystem === 'lnglat' ||
362
+ coordinateSystem === 'cartesian'
364
363
  );
365
364
  }
366
365
 
@@ -869,7 +868,6 @@ export default abstract class Layer<PropsT extends {} = {}> extends Component<
869
868
  /* (Internal) Called by layer manager when a new layer is found */
870
869
  _initialize() {
871
870
  assert(!this.internalState); // finalized layer cannot be reused
872
- assert(Number.isFinite(this.props.coordinateSystem)); // invalid coordinateSystem
873
871
 
874
872
  debug(TRACE_INITIALIZE, this);
875
873
 
@@ -2,7 +2,12 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {Device, Parameters, RenderPassParameters} from '@luma.gl/core';
5
+ import type {
6
+ Device,
7
+ Parameters,
8
+ RenderPassParameters,
9
+ RenderPipelineParameters
10
+ } from '@luma.gl/core';
6
11
  import type {Framebuffer, RenderPass} from '@luma.gl/core';
7
12
  import type {NumberArray4} from '@math.gl/core';
8
13
 
@@ -16,6 +21,18 @@ import type {PickingProps} from '@luma.gl/shadertools';
16
21
 
17
22
  export type Rect = {x: number; y: number; width: number; height: number};
18
23
 
24
+ // WebGPU complication: Matching attachment state of the renderpass requires including a depth buffer
25
+ const WEBGPU_DEFAULT_DRAW_PARAMETERS: RenderPipelineParameters = {
26
+ depthWriteEnabled: true,
27
+ depthCompare: 'less-equal',
28
+ blendColorOperation: 'add',
29
+ blendColorSrcFactor: 'src-alpha',
30
+ blendColorDstFactor: 'one',
31
+ blendAlphaOperation: 'add',
32
+ blendAlphaSrcFactor: 'one-minus-dst-alpha',
33
+ blendAlphaDstFactor: 'one'
34
+ };
35
+
19
36
  export type LayersPassRenderOptions = {
20
37
  /** @deprecated TODO v9 recommend we rename this to framebuffer to minimize confusion */
21
38
  target?: Framebuffer | null;
@@ -206,7 +223,10 @@ export default class LayersPass extends Pass {
206
223
  pass,
207
224
  shaderModuleProps
208
225
  );
226
+ const defaultParams =
227
+ layer.context.device.type === 'webgpu' ? WEBGPU_DEFAULT_DRAW_PARAMETERS : null;
209
228
  layerParam.layerParameters = {
229
+ ...defaultParams,
210
230
  ...layer.context.deck?.props.parameters,
211
231
  ...this.getLayerParameters(layer, layerIndex, viewport)
212
232
  };
@@ -2,9 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {ShaderAssembler} from '@luma.gl/shadertools';
6
-
7
- import {gouraudMaterial, phongMaterial} from '@luma.gl/shadertools';
5
+ import {ShaderAssembler, gouraudMaterial, phongMaterial} from '@luma.gl/shadertools';
8
6
  import {layerUniforms} from './misc/layer-uniforms';
9
7
  import color from './color/color';
10
8
  import geometry from './misc/geometry';
@@ -9,7 +9,7 @@ struct pickingUniforms {
9
9
  isActive: f32,
10
10
  isAttribute: f32,
11
11
  isHighlightActive: f32,
12
- useFloatColors: f32,
12
+ useByteColors: f32,
13
13
  highlightedObjectColor: vec3<f32>,
14
14
  highlightColor: vec4<f32>,
15
15
  };
@@ -17,11 +17,11 @@ struct pickingUniforms {
17
17
  @group(0) @binding(auto) var<uniform> picking: pickingUniforms;
18
18
 
19
19
  fn picking_normalizeColor(color: vec3<f32>) -> vec3<f32> {
20
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
20
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
21
21
  }
22
22
 
23
23
  fn picking_normalizeColor4(color: vec4<f32>) -> vec4<f32> {
24
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
24
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
25
25
  }
26
26
 
27
27
  fn picking_isColorZero(color: vec3<f32>) -> bool {
@@ -36,7 +36,7 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
36
36
  export default {
37
37
  ...picking,
38
38
  source: sourceWGSL,
39
- defaultUniforms: {...picking.defaultUniforms, useFloatColors: false},
39
+ defaultUniforms: {...picking.defaultUniforms, useByteColors: true},
40
40
  inject: {
41
41
  'vs:DECKGL_FILTER_GL_POSITION': `
42
42
  // for picking depth values
@@ -6,7 +6,6 @@
6
6
  * Projection utils
7
7
  * TODO: move to Viewport class?
8
8
  */
9
- import {COORDINATE_SYSTEM} from '../../lib/constants';
10
9
  import {getOffsetOrigin} from './viewport-uniforms';
11
10
  import WebMercatorViewport from '../../viewports/web-mercator-viewport';
12
11
 
@@ -56,14 +55,14 @@ function normalizeParameters(opts: {
56
55
  const {viewport, modelMatrix, coordinateOrigin} = opts;
57
56
  let {coordinateSystem, fromCoordinateSystem, fromCoordinateOrigin} = opts;
58
57
 
59
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
60
- coordinateSystem = viewport.isGeospatial
61
- ? COORDINATE_SYSTEM.LNGLAT
62
- : COORDINATE_SYSTEM.CARTESIAN;
58
+ if (coordinateSystem === 'default') {
59
+ coordinateSystem = viewport.isGeospatial ? 'lnglat' : 'cartesian';
63
60
  }
64
61
 
65
62
  if (fromCoordinateSystem === undefined) {
66
63
  fromCoordinateSystem = coordinateSystem;
64
+ } else if (fromCoordinateSystem === 'default') {
65
+ fromCoordinateSystem = viewport.isGeospatial ? 'lnglat' : 'cartesian';
67
66
  }
68
67
  if (fromCoordinateOrigin === undefined) {
69
68
  fromCoordinateOrigin = coordinateOrigin;
@@ -103,28 +102,39 @@ export function getWorldPosition(
103
102
  }
104
103
 
105
104
  switch (coordinateSystem) {
106
- case COORDINATE_SYSTEM.LNGLAT:
105
+ case 'default':
106
+ return getWorldPosition(position, {
107
+ viewport,
108
+ modelMatrix,
109
+ coordinateSystem: viewport.isGeospatial ? 'lnglat' : 'cartesian',
110
+ coordinateOrigin,
111
+ offsetMode
112
+ });
113
+
114
+ case 'lnglat':
107
115
  return lngLatZToWorldPosition([x, y, z], viewport, offsetMode);
108
116
 
109
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
117
+ case 'lnglat-offsets':
110
118
  return lngLatZToWorldPosition(
111
119
  [x + coordinateOrigin[0], y + coordinateOrigin[1], z + (coordinateOrigin[2] || 0)],
112
120
  viewport,
113
121
  offsetMode
114
122
  );
115
123
 
116
- case COORDINATE_SYSTEM.METER_OFFSETS:
124
+ case 'meter-offsets':
117
125
  return lngLatZToWorldPosition(
118
126
  addMetersToLngLat(coordinateOrigin, [x, y, z]) as [number, number, number],
119
127
  viewport,
120
128
  offsetMode
121
129
  );
122
130
 
123
- case COORDINATE_SYSTEM.CARTESIAN:
124
- default:
131
+ case 'cartesian':
125
132
  return viewport.isGeospatial
126
133
  ? [x + coordinateOrigin[0], y + coordinateOrigin[1], z + coordinateOrigin[2]]
127
134
  : viewport.projectPosition([x, y, z]);
135
+
136
+ default:
137
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
128
138
  }
129
139
  }
130
140
 
@@ -2,12 +2,21 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {COORDINATE_SYSTEM, PROJECTION_MODE, UNIT} from '../../lib/constants';
6
-
7
- // We are generating these from the js code in constants.js
8
- const COORDINATE_SYSTEM_GLSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM)
9
- .map(key => `const int COORDINATE_SYSTEM_${key} = ${COORDINATE_SYSTEM[key]};`)
10
- .join('');
5
+ import {PROJECTION_MODE, UNIT} from '../../lib/constants';
6
+ import {getShaderCoordinateSystem} from './viewport-uniforms';
7
+
8
+ const SHADER_COORDINATE_SYSTEMS = [
9
+ 'default',
10
+ 'lnglat',
11
+ 'meter-offsets',
12
+ 'lnglat-offsets',
13
+ 'cartesian'
14
+ ] as const;
15
+
16
+ const COORDINATE_SYSTEM_GLSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS.map(
17
+ coordinateSystem =>
18
+ `const int COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll('-', '_')} = ${getShaderCoordinateSystem(coordinateSystem)};`
19
+ ).join('');
11
20
  const PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE)
12
21
  .map(key => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`)
13
22
  .join('');
@@ -2,12 +2,21 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {COORDINATE_SYSTEM, PROJECTION_MODE, UNIT} from '../../lib/constants';
6
-
7
- // We are generating these from the js code in constants.js
8
- const COORDINATE_SYSTEM_WGSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM)
9
- .map(key => `const COORDINATE_SYSTEM_${key}: i32 = ${COORDINATE_SYSTEM[key]};`)
10
- .join('');
5
+ import {PROJECTION_MODE, UNIT} from '../../lib/constants';
6
+ import {getShaderCoordinateSystem} from './viewport-uniforms';
7
+
8
+ const SHADER_COORDINATE_SYSTEMS = [
9
+ 'default',
10
+ 'lnglat',
11
+ 'meter-offsets',
12
+ 'lnglat-offsets',
13
+ 'cartesian'
14
+ ] as const;
15
+
16
+ const COORDINATE_SYSTEM_WGSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS.map(
17
+ coordinateSystem =>
18
+ `const COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll('-', '_')}: i32 = ${getShaderCoordinateSystem(coordinateSystem)};`
19
+ ).join('');
11
20
  const PROJECTION_MODE_WGSL_CONSTANTS = Object.keys(PROJECTION_MODE)
12
21
  .map(key => `const PROJECTION_MODE_${key}: i32 = ${PROJECTION_MODE[key]};`)
13
22
  .join('');
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {mat4, Matrix4Like, vec4} from '@math.gl/core';
8
8
 
9
- import {COORDINATE_SYSTEM, PROJECTION_MODE} from '../../lib/constants';
9
+ import {PROJECTION_MODE} from '../../lib/constants';
10
10
 
11
11
  import memoize from '../../utils/memoize';
12
12
 
@@ -24,6 +24,23 @@ const IDENTITY_MATRIX: Matrix4Like = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
24
24
  const DEFAULT_PIXELS_PER_UNIT2: Vec3 = [0, 0, 0];
25
25
  const DEFAULT_COORDINATE_ORIGIN: Vec3 = [0, 0, 0];
26
26
 
27
+ /** Coordinate system constants */
28
+ const COORDINATE_SYSTEM_NUMBERS = {
29
+ default: -1,
30
+ cartesian: 0,
31
+ lnglat: 1,
32
+ 'meter-offsets': 2,
33
+ 'lnglat-offsets': 3
34
+ } as const satisfies Record<CoordinateSystem, -1 | 0 | 1 | 2 | 3>;
35
+
36
+ export function getShaderCoordinateSystem(coordinateSystem: CoordinateSystem) {
37
+ const shaderCoordinateSystem = COORDINATE_SYSTEM_NUMBERS[coordinateSystem];
38
+ if (shaderCoordinateSystem === undefined) {
39
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
40
+ }
41
+ return shaderCoordinateSystem;
42
+ }
43
+
27
44
  const getMemoizedViewportUniforms = memoize(calculateViewportUniforms);
28
45
 
29
46
  export function getOffsetOrigin(
@@ -43,10 +60,7 @@ export function getOffsetOrigin(
43
60
  let geospatialOrigin: Vec3 | null;
44
61
  let offsetMode = true;
45
62
 
46
- if (
47
- coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS ||
48
- coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS
49
- ) {
63
+ if (coordinateSystem === 'lnglat-offsets' || coordinateSystem === 'meter-offsets') {
50
64
  geospatialOrigin = coordinateOrigin;
51
65
  } else {
52
66
  geospatialOrigin = viewport.isGeospatial
@@ -57,21 +71,18 @@ export function getOffsetOrigin(
57
71
 
58
72
  switch (viewport.projectionMode) {
59
73
  case PROJECTION_MODE.WEB_MERCATOR:
60
- if (
61
- coordinateSystem === COORDINATE_SYSTEM.LNGLAT ||
62
- coordinateSystem === COORDINATE_SYSTEM.CARTESIAN
63
- ) {
74
+ if (coordinateSystem === 'lnglat' || coordinateSystem === 'cartesian') {
64
75
  geospatialOrigin = [0, 0, 0];
65
76
  offsetMode = false;
66
77
  }
67
78
  break;
68
79
 
69
80
  case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
70
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
81
+ if (coordinateSystem === 'lnglat') {
71
82
  // viewport center in world space
72
83
  // @ts-expect-error when using LNGLAT coordinates, we expect the viewport to be geospatial, in which case geospatialOrigin is defined
73
84
  shaderCoordinateOrigin = geospatialOrigin;
74
- } else if (coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
85
+ } else if (coordinateSystem === 'cartesian') {
75
86
  // viewport center in common space
76
87
  shaderCoordinateOrigin = [
77
88
  Math.fround(viewport.center[0]),
@@ -223,14 +234,12 @@ export function getUniformsFromViewport({
223
234
  devicePixelRatio = 1,
224
235
  modelMatrix = null,
225
236
  // Match Layer.defaultProps
226
- coordinateSystem = COORDINATE_SYSTEM.DEFAULT,
237
+ coordinateSystem = 'default',
227
238
  coordinateOrigin = DEFAULT_COORDINATE_ORIGIN,
228
239
  autoWrapLongitude = false
229
240
  }: ProjectProps): ProjectUniforms {
230
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
231
- coordinateSystem = viewport.isGeospatial
232
- ? COORDINATE_SYSTEM.LNGLAT
233
- : COORDINATE_SYSTEM.CARTESIAN;
241
+ if (coordinateSystem === 'default') {
242
+ coordinateSystem = viewport.isGeospatial ? 'lnglat' : 'cartesian';
234
243
  }
235
244
 
236
245
  const uniforms = getMemoizedViewportUniforms({
@@ -283,7 +292,7 @@ function calculateViewportUniforms({
283
292
 
284
293
  const uniforms: ProjectUniforms = {
285
294
  // Projection mode values
286
- coordinateSystem,
295
+ coordinateSystem: getShaderCoordinateSystem(coordinateSystem),
287
296
  projectionMode: viewport.projectionMode,
288
297
  coordinateOrigin: shaderCoordinateOrigin,
289
298
  commonOrigin: originCommon.slice(0, 3) as Vec3,
@@ -324,13 +333,13 @@ function calculateViewportUniforms({
324
333
  unitsPerDegree2: Vec3;
325
334
  };
326
335
  switch (coordinateSystem) {
327
- case COORDINATE_SYSTEM.METER_OFFSETS:
336
+ case 'meter-offsets':
328
337
  uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
329
338
  uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
330
339
  break;
331
340
 
332
- case COORDINATE_SYSTEM.LNGLAT:
333
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
341
+ case 'lnglat':
342
+ case 'lnglat-offsets':
334
343
  // @ts-expect-error _pseudoMeters only exists on WebMercatorView
335
344
  if (!viewport._pseudoMeters) {
336
345
  uniforms.commonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
@@ -340,7 +349,7 @@ function calculateViewportUniforms({
340
349
  break;
341
350
 
342
351
  // a.k.a "preprojected" positions
343
- case COORDINATE_SYSTEM.CARTESIAN:
352
+ case 'cartesian':
344
353
  uniforms.commonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
345
354
  uniforms.commonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
346
355
  break;
@@ -12,7 +12,11 @@ import {pixelsToWorld} from '@math.gl/web-mercator';
12
12
  import type {Texture} from '@luma.gl/core';
13
13
  import {ShaderModule} from '@luma.gl/shadertools';
14
14
  import type Viewport from '../../viewports/viewport';
15
- import type {ProjectProps, ProjectUniforms} from '../project/viewport-uniforms';
15
+ import {
16
+ ProjectProps,
17
+ ProjectUniforms,
18
+ getShaderCoordinateSystem
19
+ } from '../project/viewport-uniforms';
16
20
 
17
21
  const uniformBlock = /* glsl */ `
18
22
  layout(std140) uniform shadowUniforms {
@@ -236,7 +240,7 @@ function createShadowUniforms(
236
240
  .translate(new Vector3(projectProps.viewport.center).negate());
237
241
 
238
242
  if (
239
- projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT &&
243
+ projectUniforms.coordinateSystem === getShaderCoordinateSystem('lnglat') &&
240
244
  projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR
241
245
  ) {
242
246
  viewProjectionMatrices[i] = viewProjectionMatrixCentered;
@@ -59,6 +59,8 @@ export function createTexture(
59
59
  });
60
60
  if (device.type === 'webgl') {
61
61
  texture.generateMipmapsWebGL();
62
+ } else if (device.type === 'webgpu') {
63
+ device.generateMipmapsWebGPU(texture);
62
64
  }
63
65
 
64
66
  // Track this texture