@luma.gl/engine 9.1.9 → 9.2.0-alpha.2

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 (102) hide show
  1. package/README.md +5 -0
  2. package/dist/animation-loop/animation-loop.d.ts +12 -12
  3. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  4. package/dist/animation-loop/animation-loop.js +26 -62
  5. package/dist/animation-loop/animation-loop.js.map +1 -1
  6. package/dist/animation-loop/animation-props.d.ts +3 -4
  7. package/dist/animation-loop/animation-props.d.ts.map +1 -1
  8. package/dist/animation-loop/make-animation-loop.d.ts +4 -1
  9. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
  10. package/dist/animation-loop/make-animation-loop.js +39 -7
  11. package/dist/animation-loop/make-animation-loop.js.map +1 -1
  12. package/dist/async-texture/async-texture.d.ts +106 -2
  13. package/dist/async-texture/async-texture.d.ts.map +1 -1
  14. package/dist/async-texture/async-texture.js +281 -13
  15. package/dist/async-texture/async-texture.js.map +1 -1
  16. package/dist/compute/computation.d.ts +1 -1
  17. package/dist/compute/computation.d.ts.map +1 -1
  18. package/dist/compute/computation.js +2 -2
  19. package/dist/compute/computation.js.map +1 -1
  20. package/dist/compute/swap.d.ts.map +1 -1
  21. package/dist/compute/swap.js +6 -2
  22. package/dist/compute/swap.js.map +1 -1
  23. package/dist/compute/texture-transform.d.ts.map +1 -1
  24. package/dist/compute/texture-transform.js +4 -2
  25. package/dist/compute/texture-transform.js.map +1 -1
  26. package/dist/debug/copy-texture-to-image.d.ts +23 -1
  27. package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
  28. package/dist/debug/copy-texture-to-image.js +37 -1
  29. package/dist/debug/copy-texture-to-image.js.map +1 -1
  30. package/dist/dist.dev.js +566 -232
  31. package/dist/dist.min.js +26 -26
  32. package/dist/factories/pipeline-factory.d.ts +11 -1
  33. package/dist/factories/pipeline-factory.d.ts.map +1 -1
  34. package/dist/factories/pipeline-factory.js +107 -25
  35. package/dist/factories/pipeline-factory.js.map +1 -1
  36. package/dist/factories/shader-factory.d.ts +5 -1
  37. package/dist/factories/shader-factory.d.ts.map +1 -1
  38. package/dist/factories/shader-factory.js +40 -6
  39. package/dist/factories/shader-factory.js.map +1 -1
  40. package/dist/geometries/cube-geometry.d.ts +3 -3
  41. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  42. package/dist/geometry/geometry.d.ts.map +1 -1
  43. package/dist/geometry/geometry.js +3 -2
  44. package/dist/geometry/geometry.js.map +1 -1
  45. package/dist/index.cjs +581 -251
  46. package/dist/index.cjs.map +4 -4
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/model/model.d.ts +4 -25
  51. package/dist/model/model.d.ts.map +1 -1
  52. package/dist/model/model.js +26 -71
  53. package/dist/model/model.js.map +1 -1
  54. package/dist/models/billboard-texture-model.d.ts.map +1 -1
  55. package/dist/models/billboard-texture-model.js +6 -4
  56. package/dist/models/billboard-texture-model.js.map +1 -1
  57. package/dist/modules/picking/legacy-picking-manager.d.ts +1 -1
  58. package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -1
  59. package/dist/modules/picking/legacy-picking-manager.js +1 -1
  60. package/dist/modules/picking/legacy-picking-manager.js.map +1 -1
  61. package/dist/modules/picking/picking-manager.d.ts +2 -2
  62. package/dist/modules/picking/picking-manager.d.ts.map +1 -1
  63. package/dist/modules/picking/picking-manager.js +2 -2
  64. package/dist/modules/picking/picking-manager.js.map +1 -1
  65. package/dist/passes/get-fragment-shader.js +2 -2
  66. package/dist/passes/shader-pass-renderer.d.ts +4 -4
  67. package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
  68. package/dist/passes/shader-pass-renderer.js +15 -5
  69. package/dist/passes/shader-pass-renderer.js.map +1 -1
  70. package/dist/shader-inputs.js +1 -1
  71. package/dist/shader-inputs.js.map +1 -1
  72. package/dist/utils/buffer-layout-helper.d.ts +12 -0
  73. package/dist/utils/buffer-layout-helper.d.ts.map +1 -0
  74. package/dist/utils/buffer-layout-helper.js +41 -0
  75. package/dist/utils/buffer-layout-helper.js.map +1 -0
  76. package/dist/utils/buffer-layout-order.d.ts +3 -0
  77. package/dist/utils/buffer-layout-order.d.ts.map +1 -0
  78. package/dist/utils/buffer-layout-order.js +16 -0
  79. package/dist/utils/buffer-layout-order.js.map +1 -0
  80. package/package.json +4 -4
  81. package/src/animation-loop/animation-loop.ts +31 -71
  82. package/src/animation-loop/animation-props.ts +3 -5
  83. package/src/animation-loop/make-animation-loop.ts +41 -9
  84. package/src/async-texture/async-texture.ts +386 -23
  85. package/src/async-texture/texture-setters.ts.disabled +296 -0
  86. package/src/compute/computation.ts +3 -3
  87. package/src/compute/swap.ts +7 -2
  88. package/src/compute/texture-transform.ts +4 -2
  89. package/src/debug/copy-texture-to-image.ts +52 -2
  90. package/src/factories/pipeline-factory.ts +122 -26
  91. package/src/factories/shader-factory.ts +43 -7
  92. package/src/geometry/geometry.ts +3 -2
  93. package/src/index.ts +12 -0
  94. package/src/model/model.ts +31 -86
  95. package/src/models/billboard-texture-model.ts +6 -4
  96. package/src/modules/picking/legacy-picking-manager.ts +2 -2
  97. package/src/modules/picking/picking-manager.ts +3 -3
  98. package/src/passes/get-fragment-shader.ts +2 -2
  99. package/src/passes/shader-pass-renderer.ts +18 -8
  100. package/src/shader-inputs.ts +1 -1
  101. package/src/utils/buffer-layout-helper.ts +51 -0
  102. package/src/utils/buffer-layout-order.ts +26 -0
package/dist/index.cjs CHANGED
@@ -254,25 +254,7 @@ function cancelAnimationFramePolyfill(timerId) {
254
254
  // dist/animation-loop/animation-loop.js
255
255
  var import_stats = require("@probe.gl/stats");
256
256
  var statIdCounter = 0;
257
- var DEFAULT_ANIMATION_LOOP_PROPS = {
258
- device: null,
259
- onAddHTML: () => "",
260
- onInitialize: async () => {
261
- return null;
262
- },
263
- onRender: () => {
264
- },
265
- onFinalize: () => {
266
- },
267
- onError: (error) => console.error(error),
268
- // eslint-disable-line no-console
269
- stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
270
- // view parameters
271
- useDevicePixels: true,
272
- autoResizeViewport: false,
273
- autoResizeDrawingBuffer: false
274
- };
275
- var AnimationLoop = class {
257
+ var _AnimationLoop = class {
276
258
  device = null;
277
259
  canvas = null;
278
260
  props;
@@ -296,21 +278,16 @@ var AnimationLoop = class {
296
278
  * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
297
279
  */
298
280
  constructor(props) {
299
- this.props = { ...DEFAULT_ANIMATION_LOOP_PROPS, ...props };
281
+ this.props = { ..._AnimationLoop.defaultAnimationLoopProps, ...props };
300
282
  props = this.props;
301
283
  if (!props.device) {
302
284
  throw new Error("No device provided");
303
285
  }
304
- const { useDevicePixels = true } = this.props;
305
286
  this.stats = props.stats || new import_stats.Stats({ id: "animation-loop-stats" });
306
287
  this.cpuTime = this.stats.get("CPU Time");
307
288
  this.gpuTime = this.stats.get("GPU Time");
308
289
  this.frameRate = this.stats.get("Frame Rate");
309
- this.setProps({
310
- autoResizeViewport: props.autoResizeViewport,
311
- autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
312
- useDevicePixels
313
- });
290
+ this.setProps({ autoResizeViewport: props.autoResizeViewport });
314
291
  this.start = this.start.bind(this);
315
292
  this.stop = this.stop.bind(this);
316
293
  this._onMousemove = this._onMousemove.bind(this);
@@ -324,38 +301,19 @@ var AnimationLoop = class {
324
301
  delete() {
325
302
  this.destroy();
326
303
  }
327
- setError(error) {
328
- var _a, _b;
304
+ reportError(error) {
329
305
  this.props.onError(error);
330
- this._error = Error();
331
- const canvas2 = (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.canvas;
332
- if (canvas2 instanceof HTMLCanvasElement) {
333
- const errorDiv = document.createElement("h1");
334
- errorDiv.innerHTML = error.message;
335
- errorDiv.style.position = "absolute";
336
- errorDiv.style.top = "20%";
337
- errorDiv.style.left = "10px";
338
- errorDiv.style.color = "black";
339
- errorDiv.style.backgroundColor = "red";
340
- document.body.appendChild(errorDiv);
341
- }
306
+ this._error = error;
342
307
  }
343
308
  /** Flags this animation loop as needing redraw */
344
309
  setNeedsRedraw(reason) {
345
310
  this.needsRedraw = this.needsRedraw || reason;
346
311
  return this;
347
312
  }
348
- /** TODO - move these props to CanvasContext? */
349
313
  setProps(props) {
350
314
  if ("autoResizeViewport" in props) {
351
315
  this.props.autoResizeViewport = props.autoResizeViewport || false;
352
316
  }
353
- if ("autoResizeDrawingBuffer" in props) {
354
- this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
355
- }
356
- if ("useDevicePixels" in props) {
357
- this.props.useDevicePixels = props.useDevicePixels || false;
358
- }
359
317
  return this;
360
318
  }
361
319
  /** Starts a render loop if not already running */
@@ -451,7 +409,6 @@ var AnimationLoop = class {
451
409
  this._startEventHandling();
452
410
  this._initializeAnimationProps();
453
411
  this._updateAnimationProps();
454
- this._resizeCanvasDrawingBuffer();
455
412
  this._resizeViewport();
456
413
  }
457
414
  _setDisplay(display) {
@@ -499,23 +456,25 @@ var AnimationLoop = class {
499
456
  this.needsRedraw = false;
500
457
  }
501
458
  _setupFrame() {
502
- this._resizeCanvasDrawingBuffer();
503
459
  this._resizeViewport();
504
460
  }
505
461
  // Initialize the object that will be passed to app callbacks
506
462
  _initializeAnimationProps() {
507
- var _a, _b;
508
- const canvas2 = (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.canvas;
509
- if (!this.device || !canvas2) {
463
+ var _a;
464
+ const canvasContext = (_a = this.device) == null ? void 0 : _a.getDefaultCanvasContext();
465
+ if (!this.device || !canvasContext) {
510
466
  throw new Error("loop");
511
467
  }
468
+ const canvas2 = canvasContext == null ? void 0 : canvasContext.canvas;
469
+ const useDevicePixels = canvasContext.props.useDevicePixels;
512
470
  this.animationProps = {
513
471
  animationLoop: this,
514
472
  device: this.device,
473
+ canvasContext,
515
474
  canvas: canvas2,
475
+ // @ts-expect-error Deprecated
476
+ useDevicePixels,
516
477
  timeline: this.timeline,
517
- // Initial values
518
- useDevicePixels: this.props.useDevicePixels,
519
478
  needsRedraw: false,
520
479
  // Placeholders
521
480
  width: 1,
@@ -564,12 +523,11 @@ var AnimationLoop = class {
564
523
  }
565
524
  /** Wait for supplied device */
566
525
  async _initDevice() {
567
- var _a;
568
526
  this.device = await this.props.device;
569
527
  if (!this.device) {
570
528
  throw new Error("No device provided");
571
529
  }
572
- this.canvas = ((_a = this.device.canvasContext) == null ? void 0 : _a.canvas) || null;
530
+ this.canvas = this.device.getDefaultCanvasContext().canvas || null;
573
531
  }
574
532
  _createInfoDiv() {
575
533
  if (this.canvas && this.props.onAddHTML) {
@@ -593,13 +551,13 @@ var AnimationLoop = class {
593
551
  }
594
552
  }
595
553
  _getSizeAndAspect() {
596
- var _a, _b, _c, _d;
554
+ var _a, _b;
597
555
  if (!this.device) {
598
556
  return { width: 1, height: 1, aspect: 1 };
599
557
  }
600
- const [width, height] = ((_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.getPixelSize()) || [1, 1];
558
+ const [width, height] = ((_a = this.device) == null ? void 0 : _a.getDefaultCanvasContext().getDevicePixelSize()) || [1, 1];
601
559
  let aspect = 1;
602
- const canvas2 = (_d = (_c = this.device) == null ? void 0 : _c.canvasContext) == null ? void 0 : _d.canvas;
560
+ const canvas2 = (_b = this.device) == null ? void 0 : _b.getDefaultCanvasContext().canvas;
603
561
  if (canvas2 && canvas2.clientHeight) {
604
562
  aspect = canvas2.clientWidth / canvas2.clientHeight;
605
563
  } else if (width > 0 && height > 0) {
@@ -607,7 +565,7 @@ var AnimationLoop = class {
607
565
  }
608
566
  return { width, height, aspect };
609
567
  }
610
- /** Default viewport setup */
568
+ /** @deprecated Default viewport setup */
611
569
  _resizeViewport() {
612
570
  if (this.props.autoResizeViewport && this.device.gl) {
613
571
  this.device.gl.viewport(
@@ -620,16 +578,6 @@ var AnimationLoop = class {
620
578
  );
621
579
  }
622
580
  }
623
- /**
624
- * Resize the render buffer of the canvas to match canvas client size
625
- * Optionally multiplying with devicePixel ratio
626
- */
627
- _resizeCanvasDrawingBuffer() {
628
- var _a, _b;
629
- if (this.props.autoResizeDrawingBuffer) {
630
- (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.resize({ useDevicePixels: this.props.useDevicePixels });
631
- }
632
- }
633
581
  _beginFrameTimers() {
634
582
  this.frameRate.timeEnd();
635
583
  this.frameRate.timeStart();
@@ -654,6 +602,21 @@ var AnimationLoop = class {
654
602
  this._getAnimationProps()._mousePosition = null;
655
603
  }
656
604
  };
605
+ var AnimationLoop = _AnimationLoop;
606
+ __publicField(AnimationLoop, "defaultAnimationLoopProps", {
607
+ device: null,
608
+ onAddHTML: () => "",
609
+ onInitialize: async () => null,
610
+ onRender: () => {
611
+ },
612
+ onFinalize: () => {
613
+ },
614
+ onError: (error) => console.error(error),
615
+ // eslint-disable-line no-console
616
+ stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
617
+ // view parameters
618
+ autoResizeViewport: false
619
+ });
657
620
 
658
621
  // dist/animation-loop/make-animation-loop.js
659
622
  var import_core2 = require("@luma.gl/core");
@@ -664,8 +627,14 @@ function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
664
627
  ...props,
665
628
  device,
666
629
  async onInitialize(animationProps) {
667
- renderLoop = new AnimationLoopTemplateCtor(animationProps);
668
- return await (renderLoop == null ? void 0 : renderLoop.onInitialize(animationProps));
630
+ clearError(animationProps.animationLoop.device);
631
+ try {
632
+ renderLoop = new AnimationLoopTemplateCtor(animationProps);
633
+ return await (renderLoop == null ? void 0 : renderLoop.onInitialize(animationProps));
634
+ } catch (error) {
635
+ setError(animationProps.animationLoop.device, error);
636
+ return null;
637
+ }
669
638
  },
670
639
  onRender: (animationProps) => renderLoop == null ? void 0 : renderLoop.onRender(animationProps),
671
640
  onFinalize: (animationProps) => renderLoop == null ? void 0 : renderLoop.onFinalize(animationProps)
@@ -675,9 +644,33 @@ function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
675
644
  };
676
645
  return animationLoop;
677
646
  }
647
+ function setError(device, error) {
648
+ var _a;
649
+ const canvas2 = device == null ? void 0 : device.getDefaultCanvasContext().canvas;
650
+ if (canvas2 instanceof HTMLCanvasElement) {
651
+ canvas2.style.overflow = "visible";
652
+ let errorDiv = document.getElementById("animation-loop-error");
653
+ errorDiv == null ? void 0 : errorDiv.remove();
654
+ errorDiv = document.createElement("h1");
655
+ errorDiv.id = "animation-loop-error";
656
+ errorDiv.innerHTML = error.message;
657
+ errorDiv.style.position = "absolute";
658
+ errorDiv.style.top = "10px";
659
+ errorDiv.style.left = "10px";
660
+ errorDiv.style.color = "black";
661
+ errorDiv.style.backgroundColor = "red";
662
+ (_a = canvas2.parentElement) == null ? void 0 : _a.appendChild(errorDiv);
663
+ }
664
+ }
665
+ function clearError(device) {
666
+ const errorDiv = document.getElementById("animation-loop-error");
667
+ if (errorDiv) {
668
+ errorDiv.remove();
669
+ }
670
+ }
678
671
 
679
672
  // dist/model/model.js
680
- var import_core7 = require("@luma.gl/core");
673
+ var import_core9 = require("@luma.gl/core");
681
674
  var import_shadertools2 = require("@luma.gl/shadertools");
682
675
 
683
676
  // dist/geometry/gpu-geometry.js
@@ -793,63 +786,140 @@ var import_core4 = require("@luma.gl/core");
793
786
  var _PipelineFactory = class {
794
787
  /** Get the singleton default pipeline factory for the specified device */
795
788
  static getDefaultPipelineFactory(device) {
796
- device._lumaData.defaultPipelineFactory = device._lumaData.defaultPipelineFactory || new _PipelineFactory(device);
797
- return device._lumaData.defaultPipelineFactory;
789
+ device._lumaData["defaultPipelineFactory"] = device._lumaData["defaultPipelineFactory"] || new _PipelineFactory(device);
790
+ return device._lumaData["defaultPipelineFactory"];
798
791
  }
799
792
  device;
793
+ cachingEnabled;
800
794
  destroyPolicy;
795
+ debug;
801
796
  _hashCounter = 0;
802
797
  _hashes = {};
803
798
  _renderPipelineCache = {};
804
799
  _computePipelineCache = {};
800
+ get [Symbol.toStringTag]() {
801
+ return "PipelineFactory";
802
+ }
803
+ toString() {
804
+ return `PipelineFactory(${this.device.id})`;
805
+ }
805
806
  constructor(device) {
806
807
  this.device = device;
807
- this.destroyPolicy = device.props._factoryDestroyPolicy;
808
+ this.cachingEnabled = device.props._cachePipelines;
809
+ this.destroyPolicy = device.props._cacheDestroyPolicy;
810
+ this.debug = device.props.debugFactories;
808
811
  }
809
- /** Return a RenderPipeline matching props. Reuses a similar pipeline if already created. */
812
+ /** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
810
813
  createRenderPipeline(props) {
814
+ var _a;
815
+ if (!this.cachingEnabled) {
816
+ return this.device.createRenderPipeline(props);
817
+ }
811
818
  const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
819
+ const cache = this._renderPipelineCache;
812
820
  const hash = this._hashRenderPipeline(allProps);
813
- if (!this._renderPipelineCache[hash]) {
814
- const pipeline = this.device.createRenderPipeline({
821
+ let pipeline = (_a = cache[hash]) == null ? void 0 : _a.pipeline;
822
+ if (!pipeline) {
823
+ pipeline = this.device.createRenderPipeline({
815
824
  ...allProps,
816
- id: allProps.id ? `${allProps.id}-cached` : void 0
825
+ id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
817
826
  });
818
827
  pipeline.hash = hash;
819
- this._renderPipelineCache[hash] = { pipeline, useCount: 0 };
828
+ cache[hash] = { pipeline, useCount: 1 };
829
+ if (this.debug) {
830
+ import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
831
+ }
832
+ } else {
833
+ cache[hash].useCount++;
834
+ if (this.debug) {
835
+ import_core4.log.warn(`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
836
+ }
820
837
  }
821
- this._renderPipelineCache[hash].useCount++;
822
- return this._renderPipelineCache[hash].pipeline;
838
+ return pipeline;
823
839
  }
840
+ /** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
824
841
  createComputePipeline(props) {
842
+ var _a;
843
+ if (!this.cachingEnabled) {
844
+ return this.device.createComputePipeline(props);
845
+ }
825
846
  const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
847
+ const cache = this._computePipelineCache;
826
848
  const hash = this._hashComputePipeline(allProps);
827
- if (!this._computePipelineCache[hash]) {
828
- const pipeline = this.device.createComputePipeline({
849
+ let pipeline = (_a = cache[hash]) == null ? void 0 : _a.pipeline;
850
+ if (!pipeline) {
851
+ pipeline = this.device.createComputePipeline({
829
852
  ...allProps,
830
853
  id: allProps.id ? `${allProps.id}-cached` : void 0
831
854
  });
832
855
  pipeline.hash = hash;
833
- this._computePipelineCache[hash] = { pipeline, useCount: 0 };
856
+ cache[hash] = { pipeline, useCount: 1 };
857
+ if (this.debug) {
858
+ import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
859
+ }
860
+ } else {
861
+ cache[hash].useCount++;
862
+ if (this.debug) {
863
+ import_core4.log.warn(`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
864
+ }
834
865
  }
835
- this._computePipelineCache[hash].useCount++;
836
- return this._computePipelineCache[hash].pipeline;
866
+ return pipeline;
837
867
  }
838
868
  release(pipeline) {
869
+ if (!this.cachingEnabled) {
870
+ pipeline.destroy();
871
+ return;
872
+ }
873
+ const cache = this._getCache(pipeline);
839
874
  const hash = pipeline.hash;
840
- const cache = pipeline instanceof import_core4.ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
841
875
  cache[hash].useCount--;
842
876
  if (cache[hash].useCount === 0) {
843
- if (this.destroyPolicy === "unused") {
844
- cache[hash].pipeline.destroy();
845
- delete cache[hash];
877
+ this._destroyPipeline(pipeline);
878
+ if (this.debug) {
879
+ import_core4.log.warn(`${this}: ${pipeline} released and destroyed`)();
846
880
  }
881
+ } else if (cache[hash].useCount < 0) {
882
+ import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
883
+ cache[hash].useCount = 0;
884
+ } else if (this.debug) {
885
+ import_core4.log.warn(`${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
847
886
  }
848
887
  }
849
888
  // PRIVATE
889
+ /** Destroy a cached pipeline, removing it from the cache (depending on destroy policy) */
890
+ _destroyPipeline(pipeline) {
891
+ const cache = this._getCache(pipeline);
892
+ switch (this.destroyPolicy) {
893
+ case "never":
894
+ return false;
895
+ case "unused":
896
+ delete cache[pipeline.hash];
897
+ pipeline.destroy();
898
+ return true;
899
+ }
900
+ }
901
+ /** Get the appropriate cache for the type of pipeline */
902
+ _getCache(pipeline) {
903
+ let cache;
904
+ if (pipeline instanceof import_core4.ComputePipeline) {
905
+ cache = this._computePipelineCache;
906
+ }
907
+ if (pipeline instanceof import_core4.RenderPipeline) {
908
+ cache = this._renderPipelineCache;
909
+ }
910
+ if (!cache) {
911
+ throw new Error(`${this}`);
912
+ }
913
+ if (!cache[pipeline.hash]) {
914
+ throw new Error(`${this}: ${pipeline} matched incorrect entry`);
915
+ }
916
+ return cache;
917
+ }
918
+ /** Calculate a hash based on all the inputs for a compute pipeline */
850
919
  _hashComputePipeline(props) {
920
+ const { type } = this.device;
851
921
  const shaderHash = this._getHash(props.shader.source);
852
- return `${shaderHash}`;
922
+ return `${type}/C/${shaderHash}`;
853
923
  }
854
924
  /** Calculate a hash based on all the inputs for a render pipeline */
855
925
  _hashRenderPipeline(props) {
@@ -857,12 +927,14 @@ var _PipelineFactory = class {
857
927
  const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
858
928
  const varyingHash = "-";
859
929
  const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
860
- switch (this.device.type) {
930
+ const { type } = this.device;
931
+ switch (type) {
861
932
  case "webgl":
862
- return `${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
933
+ return `${type}/R/${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
934
+ case "webgpu":
863
935
  default:
864
936
  const parameterHash = this._getHash(JSON.stringify(props.parameters));
865
- return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
937
+ return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
866
938
  }
867
939
  }
868
940
  _getHash(key) {
@@ -880,19 +952,32 @@ var import_core5 = require("@luma.gl/core");
880
952
  var _ShaderFactory = class {
881
953
  /** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
882
954
  static getDefaultShaderFactory(device) {
883
- device._lumaData.defaultShaderFactory ||= new _ShaderFactory(device);
884
- return device._lumaData.defaultShaderFactory;
955
+ device._lumaData["defaultShaderFactory"] ||= new _ShaderFactory(device);
956
+ return device._lumaData["defaultShaderFactory"];
885
957
  }
886
958
  device;
959
+ cachingEnabled;
887
960
  destroyPolicy;
961
+ debug;
888
962
  _cache = {};
963
+ get [Symbol.toStringTag]() {
964
+ return "ShaderFactory";
965
+ }
966
+ toString() {
967
+ return `${this[Symbol.toStringTag]}(${this.device.id})`;
968
+ }
889
969
  /** @internal */
890
970
  constructor(device) {
891
971
  this.device = device;
892
- this.destroyPolicy = device.props._factoryDestroyPolicy;
972
+ this.cachingEnabled = device.props._cacheShaders;
973
+ this.destroyPolicy = device.props._cacheDestroyPolicy;
974
+ this.debug = true;
893
975
  }
894
976
  /** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
895
977
  createShader(props) {
978
+ if (!this.cachingEnabled) {
979
+ return this.device.createShader(props);
980
+ }
896
981
  const key = this._hashShader(props);
897
982
  let cacheEntry = this._cache[key];
898
983
  if (!cacheEntry) {
@@ -900,13 +985,24 @@ var _ShaderFactory = class {
900
985
  ...props,
901
986
  id: props.id ? `${props.id}-cached` : void 0
902
987
  });
903
- this._cache[key] = cacheEntry = { shader, useCount: 0 };
988
+ this._cache[key] = cacheEntry = { shader, useCount: 1 };
989
+ if (this.debug) {
990
+ import_core5.log.warn(`${this}: Created new shader ${shader.id}`)();
991
+ }
992
+ } else {
993
+ cacheEntry.useCount++;
994
+ if (this.debug) {
995
+ import_core5.log.warn(`${this}: Reusing shader ${cacheEntry.shader.id} count=${cacheEntry.useCount}`)();
996
+ }
904
997
  }
905
- cacheEntry.useCount++;
906
998
  return cacheEntry.shader;
907
999
  }
908
1000
  /** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
909
1001
  release(shader) {
1002
+ if (!this.cachingEnabled) {
1003
+ shader.destroy();
1004
+ return;
1005
+ }
910
1006
  const key = this._hashShader(shader);
911
1007
  const cacheEntry = this._cache[key];
912
1008
  if (cacheEntry) {
@@ -915,7 +1011,14 @@ var _ShaderFactory = class {
915
1011
  if (this.destroyPolicy === "unused") {
916
1012
  delete this._cache[key];
917
1013
  cacheEntry.shader.destroy();
1014
+ if (this.debug) {
1015
+ import_core5.log.warn(`${this}: Releasing shader ${shader.id}, destroyed`)();
1016
+ }
918
1017
  }
1018
+ } else if (cacheEntry.useCount < 0) {
1019
+ throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
1020
+ } else if (this.debug) {
1021
+ import_core5.log.warn(`${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
919
1022
  }
920
1023
  }
921
1024
  }
@@ -1026,8 +1129,58 @@ function deepEqual(a, b, depth) {
1026
1129
  return false;
1027
1130
  }
1028
1131
 
1029
- // dist/shader-inputs.js
1132
+ // dist/utils/buffer-layout-helper.js
1030
1133
  var import_core6 = require("@luma.gl/core");
1134
+ var BufferLayoutHelper = class {
1135
+ bufferLayouts;
1136
+ constructor(bufferLayouts) {
1137
+ this.bufferLayouts = bufferLayouts;
1138
+ }
1139
+ getBufferLayout(name) {
1140
+ return this.bufferLayouts.find((layout) => layout.name === name) || null;
1141
+ }
1142
+ /** Get attribute names from a BufferLayout */
1143
+ getAttributeNamesForBuffer(bufferLayout) {
1144
+ var _a;
1145
+ return bufferLayout.attributes ? (_a = bufferLayout.attributes) == null ? void 0 : _a.map((layout) => layout.attribute) : [bufferLayout.name];
1146
+ }
1147
+ mergeBufferLayouts(bufferLayouts1, bufferLayouts2) {
1148
+ const mergedLayouts = [...bufferLayouts1];
1149
+ for (const attribute of bufferLayouts2) {
1150
+ const index = mergedLayouts.findIndex((attribute2) => attribute2.name === attribute.name);
1151
+ if (index < 0) {
1152
+ mergedLayouts.push(attribute);
1153
+ } else {
1154
+ mergedLayouts[index] = attribute;
1155
+ }
1156
+ }
1157
+ return mergedLayouts;
1158
+ }
1159
+ getBufferIndex(bufferName) {
1160
+ const bufferIndex = this.bufferLayouts.findIndex((layout) => layout.name === bufferName);
1161
+ if (bufferIndex === -1) {
1162
+ import_core6.log.warn(`BufferLayout: Missing buffer for "${bufferName}".`)();
1163
+ }
1164
+ return bufferIndex;
1165
+ }
1166
+ };
1167
+
1168
+ // dist/utils/buffer-layout-order.js
1169
+ function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
1170
+ const shaderLayoutMap = Object.fromEntries(shaderLayout.attributes.map((attr) => [attr.name, attr.location]));
1171
+ const sortedLayout = bufferLayout.slice();
1172
+ sortedLayout.sort((a, b) => {
1173
+ const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
1174
+ const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
1175
+ const minLocationA = Math.min(...attributeNamesA.map((name) => shaderLayoutMap[name]));
1176
+ const minLocationB = Math.min(...attributeNamesB.map((name) => shaderLayoutMap[name]));
1177
+ return minLocationA - minLocationB;
1178
+ });
1179
+ return sortedLayout;
1180
+ }
1181
+
1182
+ // dist/shader-inputs.js
1183
+ var import_core7 = require("@luma.gl/core");
1031
1184
  var import_shadertools = require("@luma.gl/shadertools");
1032
1185
 
1033
1186
  // dist/model/split-uniforms-and-bindings.js
@@ -1075,14 +1228,14 @@ var ShaderInputs = class {
1075
1228
  for (const resolvedModule of resolvedModules) {
1076
1229
  modules[resolvedModule.name] = resolvedModule;
1077
1230
  }
1078
- import_core6.log.log(1, "Creating ShaderInputs with modules", Object.keys(modules))();
1231
+ import_core7.log.log(1, "Creating ShaderInputs with modules", Object.keys(modules))();
1079
1232
  this.modules = modules;
1080
1233
  this.moduleUniforms = {};
1081
1234
  this.moduleBindings = {};
1082
1235
  for (const [name, module2] of Object.entries(modules)) {
1083
1236
  this._addModule(module2);
1084
1237
  if (module2.name && name !== module2.name && !this.options.disableWarnings) {
1085
- import_core6.log.warn(`Module name: ${name} vs ${module2.name}`)();
1238
+ import_core7.log.warn(`Module name: ${name} vs ${module2.name}`)();
1086
1239
  }
1087
1240
  }
1088
1241
  }
@@ -1100,7 +1253,7 @@ var ShaderInputs = class {
1100
1253
  const module2 = this.modules[moduleName];
1101
1254
  if (!module2) {
1102
1255
  if (!this.options.disableWarnings) {
1103
- import_core6.log.warn(`Module ${name} not found`)();
1256
+ import_core7.log.warn(`Module ${name} not found`)();
1104
1257
  }
1105
1258
  continue;
1106
1259
  }
@@ -1153,6 +1306,9 @@ var ShaderInputs = class {
1153
1306
  }
1154
1307
  };
1155
1308
 
1309
+ // dist/async-texture/async-texture.js
1310
+ var import_core8 = require("@luma.gl/core");
1311
+
1156
1312
  // dist/application-utils/load-file.js
1157
1313
  var pathPrefix = "";
1158
1314
  function setPathPrefix(prefix) {
@@ -1180,9 +1336,12 @@ async function loadImage(url, opts) {
1180
1336
  }
1181
1337
 
1182
1338
  // dist/async-texture/async-texture.js
1183
- var AsyncTexture = class {
1339
+ var TextureCubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
1340
+ var CubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
1341
+ var _AsyncTexture = class {
1184
1342
  device;
1185
1343
  id;
1344
+ props;
1186
1345
  // TODO - should we type these as possibly `null`? It will make usage harder?
1187
1346
  // @ts-expect-error
1188
1347
  texture;
@@ -1205,9 +1364,15 @@ var AsyncTexture = class {
1205
1364
  }
1206
1365
  constructor(device, props) {
1207
1366
  this.device = device;
1208
- this.id = props.id || uid("async-texture");
1367
+ const id = uid("async-texture");
1368
+ this.props = { ..._AsyncTexture.defaultProps, id, ...props };
1369
+ this.id = this.props.id;
1370
+ props = { ...props };
1209
1371
  if (typeof (props == null ? void 0 : props.data) === "string" && props.dimension === "2d") {
1210
- props = { ...props, data: loadImageBitmap(props.data) };
1372
+ props.data = loadImageBitmap(props.data);
1373
+ }
1374
+ if (props.mipmaps) {
1375
+ props.mipLevels = "auto";
1211
1376
  }
1212
1377
  this.ready = new Promise((resolve, reject) => {
1213
1378
  this.resolveReady = () => {
@@ -1219,22 +1384,50 @@ var AsyncTexture = class {
1219
1384
  this.initAsync(props);
1220
1385
  }
1221
1386
  async initAsync(props) {
1387
+ let resolveReady;
1388
+ let rejectReady;
1222
1389
  const asyncData = props.data;
1223
- let data;
1224
- try {
1225
- data = await awaitAllPromises(asyncData);
1226
- } catch (error) {
1227
- this.rejectReady(error);
1228
- }
1390
+ const data = await awaitAllPromises(asyncData).then(resolveReady, rejectReady);
1229
1391
  if (this.destroyed) {
1230
1392
  return;
1231
1393
  }
1232
- const syncProps = { ...props, data };
1394
+ const size = this.props.width && this.props.height ? { width: this.props.width, height: this.props.height } : this.getTextureDataSize(data);
1395
+ if (!size) {
1396
+ throw new Error("Texture size could not be determined");
1397
+ }
1398
+ const syncProps = { ...size, ...props, data: void 0, mipLevels: 1 };
1399
+ const maxMips = this.device.getMipLevelCount(syncProps.width, syncProps.height);
1400
+ syncProps.mipLevels = this.props.mipLevels === "auto" ? maxMips : Math.min(maxMips, this.props.mipLevels);
1233
1401
  this.texture = this.device.createTexture(syncProps);
1234
1402
  this.sampler = this.texture.sampler;
1235
1403
  this.view = this.texture.view;
1236
1404
  this.isReady = true;
1237
- this.resolveReady();
1405
+ if (props.data) {
1406
+ switch (this.props.dimension) {
1407
+ case "1d":
1408
+ this._setTexture1DData(this.texture, data);
1409
+ break;
1410
+ case "2d":
1411
+ this._setTexture2DData(data);
1412
+ break;
1413
+ case "3d":
1414
+ this._setTexture3DData(this.texture, data);
1415
+ break;
1416
+ case "2d-array":
1417
+ this._setTextureArrayData(this.texture, data);
1418
+ break;
1419
+ case "cube":
1420
+ this._setTextureCubeData(this.texture, data);
1421
+ break;
1422
+ case "cube-array":
1423
+ this._setTextureCubeArrayData(this.texture, data);
1424
+ break;
1425
+ }
1426
+ }
1427
+ if (this.props.mipmaps) {
1428
+ this.generateMipmaps();
1429
+ }
1430
+ import_core8.log.info(1, `${this} loaded`);
1238
1431
  }
1239
1432
  destroy() {
1240
1433
  if (this.texture) {
@@ -1243,10 +1436,18 @@ var AsyncTexture = class {
1243
1436
  }
1244
1437
  this.destroyed = true;
1245
1438
  }
1439
+ generateMipmaps() {
1440
+ this.texture.generateMipmapsWebGL();
1441
+ }
1442
+ /** Set sampler or create and set new Sampler from SamplerProps */
1443
+ setSampler(sampler = {}) {
1444
+ this.texture.setSampler(sampler instanceof import_core8.Sampler ? sampler : this.device.createSampler(sampler));
1445
+ }
1246
1446
  /**
1247
1447
  * Textures are immutable and cannot be resized after creation,
1248
1448
  * but we can create a similar texture with the same parameters but a new size.
1249
1449
  * @note Does not copy contents of the texture
1450
+ * @note Mipmaps may need to be regenerated after resizing / setting new data
1250
1451
  * @todo Abort pending promise and create a texture with the new size?
1251
1452
  */
1252
1453
  resize(size) {
@@ -1263,7 +1464,166 @@ var AsyncTexture = class {
1263
1464
  }
1264
1465
  return true;
1265
1466
  }
1467
+ /** Check if texture data is a typed array */
1468
+ isTextureLevelData(data) {
1469
+ const typedArray = data == null ? void 0 : data.data;
1470
+ return ArrayBuffer.isView(typedArray);
1471
+ }
1472
+ /** Get the size of the texture described by the provided TextureData */
1473
+ getTextureDataSize(data) {
1474
+ if (!data) {
1475
+ return null;
1476
+ }
1477
+ if (ArrayBuffer.isView(data)) {
1478
+ return null;
1479
+ }
1480
+ if (Array.isArray(data)) {
1481
+ return this.getTextureDataSize(data[0]);
1482
+ }
1483
+ if (this.device.isExternalImage(data)) {
1484
+ return this.device.getExternalImageSize(data);
1485
+ }
1486
+ if (data && typeof data === "object" && data.constructor === Object) {
1487
+ const textureDataArray = Object.values(data);
1488
+ const untypedData = textureDataArray[0];
1489
+ return { width: untypedData.width, height: untypedData.height };
1490
+ }
1491
+ throw new Error("texture size deduction failed");
1492
+ }
1493
+ /** Convert luma.gl cubemap face constants to depth index */
1494
+ getCubeFaceDepth(face) {
1495
+ switch (face) {
1496
+ case "+X":
1497
+ return 0;
1498
+ case "-X":
1499
+ return 1;
1500
+ case "+Y":
1501
+ return 2;
1502
+ case "-Y":
1503
+ return 3;
1504
+ case "+Z":
1505
+ return 4;
1506
+ case "-Z":
1507
+ return 5;
1508
+ default:
1509
+ throw new Error(face);
1510
+ }
1511
+ }
1512
+ // EXPERIMENTAL
1513
+ setTextureData(data) {
1514
+ }
1515
+ /** Experimental: Set multiple mip levels */
1516
+ _setTexture1DData(texture, data) {
1517
+ throw new Error("setTexture1DData not supported in WebGL.");
1518
+ }
1519
+ /** Experimental: Set multiple mip levels */
1520
+ _setTexture2DData(lodData, depth = 0) {
1521
+ if (!this.texture) {
1522
+ throw new Error("Texture not initialized");
1523
+ }
1524
+ const lodArray = this._normalizeTextureData(lodData);
1525
+ if (lodArray.length > 1 && this.props.mipmaps !== false) {
1526
+ import_core8.log.warn(`Texture ${this.id} mipmap and multiple LODs.`)();
1527
+ }
1528
+ for (let mipLevel = 0; mipLevel < lodArray.length; mipLevel++) {
1529
+ const imageData = lodArray[mipLevel];
1530
+ if (this.device.isExternalImage(imageData)) {
1531
+ this.texture.copyExternalImage({ image: imageData, depth, mipLevel, flipY: true });
1532
+ } else {
1533
+ this.texture.copyImageData({ data: imageData.data, mipLevel });
1534
+ }
1535
+ }
1536
+ }
1537
+ /**
1538
+ * Experimental: Sets 3D texture data: multiple depth slices, multiple mip levels
1539
+ * @param data
1540
+ */
1541
+ _setTexture3DData(texture, data) {
1542
+ var _a;
1543
+ if (((_a = this.texture) == null ? void 0 : _a.props.dimension) !== "3d") {
1544
+ throw new Error(this.id);
1545
+ }
1546
+ for (let depth = 0; depth < data.length; depth++) {
1547
+ this._setTexture2DData(data[depth], depth);
1548
+ }
1549
+ }
1550
+ /**
1551
+ * Experimental: Set Cube texture data, multiple faces, multiple mip levels
1552
+ * @todo - could support TextureCubeArray with depth
1553
+ * @param data
1554
+ * @param index
1555
+ */
1556
+ _setTextureCubeData(texture, data) {
1557
+ var _a;
1558
+ if (((_a = this.texture) == null ? void 0 : _a.props.dimension) !== "cube") {
1559
+ throw new Error(this.id);
1560
+ }
1561
+ for (const [face, faceData] of Object.entries(data)) {
1562
+ const faceDepth = CubeFaces.indexOf(face);
1563
+ this._setTexture2DData(faceData, faceDepth);
1564
+ }
1565
+ }
1566
+ /**
1567
+ * Experimental: Sets texture array data, multiple levels, multiple depth slices
1568
+ * @param data
1569
+ */
1570
+ _setTextureArrayData(texture, data) {
1571
+ var _a;
1572
+ if (((_a = this.texture) == null ? void 0 : _a.props.dimension) !== "2d-array") {
1573
+ throw new Error(this.id);
1574
+ }
1575
+ for (let depth = 0; depth < data.length; depth++) {
1576
+ this._setTexture2DData(data[depth], depth);
1577
+ }
1578
+ }
1579
+ /**
1580
+ * Experimental: Sets texture cube array, multiple faces, multiple levels, multiple mip levels
1581
+ * @param data
1582
+ */
1583
+ _setTextureCubeArrayData(texture, data) {
1584
+ throw new Error("setTextureCubeArrayData not supported in WebGL2.");
1585
+ }
1586
+ /** Experimental */
1587
+ _setTextureCubeFaceData(texture, lodData, face, depth = 0) {
1588
+ if (Array.isArray(lodData) && lodData.length > 1 && this.props.mipmaps !== false) {
1589
+ import_core8.log.warn(`${this.id} has mipmap and multiple LODs.`)();
1590
+ }
1591
+ const faceDepth = TextureCubeFaces.indexOf(face);
1592
+ this._setTexture2DData(lodData, faceDepth);
1593
+ }
1594
+ /**
1595
+ * Normalize TextureData to an array of TextureImageData / ExternalImages
1596
+ * @param data
1597
+ * @param options
1598
+ * @returns array of TextureImageData / ExternalImages
1599
+ */
1600
+ _normalizeTextureData(data) {
1601
+ const options = this.texture;
1602
+ let mipLevelArray;
1603
+ if (ArrayBuffer.isView(data)) {
1604
+ mipLevelArray = [
1605
+ {
1606
+ // ts-expect-error does data really need to be Uint8ClampedArray?
1607
+ data,
1608
+ width: options.width,
1609
+ height: options.height
1610
+ // depth: options.depth
1611
+ }
1612
+ ];
1613
+ } else if (!Array.isArray(data)) {
1614
+ mipLevelArray = [data];
1615
+ } else {
1616
+ mipLevelArray = data;
1617
+ }
1618
+ return mipLevelArray;
1619
+ }
1266
1620
  };
1621
+ var AsyncTexture = _AsyncTexture;
1622
+ __publicField(AsyncTexture, "defaultProps", {
1623
+ ...import_core8.Texture.defaultProps,
1624
+ data: null,
1625
+ mipmaps: false
1626
+ });
1267
1627
  async function awaitAllPromises(x) {
1268
1628
  x = await x;
1269
1629
  if (Array.isArray(x)) {
@@ -1319,8 +1679,6 @@ var _Model = class {
1319
1679
  constantAttributes = {};
1320
1680
  /** Bindings (textures, samplers, uniform buffers) */
1321
1681
  bindings = {};
1322
- /** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
1323
- uniforms = {};
1324
1682
  /**
1325
1683
  * VertexArray
1326
1684
  * @note not implemented: if bufferLayout is updated, vertex array has to be rebuilt!
@@ -1338,7 +1696,6 @@ var _Model = class {
1338
1696
  _uniformStore;
1339
1697
  _attributeInfos = {};
1340
1698
  _gpuGeometry = null;
1341
- _getModuleUniforms;
1342
1699
  props;
1343
1700
  _pipelineNeedsUpdate = "newly created";
1344
1701
  _needsRedraw = "initializing";
@@ -1398,7 +1755,8 @@ var _Model = class {
1398
1755
  this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
1399
1756
  this.pipeline = this._updatePipeline();
1400
1757
  this.vertexArray = device.createVertexArray({
1401
- renderPipeline: this.pipeline
1758
+ shaderLayout: this.pipeline.shaderLayout,
1759
+ bufferLayout: this.pipeline.bufferLayout
1402
1760
  });
1403
1761
  if (this._gpuGeometry) {
1404
1762
  this._setGeometryAttributes(this._gpuGeometry);
@@ -1424,12 +1782,6 @@ var _Model = class {
1424
1782
  if (props.bindings) {
1425
1783
  this.setBindings(props.bindings);
1426
1784
  }
1427
- if (props.uniforms) {
1428
- this.setUniformsWebGL(props.uniforms);
1429
- }
1430
- if (props.moduleSettings) {
1431
- this.updateModuleSettingsWebGL(props.moduleSettings);
1432
- }
1433
1785
  if (props.transformFeedback) {
1434
1786
  this.transformFeedback = props.transformFeedback;
1435
1787
  }
@@ -1437,16 +1789,16 @@ var _Model = class {
1437
1789
  }
1438
1790
  destroy() {
1439
1791
  var _a;
1440
- if (this._destroyed)
1441
- return;
1442
- this.pipelineFactory.release(this.pipeline);
1443
- this.shaderFactory.release(this.pipeline.vs);
1444
- if (this.pipeline.fs) {
1445
- this.shaderFactory.release(this.pipeline.fs);
1792
+ if (!this._destroyed) {
1793
+ this.pipelineFactory.release(this.pipeline);
1794
+ this.shaderFactory.release(this.pipeline.vs);
1795
+ if (this.pipeline.fs) {
1796
+ this.shaderFactory.release(this.pipeline.fs);
1797
+ }
1798
+ this._uniformStore.destroy();
1799
+ (_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
1800
+ this._destroyed = true;
1446
1801
  }
1447
- this._uniformStore.destroy();
1448
- (_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
1449
- this._destroyed = true;
1450
1802
  }
1451
1803
  // Draw call
1452
1804
  /** Query redraw status. Clears the status. */
@@ -1469,7 +1821,7 @@ var _Model = class {
1469
1821
  draw(renderPass) {
1470
1822
  const loadingBinding = this._areBindingsLoading();
1471
1823
  if (loadingBinding) {
1472
- import_core7.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
1824
+ import_core9.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
1473
1825
  return false;
1474
1826
  }
1475
1827
  try {
@@ -1487,9 +1839,6 @@ var _Model = class {
1487
1839
  this.pipeline.setBindings(syncBindings, {
1488
1840
  disableWarnings: this.props.disableWarnings
1489
1841
  });
1490
- if (!isObjectEmpty(this.uniforms)) {
1491
- this.pipeline.setUniformsWebGL(this.uniforms);
1492
- }
1493
1842
  const { indexBuffer } = this.vertexArray;
1494
1843
  const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
1495
1844
  drawSuccess = this.pipeline.draw({
@@ -1531,7 +1880,7 @@ var _Model = class {
1531
1880
  const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
1532
1881
  if (gpuGeometry) {
1533
1882
  this.setTopology(gpuGeometry.topology || "triangle-list");
1534
- const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
1883
+ const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
1535
1884
  this.bufferLayout = bufferLayoutHelper.mergeBufferLayouts(gpuGeometry.bufferLayout, this.bufferLayout);
1536
1885
  if (this.vertexArray) {
1537
1886
  this._setGeometryAttributes(gpuGeometry);
@@ -1554,12 +1903,13 @@ var _Model = class {
1554
1903
  * @note Triggers a pipeline rebuild / pipeline cache fetch
1555
1904
  */
1556
1905
  setBufferLayout(bufferLayout) {
1557
- const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
1906
+ const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
1558
1907
  this.bufferLayout = this._gpuGeometry ? bufferLayoutHelper.mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout;
1559
1908
  this._setPipelineNeedsUpdate("bufferLayout");
1560
1909
  this.pipeline = this._updatePipeline();
1561
1910
  this.vertexArray = this.device.createVertexArray({
1562
- renderPipeline: this.pipeline
1911
+ shaderLayout: this.pipeline.shaderLayout,
1912
+ bufferLayout: this.pipeline.bufferLayout
1563
1913
  });
1564
1914
  if (this._gpuGeometry) {
1565
1915
  this._setGeometryAttributes(this._gpuGeometry);
@@ -1599,7 +1949,7 @@ var _Model = class {
1599
1949
  /** Set the shader inputs */
1600
1950
  setShaderInputs(shaderInputs) {
1601
1951
  this.shaderInputs = shaderInputs;
1602
- this._uniformStore = new import_core7.UniformStore(this.shaderInputs.modules);
1952
+ this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
1603
1953
  for (const [moduleName, module2] of Object.entries(this.shaderInputs.modules)) {
1604
1954
  if (shaderModuleHasUniforms(module2)) {
1605
1955
  const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
@@ -1642,16 +1992,16 @@ var _Model = class {
1642
1992
  */
1643
1993
  setAttributes(buffers, options) {
1644
1994
  const disableWarnings = (options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings;
1645
- if (buffers.indices) {
1646
- import_core7.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
1995
+ if (buffers["indices"]) {
1996
+ import_core9.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
1647
1997
  }
1648
- this.bufferLayout = (0, import_core7.sortedBufferLayoutByShaderSourceLocations)(this.pipeline.shaderLayout, this.bufferLayout);
1649
- const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
1998
+ this.bufferLayout = sortedBufferLayoutByShaderSourceLocations(this.pipeline.shaderLayout, this.bufferLayout);
1999
+ const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
1650
2000
  for (const [bufferName, buffer] of Object.entries(buffers)) {
1651
2001
  const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
1652
2002
  if (!bufferLayout) {
1653
2003
  if (!disableWarnings) {
1654
- import_core7.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
2004
+ import_core9.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
1655
2005
  }
1656
2006
  continue;
1657
2007
  }
@@ -1666,7 +2016,7 @@ var _Model = class {
1666
2016
  }
1667
2017
  }
1668
2018
  if (!set && !disableWarnings) {
1669
- import_core7.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
2019
+ import_core9.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
1670
2020
  }
1671
2021
  }
1672
2022
  this.setNeedsRedraw("attributes");
@@ -1685,42 +2035,12 @@ var _Model = class {
1685
2035
  if (attributeInfo) {
1686
2036
  this.vertexArray.setConstantWebGL(attributeInfo.location, value);
1687
2037
  } else if (!((options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings)) {
1688
- import_core7.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
2038
+ import_core9.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
1689
2039
  }
1690
2040
  }
1691
2041
  this.setNeedsRedraw("constants");
1692
2042
  }
1693
- // DEPRECATED METHODS
1694
- /**
1695
- * Sets individual uniforms
1696
- * @deprecated WebGL only, use uniform buffers for portability
1697
- * @param uniforms
1698
- */
1699
- setUniforms(uniforms) {
1700
- this.setUniformsWebGL(uniforms);
1701
- }
1702
- /**
1703
- * Sets individual uniforms
1704
- * @deprecated WebGL only, use uniform buffers for portability
1705
- * @param uniforms
1706
- */
1707
- setUniformsWebGL(uniforms) {
1708
- if (!isObjectEmpty(uniforms)) {
1709
- this.pipeline.setUniformsWebGL(uniforms);
1710
- Object.assign(this.uniforms, uniforms);
1711
- }
1712
- this.setNeedsRedraw("uniforms");
1713
- }
1714
- /**
1715
- * @deprecated Updates shader module settings (which results in uniforms being set)
1716
- */
1717
- updateModuleSettingsWebGL(props) {
1718
- const { bindings, uniforms } = splitUniformsAndBindings(this._getModuleUniforms(props));
1719
- Object.assign(this.bindings, bindings);
1720
- Object.assign(this.uniforms, uniforms);
1721
- this.setNeedsRedraw("moduleSettings");
1722
- }
1723
- // Internal methods
2043
+ // INTERNAL METHODS
1724
2044
  /** Check that bindings are loaded. Returns id of first binding that is still loading. */
1725
2045
  _areBindingsLoading() {
1726
2046
  for (const binding of Object.values(this.bindings)) {
@@ -1748,16 +2068,16 @@ var _Model = class {
1748
2068
  _getBindingsUpdateTimestamp() {
1749
2069
  let timestamp = 0;
1750
2070
  for (const binding of Object.values(this.bindings)) {
1751
- if (binding instanceof import_core7.TextureView) {
2071
+ if (binding instanceof import_core9.TextureView) {
1752
2072
  timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
1753
- } else if (binding instanceof import_core7.Buffer || binding instanceof import_core7.Texture) {
2073
+ } else if (binding instanceof import_core9.Buffer || binding instanceof import_core9.Texture) {
1754
2074
  timestamp = Math.max(timestamp, binding.updateTimestamp);
1755
2075
  } else if (binding instanceof AsyncTexture) {
1756
2076
  timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
1757
2077
  // The texture will become available in the future
1758
2078
  Infinity
1759
2079
  );
1760
- } else if (!(binding instanceof import_core7.Sampler)) {
2080
+ } else if (!(binding instanceof import_core9.Sampler)) {
1761
2081
  timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
1762
2082
  }
1763
2083
  }
@@ -1792,7 +2112,7 @@ var _Model = class {
1792
2112
  let prevShaderVs = null;
1793
2113
  let prevShaderFs = null;
1794
2114
  if (this.pipeline) {
1795
- import_core7.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
2115
+ import_core9.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
1796
2116
  prevShaderVs = this.pipeline.vs;
1797
2117
  prevShaderFs = this.pipeline.fs;
1798
2118
  }
@@ -1825,7 +2145,7 @@ var _Model = class {
1825
2145
  vs: vs3,
1826
2146
  fs: fs3
1827
2147
  });
1828
- this._attributeInfos = (0, import_core7.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
2148
+ this._attributeInfos = (0, import_core9.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
1829
2149
  if (prevShaderVs)
1830
2150
  this.shaderFactory.release(prevShaderVs);
1831
2151
  if (prevShaderFs)
@@ -1837,27 +2157,24 @@ var _Model = class {
1837
2157
  _lastLogTime = 0;
1838
2158
  _logOpen = false;
1839
2159
  _logDrawCallStart() {
1840
- const logDrawTimeout = import_core7.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
1841
- if (import_core7.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
2160
+ const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
2161
+ if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
1842
2162
  return;
1843
2163
  }
1844
2164
  this._lastLogTime = Date.now();
1845
2165
  this._logOpen = true;
1846
- import_core7.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core7.log.level <= 2 })();
2166
+ import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
1847
2167
  }
1848
2168
  _logDrawCallEnd() {
1849
2169
  if (this._logOpen) {
1850
2170
  const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
1851
- import_core7.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
2171
+ import_core9.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
1852
2172
  const uniformTable = this.shaderInputs.getDebugTable();
1853
- for (const [name, value] of Object.entries(this.uniforms)) {
1854
- uniformTable[name] = { value };
1855
- }
1856
- import_core7.log.table(LOG_DRAW_PRIORITY, uniformTable)();
2173
+ import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
1857
2174
  const attributeTable = this._getAttributeDebugTable();
1858
- import_core7.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
1859
- import_core7.log.table(LOG_DRAW_PRIORITY, attributeTable)();
1860
- import_core7.log.groupEnd(LOG_DRAW_PRIORITY)();
2175
+ import_core9.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
2176
+ import_core9.log.table(LOG_DRAW_PRIORITY, attributeTable)();
2177
+ import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
1861
2178
  this._logOpen = false;
1862
2179
  }
1863
2180
  }
@@ -1886,7 +2203,7 @@ var _Model = class {
1886
2203
  if (this.vertexArray.indexBuffer) {
1887
2204
  const { indexBuffer } = this.vertexArray;
1888
2205
  const values = indexBuffer.indexType === "uint32" ? new Uint32Array(indexBuffer.debugData) : new Uint16Array(indexBuffer.debugData);
1889
- table.indices = {
2206
+ table["indices"] = {
1890
2207
  name: "indices",
1891
2208
  type: indexBuffer.indexType,
1892
2209
  values: values.toString()
@@ -1896,14 +2213,14 @@ var _Model = class {
1896
2213
  }
1897
2214
  // TODO - fix typing of luma data types
1898
2215
  _getBufferOrConstantValues(attribute, dataType) {
1899
- const TypedArrayConstructor = (0, import_core7.getTypedArrayFromDataType)(dataType);
1900
- const typedArray = attribute instanceof import_core7.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
2216
+ const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
2217
+ const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
1901
2218
  return typedArray.toString();
1902
2219
  }
1903
2220
  };
1904
2221
  var Model = _Model;
1905
2222
  __publicField(Model, "defaultProps", {
1906
- ...import_core7.RenderPipeline.defaultProps,
2223
+ ...import_core9.RenderPipeline.defaultProps,
1907
2224
  source: void 0,
1908
2225
  vs: null,
1909
2226
  fs: null,
@@ -1912,7 +2229,6 @@ __publicField(Model, "defaultProps", {
1912
2229
  userData: {},
1913
2230
  defines: {},
1914
2231
  modules: [],
1915
- moduleSettings: void 0,
1916
2232
  geometry: null,
1917
2233
  indexBuffer: null,
1918
2234
  attributes: {},
@@ -1950,7 +2266,7 @@ function isObjectEmpty(obj) {
1950
2266
  }
1951
2267
 
1952
2268
  // dist/compute/buffer-transform.js
1953
- var import_core8 = require("@luma.gl/core");
2269
+ var import_core10 = require("@luma.gl/core");
1954
2270
  var import_shadertools3 = require("@luma.gl/shadertools");
1955
2271
  var _BufferTransform = class {
1956
2272
  device;
@@ -2013,7 +2329,7 @@ var _BufferTransform = class {
2013
2329
  if (!result) {
2014
2330
  throw new Error("BufferTransform#getBuffer");
2015
2331
  }
2016
- if (result instanceof import_core8.Buffer) {
2332
+ if (result instanceof import_core10.Buffer) {
2017
2333
  return result.readAsync();
2018
2334
  }
2019
2335
  const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
@@ -2050,7 +2366,7 @@ var TextureTransform = class {
2050
2366
  mipmapFilter: "nearest"
2051
2367
  });
2052
2368
  this.model = new Model(this.device, {
2053
- id: props.id || "texture-transform-model",
2369
+ id: props.id || uid("texture-transform-model"),
2054
2370
  fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
2055
2371
  input: props.targetTextureVarying,
2056
2372
  inputChannels: props.targetTextureChannels,
@@ -2080,6 +2396,7 @@ var TextureTransform = class {
2080
2396
  const renderPass = this.device.beginRenderPass({ framebuffer, ...options });
2081
2397
  this.model.draw(renderPass);
2082
2398
  renderPass.end();
2399
+ this.device.submit();
2083
2400
  }
2084
2401
  getTargetTexture() {
2085
2402
  const { targetTexture } = this.bindings[this.currentIndex];
@@ -2167,9 +2484,9 @@ var Geometry = class {
2167
2484
  this.attributes[attributeName] = attribute;
2168
2485
  }
2169
2486
  }
2170
- if (this.indices && this.indices.isIndexed !== void 0) {
2487
+ if (this.indices && this.indices["isIndexed"] !== void 0) {
2171
2488
  this.indices = Object.assign({}, this.indices);
2172
- delete this.indices.isIndexed;
2489
+ delete this.indices["isIndexed"];
2173
2490
  }
2174
2491
  this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
2175
2492
  }
@@ -2295,7 +2612,7 @@ var BACKGROUND_FS_WGSL = (
2295
2612
  @group(0) @binding(1) var backgroundTextureSampler: sampler;
2296
2613
 
2297
2614
  fn billboardTexture_getTextureUV(coordinates: vec2<f32>) -> vec2<f32> {
2298
- let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0) * 2;
2615
+ let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0);
2299
2616
  let texSize: vec2<f32> = vec2<f32>(f32(iTexSize.x), f32(iTexSize.y));
2300
2617
  var position: vec2<f32> = coordinates.xy / texSize;
2301
2618
  return position;
@@ -2317,7 +2634,7 @@ uniform sampler2D backgroundTexture;
2317
2634
  out vec4 fragColor;
2318
2635
 
2319
2636
  vec2 billboardTexture_getTextureUV() {
2320
- ivec2 iTexSize = textureDimensions(backgroundTexture, 0) * 2;
2637
+ ivec2 iTexSize = textureSize(backgroundTexture, 0);
2321
2638
  vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
2322
2639
  vec2 position = gl_FragCoord.xy / texSize;
2323
2640
  return position;
@@ -2337,18 +2654,20 @@ var BackgroundTextureModel = class extends ClipSpace {
2337
2654
  fs: BACKGROUND_FS,
2338
2655
  parameters: {
2339
2656
  depthWriteEnabled: false,
2340
- depthCompare: "always",
2341
2657
  ...props.blend ? {
2342
2658
  blend: true,
2343
2659
  blendColorOperation: "add",
2344
2660
  blendAlphaOperation: "add",
2345
2661
  blendColorSrcFactor: "one",
2346
- blendColorDstFactor: "one-minus-src-color",
2662
+ blendColorDstFactor: "one-minus-src",
2347
2663
  blendAlphaSrcFactor: "one",
2348
2664
  blendAlphaDstFactor: "one-minus-src-alpha"
2349
2665
  } : {}
2350
2666
  }
2351
2667
  });
2668
+ if (!props.backgroundTexture) {
2669
+ throw new Error("BackgroundTextureModel requires a backgroundTexture prop");
2670
+ }
2352
2671
  this.setTexture(props.backgroundTexture);
2353
2672
  }
2354
2673
  setTexture(backgroundTexture) {
@@ -2363,14 +2682,14 @@ var BackgroundTextureModel = class extends ClipSpace {
2363
2682
  };
2364
2683
 
2365
2684
  // dist/scenegraph/scenegraph-node.js
2366
- var import_core9 = require("@math.gl/core");
2685
+ var import_core11 = require("@math.gl/core");
2367
2686
  var ScenegraphNode = class {
2368
2687
  id;
2369
- matrix = new import_core9.Matrix4();
2688
+ matrix = new import_core11.Matrix4();
2370
2689
  display = true;
2371
- position = new import_core9.Vector3();
2372
- rotation = new import_core9.Vector3();
2373
- scale = new import_core9.Vector3(1, 1, 1);
2690
+ position = new import_core11.Vector3();
2691
+ rotation = new import_core11.Vector3();
2692
+ scale = new import_core11.Vector3(1, 1, 1);
2374
2693
  userData = {};
2375
2694
  props = {};
2376
2695
  constructor(props = {}) {
@@ -2455,7 +2774,7 @@ var ScenegraphNode = class {
2455
2774
  }
2456
2775
  getCoordinateUniforms(viewMatrix, modelMatrix) {
2457
2776
  modelMatrix = modelMatrix || this.matrix;
2458
- const worldMatrix = new import_core9.Matrix4(viewMatrix).multiplyRight(modelMatrix);
2777
+ const worldMatrix = new import_core11.Matrix4(viewMatrix).multiplyRight(modelMatrix);
2459
2778
  const worldInverse = worldMatrix.invert();
2460
2779
  const worldInverseTranspose = worldInverse.transpose();
2461
2780
  return {
@@ -2507,14 +2826,14 @@ var ScenegraphNode = class {
2507
2826
  };
2508
2827
 
2509
2828
  // dist/scenegraph/group-node.js
2510
- var import_core10 = require("@math.gl/core");
2511
- var import_core11 = require("@luma.gl/core");
2829
+ var import_core12 = require("@math.gl/core");
2830
+ var import_core13 = require("@luma.gl/core");
2512
2831
  var GroupNode = class extends ScenegraphNode {
2513
2832
  children;
2514
2833
  constructor(props = {}) {
2515
2834
  props = Array.isArray(props) ? { children: props } : props;
2516
2835
  const { children = [] } = props;
2517
- import_core11.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
2836
+ import_core13.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
2518
2837
  super(props);
2519
2838
  this.children = children;
2520
2839
  }
@@ -2529,12 +2848,12 @@ var GroupNode = class extends ScenegraphNode {
2529
2848
  return;
2530
2849
  }
2531
2850
  const [min, max] = bounds;
2532
- const center = new import_core10.Vector3(min).add(max).divide([2, 2, 2]);
2851
+ const center = new import_core12.Vector3(min).add(max).divide([2, 2, 2]);
2533
2852
  worldMatrix.transformAsPoint(center, center);
2534
- const halfSize = new import_core10.Vector3(max).subtract(min).divide([2, 2, 2]);
2853
+ const halfSize = new import_core12.Vector3(max).subtract(min).divide([2, 2, 2]);
2535
2854
  worldMatrix.transformAsVector(halfSize, halfSize);
2536
2855
  for (let v = 0; v < 8; v++) {
2537
- const position = new import_core10.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
2856
+ const position = new import_core12.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
2538
2857
  for (let i = 0; i < 3; i++) {
2539
2858
  result[0][i] = Math.min(result[0][i], position[i]);
2540
2859
  result[1][i] = Math.max(result[1][i], position[i]);
@@ -2574,8 +2893,8 @@ var GroupNode = class extends ScenegraphNode {
2574
2893
  this.children = [];
2575
2894
  return this;
2576
2895
  }
2577
- traverse(visitor, { worldMatrix = new import_core10.Matrix4() } = {}) {
2578
- const modelMatrix = new import_core10.Matrix4(worldMatrix).multiplyRight(this.matrix);
2896
+ traverse(visitor, { worldMatrix = new import_core12.Matrix4() } = {}) {
2897
+ const modelMatrix = new import_core12.Matrix4(worldMatrix).multiplyRight(this.matrix);
2579
2898
  for (const child of this.children) {
2580
2899
  if (child instanceof GroupNode) {
2581
2900
  child.traverse(visitor, { worldMatrix: modelMatrix });
@@ -3357,7 +3676,7 @@ var CylinderGeometry = class extends TruncatedConeGeometry {
3357
3676
  };
3358
3677
 
3359
3678
  // dist/geometries/ico-sphere-geometry.js
3360
- var import_core12 = require("@math.gl/core");
3679
+ var import_core14 = require("@math.gl/core");
3361
3680
  var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
3362
3681
  var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
3363
3682
  var IcoSphereGeometry = class extends Geometry {
@@ -3455,7 +3774,7 @@ function tesselateIcosaHedron(props) {
3455
3774
  const u3 = 1 - phi3 / PI2;
3456
3775
  const vec1 = [x3 - x2, y3 - y2, z3 - z2];
3457
3776
  const vec2 = [x1 - x2, y1 - y2, z1 - z2];
3458
- const normal = new import_core12.Vector3(vec1).cross(vec2).normalize();
3777
+ const normal = new import_core14.Vector3(vec1).cross(vec2).normalize();
3459
3778
  let newIndex;
3460
3779
  if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
3461
3780
  positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
@@ -3719,7 +4038,7 @@ function fract(n) {
3719
4038
  var import_shadertools5 = require("@luma.gl/shadertools");
3720
4039
 
3721
4040
  // dist/compute/swap.js
3722
- var import_core13 = require("@luma.gl/core");
4041
+ var import_core15 = require("@luma.gl/core");
3723
4042
  var Swap = class {
3724
4043
  /** The current resource - usually the source for renders or computations */
3725
4044
  current;
@@ -3748,12 +4067,16 @@ var SwapFramebuffers = class extends Swap {
3748
4067
  props = { ...props };
3749
4068
  let colorAttachments = (_a = props.colorAttachments) == null ? void 0 : _a.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
3750
4069
  format: colorAttachment,
3751
- usage: import_core13.Texture.COPY_DST | import_core13.Texture.RENDER_ATTACHMENT
4070
+ usage: import_core15.Texture.SAMPLE | import_core15.Texture.RENDER | import_core15.Texture.COPY_SRC | import_core15.Texture.COPY_DST,
4071
+ width: 1,
4072
+ height: 1
3752
4073
  }));
3753
4074
  const current = device.createFramebuffer({ ...props, colorAttachments });
3754
4075
  colorAttachments = (_b = props.colorAttachments) == null ? void 0 : _b.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
3755
4076
  format: colorAttachment,
3756
- usage: import_core13.Texture.COPY_DST | import_core13.Texture.RENDER_ATTACHMENT
4077
+ usage: import_core15.Texture.TEXTURE | import_core15.Texture.COPY_SRC | import_core15.Texture.COPY_DST | import_core15.Texture.RENDER_ATTACHMENT,
4078
+ width: 1,
4079
+ height: 1
3757
4080
  }));
3758
4081
  const next = device.createFramebuffer({ ...props, colorAttachments });
3759
4082
  super({ current, next });
@@ -3815,11 +4138,11 @@ function getFilterShaderWGSL(func) {
3815
4138
  return (
3816
4139
  /* wgsl */
3817
4140
  `// Binding 0:1 is reserved for shader passes
3818
- @group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
4141
+ // @group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
3819
4142
  @group(0) @binding(1) var texture: texture_2d<f32>;
3820
4143
  @group(0) @binding(2) var sampler: sampler;
3821
4144
 
3822
- struct FragmentInputs = {
4145
+ struct FragmentInputs {
3823
4146
  @location(0) fragUV: vec2f,
3824
4147
  @location(1) fragPosition: vec4f,
3825
4148
  @location(2) fragCoordinate: vec4f
@@ -3921,9 +4244,9 @@ var ShaderPassRenderer = class {
3921
4244
  props.shaderPasses.map((shaderPass) => (0, import_shadertools5.initializeShaderModule)(shaderPass));
3922
4245
  const modules = props.shaderPasses.reduce((object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }), {});
3923
4246
  this.shaderInputs = props.shaderInputs || new ShaderInputs(modules);
3924
- const size = device.getCanvasContext().getPixelSize();
4247
+ const size = device.getCanvasContext().getDrawingBufferSize();
3925
4248
  this.swapFramebuffers = new SwapFramebuffers(device, {
3926
- colorAttachments: ["rgba8unorm"],
4249
+ colorAttachments: [device.preferredColorFormat],
3927
4250
  width: size[0],
3928
4251
  height: size[1]
3929
4252
  });
@@ -3977,7 +4300,13 @@ void main() {
3977
4300
  if (!outputTexture) {
3978
4301
  return false;
3979
4302
  }
3980
- const renderPass = this.device.beginRenderPass({ clearColor: [0, 0, 0, 1], clearDepth: 1 });
4303
+ const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilAttachment: false });
4304
+ const renderPass = this.device.beginRenderPass({
4305
+ id: "shader-pass-renderer-to-screen",
4306
+ framebuffer,
4307
+ clearColor: [0, 0, 0, 1],
4308
+ clearDepth: 1
4309
+ });
3981
4310
  this.clipSpace.setBindings({ sourceTexture: outputTexture });
3982
4311
  this.clipSpace.draw(renderPass);
3983
4312
  renderPass.end();
@@ -3996,6 +4325,7 @@ void main() {
3996
4325
  backgroundTexture: sourceTexture
3997
4326
  });
3998
4327
  const clearTexturePass = this.device.beginRenderPass({
4328
+ id: "shader-pass-renderer-clear-texture",
3999
4329
  framebuffer: this.swapFramebuffers.current,
4000
4330
  clearColor: [0, 0, 0, 1]
4001
4331
  });
@@ -4014,6 +4344,7 @@ void main() {
4014
4344
  // texSize: [sourceTextures.width, sourceTextures.height]
4015
4345
  };
4016
4346
  const renderPass = this.device.beginRenderPass({
4347
+ id: "shader-pass-renderer-run-pass",
4017
4348
  framebuffer: this.swapFramebuffers.next,
4018
4349
  clearColor: [0, 0, 0, 1],
4019
4350
  clearDepth: 1
@@ -4062,8 +4393,7 @@ var SubPassRenderer = class {
4062
4393
  fs: fs3,
4063
4394
  modules: [shaderPass],
4064
4395
  parameters: {
4065
- depthWriteEnabled: false,
4066
- depthCompare: "always"
4396
+ depthWriteEnabled: false
4067
4397
  }
4068
4398
  });
4069
4399
  }
@@ -4084,7 +4414,7 @@ var SubPassRenderer = class {
4084
4414
  };
4085
4415
 
4086
4416
  // dist/compute/computation.js
4087
- var import_core14 = require("@luma.gl/core");
4417
+ var import_core16 = require("@luma.gl/core");
4088
4418
  var import_shadertools6 = require("@luma.gl/shadertools");
4089
4419
  var import_types2 = require("@math.gl/types");
4090
4420
  var LOG_DRAW_PRIORITY2 = 2;
@@ -4183,7 +4513,7 @@ var _Computation = class {
4183
4513
  }
4184
4514
  setShaderInputs(shaderInputs) {
4185
4515
  this.shaderInputs = shaderInputs;
4186
- this._uniformStore = new import_core14.UniformStore(this.shaderInputs.modules);
4516
+ this._uniformStore = new import_core16.UniformStore(this.shaderInputs.modules);
4187
4517
  for (const moduleName of Object.keys(this.shaderInputs.modules)) {
4188
4518
  const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
4189
4519
  this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
@@ -4220,7 +4550,7 @@ var _Computation = class {
4220
4550
  if (this._pipelineNeedsUpdate) {
4221
4551
  let prevShader = null;
4222
4552
  if (this.pipeline) {
4223
- import_core14.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
4553
+ import_core16.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
4224
4554
  prevShader = this.shader;
4225
4555
  }
4226
4556
  this._pipelineNeedsUpdate = false;
@@ -4244,33 +4574,33 @@ var _Computation = class {
4244
4574
  _lastLogTime = 0;
4245
4575
  _logOpen = false;
4246
4576
  _logDrawCallStart() {
4247
- const logDrawTimeout = import_core14.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
4248
- if (import_core14.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
4577
+ const logDrawTimeout = import_core16.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
4578
+ if (import_core16.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
4249
4579
  return;
4250
4580
  }
4251
4581
  this._lastLogTime = Date.now();
4252
4582
  this._logOpen = true;
4253
- import_core14.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core14.log.level <= 2 })();
4583
+ import_core16.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core16.log.level <= 2 })();
4254
4584
  }
4255
4585
  _logDrawCallEnd() {
4256
4586
  if (this._logOpen) {
4257
4587
  const uniformTable = this.shaderInputs.getDebugTable();
4258
- import_core14.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
4259
- import_core14.log.groupEnd(LOG_DRAW_PRIORITY2)();
4588
+ import_core16.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
4589
+ import_core16.log.groupEnd(LOG_DRAW_PRIORITY2)();
4260
4590
  this._logOpen = false;
4261
4591
  }
4262
4592
  }
4263
4593
  _drawCount = 0;
4264
4594
  // TODO - fix typing of luma data types
4265
4595
  _getBufferOrConstantValues(attribute, dataType) {
4266
- const TypedArrayConstructor = (0, import_core14.getTypedArrayFromDataType)(dataType);
4267
- const typedArray = attribute instanceof import_core14.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
4596
+ const TypedArrayConstructor = (0, import_core16.getTypedArrayConstructor)(dataType);
4597
+ const typedArray = attribute instanceof import_core16.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
4268
4598
  return typedArray.toString();
4269
4599
  }
4270
4600
  };
4271
4601
  var Computation = _Computation;
4272
4602
  __publicField(Computation, "defaultProps", {
4273
- ...import_core14.ComputePipeline.defaultProps,
4603
+ ...import_core16.ComputePipeline.defaultProps,
4274
4604
  id: "unnamed",
4275
4605
  handle: void 0,
4276
4606
  userData: {},
@@ -4423,7 +4753,7 @@ var _PickingManager = class {
4423
4753
  beginRenderPass() {
4424
4754
  var _a;
4425
4755
  const framebuffer = this.getFramebuffer();
4426
- framebuffer.resize(this.device.getDefaultCanvasContext().getPixelSize());
4756
+ framebuffer.resize(this.device.getDefaultCanvasContext().getDevicePixelSize());
4427
4757
  (_a = this.props.shaderInputs) == null ? void 0 : _a.setProps({ picking: { isActive: true } });
4428
4758
  const pickingPass = this.device.beginRenderPass({
4429
4759
  framebuffer,
@@ -4432,7 +4762,7 @@ var _PickingManager = class {
4432
4762
  });
4433
4763
  return pickingPass;
4434
4764
  }
4435
- getPickInfo(mousePosition) {
4765
+ async updatePickInfo(mousePosition) {
4436
4766
  var _a;
4437
4767
  const framebuffer = this.getFramebuffer();
4438
4768
  const [pickX, pickY] = this.getPickPosition(mousePosition);
@@ -4795,7 +5125,7 @@ var LegacyPickingManager = class {
4795
5125
  /** Prepare for rendering picking colors */
4796
5126
  beginRenderPass() {
4797
5127
  const framebuffer = this.getFramebuffer();
4798
- framebuffer.resize(this.device.getCanvasContext().getPixelSize());
5128
+ framebuffer.resize(this.device.getCanvasContext().getDevicePixelSize());
4799
5129
  this.shaderInputs.setProps({ picking: { isActive: true } });
4800
5130
  const pickingPass = this.device.beginRenderPass({
4801
5131
  framebuffer,