@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.
- package/README.md +5 -0
- package/dist/animation-loop/animation-loop.d.ts +12 -12
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +26 -62
- package/dist/animation-loop/animation-loop.js.map +1 -1
- package/dist/animation-loop/animation-props.d.ts +3 -4
- package/dist/animation-loop/animation-props.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.d.ts +4 -1
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +39 -7
- package/dist/animation-loop/make-animation-loop.js.map +1 -1
- package/dist/async-texture/async-texture.d.ts +106 -2
- package/dist/async-texture/async-texture.d.ts.map +1 -1
- package/dist/async-texture/async-texture.js +281 -13
- package/dist/async-texture/async-texture.js.map +1 -1
- package/dist/compute/computation.d.ts +1 -1
- package/dist/compute/computation.d.ts.map +1 -1
- package/dist/compute/computation.js +2 -2
- package/dist/compute/computation.js.map +1 -1
- package/dist/compute/swap.d.ts.map +1 -1
- package/dist/compute/swap.js +6 -2
- package/dist/compute/swap.js.map +1 -1
- package/dist/compute/texture-transform.d.ts.map +1 -1
- package/dist/compute/texture-transform.js +4 -2
- package/dist/compute/texture-transform.js.map +1 -1
- package/dist/debug/copy-texture-to-image.d.ts +23 -1
- package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
- package/dist/debug/copy-texture-to-image.js +37 -1
- package/dist/debug/copy-texture-to-image.js.map +1 -1
- package/dist/dist.dev.js +566 -232
- package/dist/dist.min.js +26 -26
- package/dist/factories/pipeline-factory.d.ts +11 -1
- package/dist/factories/pipeline-factory.d.ts.map +1 -1
- package/dist/factories/pipeline-factory.js +107 -25
- package/dist/factories/pipeline-factory.js.map +1 -1
- package/dist/factories/shader-factory.d.ts +5 -1
- package/dist/factories/shader-factory.d.ts.map +1 -1
- package/dist/factories/shader-factory.js +40 -6
- package/dist/factories/shader-factory.js.map +1 -1
- package/dist/geometries/cube-geometry.d.ts +3 -3
- package/dist/geometries/cube-geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +3 -2
- package/dist/geometry/geometry.js.map +1 -1
- package/dist/index.cjs +581 -251
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/model.d.ts +4 -25
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +26 -71
- package/dist/model/model.js.map +1 -1
- package/dist/models/billboard-texture-model.d.ts.map +1 -1
- package/dist/models/billboard-texture-model.js +6 -4
- package/dist/models/billboard-texture-model.js.map +1 -1
- package/dist/modules/picking/legacy-picking-manager.d.ts +1 -1
- package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -1
- package/dist/modules/picking/legacy-picking-manager.js +1 -1
- package/dist/modules/picking/legacy-picking-manager.js.map +1 -1
- package/dist/modules/picking/picking-manager.d.ts +2 -2
- package/dist/modules/picking/picking-manager.d.ts.map +1 -1
- package/dist/modules/picking/picking-manager.js +2 -2
- package/dist/modules/picking/picking-manager.js.map +1 -1
- package/dist/passes/get-fragment-shader.js +2 -2
- package/dist/passes/shader-pass-renderer.d.ts +4 -4
- package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
- package/dist/passes/shader-pass-renderer.js +15 -5
- package/dist/passes/shader-pass-renderer.js.map +1 -1
- package/dist/shader-inputs.js +1 -1
- package/dist/shader-inputs.js.map +1 -1
- package/dist/utils/buffer-layout-helper.d.ts +12 -0
- package/dist/utils/buffer-layout-helper.d.ts.map +1 -0
- package/dist/utils/buffer-layout-helper.js +41 -0
- package/dist/utils/buffer-layout-helper.js.map +1 -0
- package/dist/utils/buffer-layout-order.d.ts +3 -0
- package/dist/utils/buffer-layout-order.d.ts.map +1 -0
- package/dist/utils/buffer-layout-order.js +16 -0
- package/dist/utils/buffer-layout-order.js.map +1 -0
- package/package.json +4 -4
- package/src/animation-loop/animation-loop.ts +31 -71
- package/src/animation-loop/animation-props.ts +3 -5
- package/src/animation-loop/make-animation-loop.ts +41 -9
- package/src/async-texture/async-texture.ts +386 -23
- package/src/async-texture/texture-setters.ts.disabled +296 -0
- package/src/compute/computation.ts +3 -3
- package/src/compute/swap.ts +7 -2
- package/src/compute/texture-transform.ts +4 -2
- package/src/debug/copy-texture-to-image.ts +52 -2
- package/src/factories/pipeline-factory.ts +122 -26
- package/src/factories/shader-factory.ts +43 -7
- package/src/geometry/geometry.ts +3 -2
- package/src/index.ts +12 -0
- package/src/model/model.ts +31 -86
- package/src/models/billboard-texture-model.ts +6 -4
- package/src/modules/picking/legacy-picking-manager.ts +2 -2
- package/src/modules/picking/picking-manager.ts +3 -3
- package/src/passes/get-fragment-shader.ts +2 -2
- package/src/passes/shader-pass-renderer.ts +18 -8
- package/src/shader-inputs.ts +1 -1
- package/src/utils/buffer-layout-helper.ts +51 -0
- package/src/utils/buffer-layout-order.ts +26 -0
package/dist/dist.dev.js
CHANGED
|
@@ -481,25 +481,7 @@ var __exports__ = (() => {
|
|
|
481
481
|
|
|
482
482
|
// src/animation-loop/animation-loop.ts
|
|
483
483
|
var statIdCounter = 0;
|
|
484
|
-
var
|
|
485
|
-
device: null,
|
|
486
|
-
onAddHTML: () => "",
|
|
487
|
-
onInitialize: async () => {
|
|
488
|
-
return null;
|
|
489
|
-
},
|
|
490
|
-
onRender: () => {
|
|
491
|
-
},
|
|
492
|
-
onFinalize: () => {
|
|
493
|
-
},
|
|
494
|
-
onError: (error) => console.error(error),
|
|
495
|
-
// eslint-disable-line no-console
|
|
496
|
-
stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
|
|
497
|
-
// view parameters
|
|
498
|
-
useDevicePixels: true,
|
|
499
|
-
autoResizeViewport: false,
|
|
500
|
-
autoResizeDrawingBuffer: false
|
|
501
|
-
};
|
|
502
|
-
var AnimationLoop = class {
|
|
484
|
+
var _AnimationLoop = class {
|
|
503
485
|
device = null;
|
|
504
486
|
canvas = null;
|
|
505
487
|
props;
|
|
@@ -523,21 +505,16 @@ var __exports__ = (() => {
|
|
|
523
505
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
524
506
|
*/
|
|
525
507
|
constructor(props) {
|
|
526
|
-
this.props = { ...
|
|
508
|
+
this.props = { ..._AnimationLoop.defaultAnimationLoopProps, ...props };
|
|
527
509
|
props = this.props;
|
|
528
510
|
if (!props.device) {
|
|
529
511
|
throw new Error("No device provided");
|
|
530
512
|
}
|
|
531
|
-
const { useDevicePixels = true } = this.props;
|
|
532
513
|
this.stats = props.stats || new Stats({ id: "animation-loop-stats" });
|
|
533
514
|
this.cpuTime = this.stats.get("CPU Time");
|
|
534
515
|
this.gpuTime = this.stats.get("GPU Time");
|
|
535
516
|
this.frameRate = this.stats.get("Frame Rate");
|
|
536
|
-
this.setProps({
|
|
537
|
-
autoResizeViewport: props.autoResizeViewport,
|
|
538
|
-
autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
|
|
539
|
-
useDevicePixels
|
|
540
|
-
});
|
|
517
|
+
this.setProps({ autoResizeViewport: props.autoResizeViewport });
|
|
541
518
|
this.start = this.start.bind(this);
|
|
542
519
|
this.stop = this.stop.bind(this);
|
|
543
520
|
this._onMousemove = this._onMousemove.bind(this);
|
|
@@ -551,37 +528,19 @@ var __exports__ = (() => {
|
|
|
551
528
|
delete() {
|
|
552
529
|
this.destroy();
|
|
553
530
|
}
|
|
554
|
-
|
|
531
|
+
reportError(error) {
|
|
555
532
|
this.props.onError(error);
|
|
556
|
-
this._error =
|
|
557
|
-
const canvas2 = this.device?.canvasContext?.canvas;
|
|
558
|
-
if (canvas2 instanceof HTMLCanvasElement) {
|
|
559
|
-
const errorDiv = document.createElement("h1");
|
|
560
|
-
errorDiv.innerHTML = error.message;
|
|
561
|
-
errorDiv.style.position = "absolute";
|
|
562
|
-
errorDiv.style.top = "20%";
|
|
563
|
-
errorDiv.style.left = "10px";
|
|
564
|
-
errorDiv.style.color = "black";
|
|
565
|
-
errorDiv.style.backgroundColor = "red";
|
|
566
|
-
document.body.appendChild(errorDiv);
|
|
567
|
-
}
|
|
533
|
+
this._error = error;
|
|
568
534
|
}
|
|
569
535
|
/** Flags this animation loop as needing redraw */
|
|
570
536
|
setNeedsRedraw(reason) {
|
|
571
537
|
this.needsRedraw = this.needsRedraw || reason;
|
|
572
538
|
return this;
|
|
573
539
|
}
|
|
574
|
-
/** TODO - move these props to CanvasContext? */
|
|
575
540
|
setProps(props) {
|
|
576
541
|
if ("autoResizeViewport" in props) {
|
|
577
542
|
this.props.autoResizeViewport = props.autoResizeViewport || false;
|
|
578
543
|
}
|
|
579
|
-
if ("autoResizeDrawingBuffer" in props) {
|
|
580
|
-
this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
|
|
581
|
-
}
|
|
582
|
-
if ("useDevicePixels" in props) {
|
|
583
|
-
this.props.useDevicePixels = props.useDevicePixels || false;
|
|
584
|
-
}
|
|
585
544
|
return this;
|
|
586
545
|
}
|
|
587
546
|
/** Starts a render loop if not already running */
|
|
@@ -676,7 +635,6 @@ var __exports__ = (() => {
|
|
|
676
635
|
this._startEventHandling();
|
|
677
636
|
this._initializeAnimationProps();
|
|
678
637
|
this._updateAnimationProps();
|
|
679
|
-
this._resizeCanvasDrawingBuffer();
|
|
680
638
|
this._resizeViewport();
|
|
681
639
|
}
|
|
682
640
|
_setDisplay(display) {
|
|
@@ -723,22 +681,24 @@ var __exports__ = (() => {
|
|
|
723
681
|
this.needsRedraw = false;
|
|
724
682
|
}
|
|
725
683
|
_setupFrame() {
|
|
726
|
-
this._resizeCanvasDrawingBuffer();
|
|
727
684
|
this._resizeViewport();
|
|
728
685
|
}
|
|
729
686
|
// Initialize the object that will be passed to app callbacks
|
|
730
687
|
_initializeAnimationProps() {
|
|
731
|
-
const
|
|
732
|
-
if (!this.device || !
|
|
688
|
+
const canvasContext = this.device?.getDefaultCanvasContext();
|
|
689
|
+
if (!this.device || !canvasContext) {
|
|
733
690
|
throw new Error("loop");
|
|
734
691
|
}
|
|
692
|
+
const canvas2 = canvasContext?.canvas;
|
|
693
|
+
const useDevicePixels = canvasContext.props.useDevicePixels;
|
|
735
694
|
this.animationProps = {
|
|
736
695
|
animationLoop: this,
|
|
737
696
|
device: this.device,
|
|
697
|
+
canvasContext,
|
|
738
698
|
canvas: canvas2,
|
|
699
|
+
// @ts-expect-error Deprecated
|
|
700
|
+
useDevicePixels,
|
|
739
701
|
timeline: this.timeline,
|
|
740
|
-
// Initial values
|
|
741
|
-
useDevicePixels: this.props.useDevicePixels,
|
|
742
702
|
needsRedraw: false,
|
|
743
703
|
// Placeholders
|
|
744
704
|
width: 1,
|
|
@@ -791,7 +751,7 @@ var __exports__ = (() => {
|
|
|
791
751
|
if (!this.device) {
|
|
792
752
|
throw new Error("No device provided");
|
|
793
753
|
}
|
|
794
|
-
this.canvas = this.device.
|
|
754
|
+
this.canvas = this.device.getDefaultCanvasContext().canvas || null;
|
|
795
755
|
}
|
|
796
756
|
_createInfoDiv() {
|
|
797
757
|
if (this.canvas && this.props.onAddHTML) {
|
|
@@ -818,9 +778,9 @@ var __exports__ = (() => {
|
|
|
818
778
|
if (!this.device) {
|
|
819
779
|
return { width: 1, height: 1, aspect: 1 };
|
|
820
780
|
}
|
|
821
|
-
const [width, height] = this.device?.
|
|
781
|
+
const [width, height] = this.device?.getDefaultCanvasContext().getDevicePixelSize() || [1, 1];
|
|
822
782
|
let aspect = 1;
|
|
823
|
-
const canvas2 = this.device?.
|
|
783
|
+
const canvas2 = this.device?.getDefaultCanvasContext().canvas;
|
|
824
784
|
if (canvas2 && canvas2.clientHeight) {
|
|
825
785
|
aspect = canvas2.clientWidth / canvas2.clientHeight;
|
|
826
786
|
} else if (width > 0 && height > 0) {
|
|
@@ -828,7 +788,7 @@ var __exports__ = (() => {
|
|
|
828
788
|
}
|
|
829
789
|
return { width, height, aspect };
|
|
830
790
|
}
|
|
831
|
-
/** Default viewport setup */
|
|
791
|
+
/** @deprecated Default viewport setup */
|
|
832
792
|
_resizeViewport() {
|
|
833
793
|
if (this.props.autoResizeViewport && this.device.gl) {
|
|
834
794
|
this.device.gl.viewport(
|
|
@@ -841,15 +801,6 @@ var __exports__ = (() => {
|
|
|
841
801
|
);
|
|
842
802
|
}
|
|
843
803
|
}
|
|
844
|
-
/**
|
|
845
|
-
* Resize the render buffer of the canvas to match canvas client size
|
|
846
|
-
* Optionally multiplying with devicePixel ratio
|
|
847
|
-
*/
|
|
848
|
-
_resizeCanvasDrawingBuffer() {
|
|
849
|
-
if (this.props.autoResizeDrawingBuffer) {
|
|
850
|
-
this.device?.canvasContext?.resize({ useDevicePixels: this.props.useDevicePixels });
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
804
|
_beginFrameTimers() {
|
|
854
805
|
this.frameRate.timeEnd();
|
|
855
806
|
this.frameRate.timeStart();
|
|
@@ -874,6 +825,21 @@ var __exports__ = (() => {
|
|
|
874
825
|
this._getAnimationProps()._mousePosition = null;
|
|
875
826
|
}
|
|
876
827
|
};
|
|
828
|
+
var AnimationLoop = _AnimationLoop;
|
|
829
|
+
__publicField(AnimationLoop, "defaultAnimationLoopProps", {
|
|
830
|
+
device: null,
|
|
831
|
+
onAddHTML: () => "",
|
|
832
|
+
onInitialize: async () => null,
|
|
833
|
+
onRender: () => {
|
|
834
|
+
},
|
|
835
|
+
onFinalize: () => {
|
|
836
|
+
},
|
|
837
|
+
onError: (error) => console.error(error),
|
|
838
|
+
// eslint-disable-line no-console
|
|
839
|
+
stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
|
|
840
|
+
// view parameters
|
|
841
|
+
autoResizeViewport: false
|
|
842
|
+
});
|
|
877
843
|
|
|
878
844
|
// src/animation-loop/make-animation-loop.ts
|
|
879
845
|
var import_core2 = __toESM(require_core(), 1);
|
|
@@ -884,8 +850,14 @@ var __exports__ = (() => {
|
|
|
884
850
|
...props,
|
|
885
851
|
device,
|
|
886
852
|
async onInitialize(animationProps) {
|
|
887
|
-
|
|
888
|
-
|
|
853
|
+
clearError(animationProps.animationLoop.device);
|
|
854
|
+
try {
|
|
855
|
+
renderLoop = new AnimationLoopTemplateCtor(animationProps);
|
|
856
|
+
return await renderLoop?.onInitialize(animationProps);
|
|
857
|
+
} catch (error) {
|
|
858
|
+
setError(animationProps.animationLoop.device, error);
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
889
861
|
},
|
|
890
862
|
onRender: (animationProps) => renderLoop?.onRender(animationProps),
|
|
891
863
|
onFinalize: (animationProps) => renderLoop?.onFinalize(animationProps)
|
|
@@ -895,9 +867,32 @@ var __exports__ = (() => {
|
|
|
895
867
|
};
|
|
896
868
|
return animationLoop;
|
|
897
869
|
}
|
|
870
|
+
function setError(device, error) {
|
|
871
|
+
const canvas2 = device?.getDefaultCanvasContext().canvas;
|
|
872
|
+
if (canvas2 instanceof HTMLCanvasElement) {
|
|
873
|
+
canvas2.style.overflow = "visible";
|
|
874
|
+
let errorDiv = document.getElementById("animation-loop-error");
|
|
875
|
+
errorDiv?.remove();
|
|
876
|
+
errorDiv = document.createElement("h1");
|
|
877
|
+
errorDiv.id = "animation-loop-error";
|
|
878
|
+
errorDiv.innerHTML = error.message;
|
|
879
|
+
errorDiv.style.position = "absolute";
|
|
880
|
+
errorDiv.style.top = "10px";
|
|
881
|
+
errorDiv.style.left = "10px";
|
|
882
|
+
errorDiv.style.color = "black";
|
|
883
|
+
errorDiv.style.backgroundColor = "red";
|
|
884
|
+
canvas2.parentElement?.appendChild(errorDiv);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function clearError(device) {
|
|
888
|
+
const errorDiv = document.getElementById("animation-loop-error");
|
|
889
|
+
if (errorDiv) {
|
|
890
|
+
errorDiv.remove();
|
|
891
|
+
}
|
|
892
|
+
}
|
|
898
893
|
|
|
899
894
|
// src/model/model.ts
|
|
900
|
-
var
|
|
895
|
+
var import_core9 = __toESM(require_core(), 1);
|
|
901
896
|
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
902
897
|
|
|
903
898
|
// src/geometry/gpu-geometry.ts
|
|
@@ -1012,63 +1007,142 @@ var __exports__ = (() => {
|
|
|
1012
1007
|
var _PipelineFactory = class {
|
|
1013
1008
|
/** Get the singleton default pipeline factory for the specified device */
|
|
1014
1009
|
static getDefaultPipelineFactory(device) {
|
|
1015
|
-
device._lumaData
|
|
1016
|
-
return device._lumaData
|
|
1010
|
+
device._lumaData["defaultPipelineFactory"] = device._lumaData["defaultPipelineFactory"] || new _PipelineFactory(device);
|
|
1011
|
+
return device._lumaData["defaultPipelineFactory"];
|
|
1017
1012
|
}
|
|
1018
1013
|
device;
|
|
1014
|
+
cachingEnabled;
|
|
1019
1015
|
destroyPolicy;
|
|
1016
|
+
debug;
|
|
1020
1017
|
_hashCounter = 0;
|
|
1021
1018
|
_hashes = {};
|
|
1022
1019
|
_renderPipelineCache = {};
|
|
1023
1020
|
_computePipelineCache = {};
|
|
1021
|
+
get [Symbol.toStringTag]() {
|
|
1022
|
+
return "PipelineFactory";
|
|
1023
|
+
}
|
|
1024
|
+
toString() {
|
|
1025
|
+
return `PipelineFactory(${this.device.id})`;
|
|
1026
|
+
}
|
|
1024
1027
|
constructor(device) {
|
|
1025
1028
|
this.device = device;
|
|
1026
|
-
this.
|
|
1029
|
+
this.cachingEnabled = device.props._cachePipelines;
|
|
1030
|
+
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1031
|
+
this.debug = device.props.debugFactories;
|
|
1027
1032
|
}
|
|
1028
|
-
/** Return a RenderPipeline matching props. Reuses
|
|
1033
|
+
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1029
1034
|
createRenderPipeline(props) {
|
|
1035
|
+
if (!this.cachingEnabled) {
|
|
1036
|
+
return this.device.createRenderPipeline(props);
|
|
1037
|
+
}
|
|
1030
1038
|
const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
|
|
1039
|
+
const cache = this._renderPipelineCache;
|
|
1031
1040
|
const hash = this._hashRenderPipeline(allProps);
|
|
1032
|
-
|
|
1033
|
-
|
|
1041
|
+
let pipeline = cache[hash]?.pipeline;
|
|
1042
|
+
if (!pipeline) {
|
|
1043
|
+
pipeline = this.device.createRenderPipeline({
|
|
1034
1044
|
...allProps,
|
|
1035
|
-
id: allProps.id ? `${allProps.id}-cached` :
|
|
1045
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
|
|
1036
1046
|
});
|
|
1037
1047
|
pipeline.hash = hash;
|
|
1038
|
-
|
|
1048
|
+
cache[hash] = { pipeline, useCount: 1 };
|
|
1049
|
+
if (this.debug) {
|
|
1050
|
+
import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1051
|
+
}
|
|
1052
|
+
} else {
|
|
1053
|
+
cache[hash].useCount++;
|
|
1054
|
+
if (this.debug) {
|
|
1055
|
+
import_core4.log.warn(
|
|
1056
|
+
`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1057
|
+
)();
|
|
1058
|
+
}
|
|
1039
1059
|
}
|
|
1040
|
-
|
|
1041
|
-
return this._renderPipelineCache[hash].pipeline;
|
|
1060
|
+
return pipeline;
|
|
1042
1061
|
}
|
|
1062
|
+
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1043
1063
|
createComputePipeline(props) {
|
|
1064
|
+
if (!this.cachingEnabled) {
|
|
1065
|
+
return this.device.createComputePipeline(props);
|
|
1066
|
+
}
|
|
1044
1067
|
const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
|
|
1068
|
+
const cache = this._computePipelineCache;
|
|
1045
1069
|
const hash = this._hashComputePipeline(allProps);
|
|
1046
|
-
|
|
1047
|
-
|
|
1070
|
+
let pipeline = cache[hash]?.pipeline;
|
|
1071
|
+
if (!pipeline) {
|
|
1072
|
+
pipeline = this.device.createComputePipeline({
|
|
1048
1073
|
...allProps,
|
|
1049
1074
|
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
1050
1075
|
});
|
|
1051
1076
|
pipeline.hash = hash;
|
|
1052
|
-
|
|
1077
|
+
cache[hash] = { pipeline, useCount: 1 };
|
|
1078
|
+
if (this.debug) {
|
|
1079
|
+
import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1080
|
+
}
|
|
1081
|
+
} else {
|
|
1082
|
+
cache[hash].useCount++;
|
|
1083
|
+
if (this.debug) {
|
|
1084
|
+
import_core4.log.warn(
|
|
1085
|
+
`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1086
|
+
)();
|
|
1087
|
+
}
|
|
1053
1088
|
}
|
|
1054
|
-
|
|
1055
|
-
return this._computePipelineCache[hash].pipeline;
|
|
1089
|
+
return pipeline;
|
|
1056
1090
|
}
|
|
1057
1091
|
release(pipeline) {
|
|
1092
|
+
if (!this.cachingEnabled) {
|
|
1093
|
+
pipeline.destroy();
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
const cache = this._getCache(pipeline);
|
|
1058
1097
|
const hash = pipeline.hash;
|
|
1059
|
-
const cache = pipeline instanceof import_core4.ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
|
|
1060
1098
|
cache[hash].useCount--;
|
|
1061
1099
|
if (cache[hash].useCount === 0) {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1100
|
+
this._destroyPipeline(pipeline);
|
|
1101
|
+
if (this.debug) {
|
|
1102
|
+
import_core4.log.warn(`${this}: ${pipeline} released and destroyed`)();
|
|
1065
1103
|
}
|
|
1104
|
+
} else if (cache[hash].useCount < 0) {
|
|
1105
|
+
import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
1106
|
+
cache[hash].useCount = 0;
|
|
1107
|
+
} else if (this.debug) {
|
|
1108
|
+
import_core4.log.warn(`${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
1066
1109
|
}
|
|
1067
1110
|
}
|
|
1068
1111
|
// PRIVATE
|
|
1112
|
+
/** Destroy a cached pipeline, removing it from the cache (depending on destroy policy) */
|
|
1113
|
+
_destroyPipeline(pipeline) {
|
|
1114
|
+
const cache = this._getCache(pipeline);
|
|
1115
|
+
switch (this.destroyPolicy) {
|
|
1116
|
+
case "never":
|
|
1117
|
+
return false;
|
|
1118
|
+
case "unused":
|
|
1119
|
+
delete cache[pipeline.hash];
|
|
1120
|
+
pipeline.destroy();
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
/** Get the appropriate cache for the type of pipeline */
|
|
1125
|
+
_getCache(pipeline) {
|
|
1126
|
+
let cache;
|
|
1127
|
+
if (pipeline instanceof import_core4.ComputePipeline) {
|
|
1128
|
+
cache = this._computePipelineCache;
|
|
1129
|
+
}
|
|
1130
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
1131
|
+
cache = this._renderPipelineCache;
|
|
1132
|
+
}
|
|
1133
|
+
if (!cache) {
|
|
1134
|
+
throw new Error(`${this}`);
|
|
1135
|
+
}
|
|
1136
|
+
if (!cache[pipeline.hash]) {
|
|
1137
|
+
throw new Error(`${this}: ${pipeline} matched incorrect entry`);
|
|
1138
|
+
}
|
|
1139
|
+
return cache;
|
|
1140
|
+
}
|
|
1141
|
+
/** Calculate a hash based on all the inputs for a compute pipeline */
|
|
1069
1142
|
_hashComputePipeline(props) {
|
|
1143
|
+
const { type } = this.device;
|
|
1070
1144
|
const shaderHash = this._getHash(props.shader.source);
|
|
1071
|
-
return `${shaderHash}`;
|
|
1145
|
+
return `${type}/C/${shaderHash}`;
|
|
1072
1146
|
}
|
|
1073
1147
|
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
1074
1148
|
_hashRenderPipeline(props) {
|
|
@@ -1076,12 +1150,14 @@ var __exports__ = (() => {
|
|
|
1076
1150
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1077
1151
|
const varyingHash = "-";
|
|
1078
1152
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
1079
|
-
|
|
1153
|
+
const { type } = this.device;
|
|
1154
|
+
switch (type) {
|
|
1080
1155
|
case "webgl":
|
|
1081
|
-
return `${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
|
|
1156
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
|
|
1157
|
+
case "webgpu":
|
|
1082
1158
|
default:
|
|
1083
1159
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1084
|
-
return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
1160
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
1085
1161
|
}
|
|
1086
1162
|
}
|
|
1087
1163
|
_getHash(key) {
|
|
@@ -1099,19 +1175,32 @@ var __exports__ = (() => {
|
|
|
1099
1175
|
var _ShaderFactory = class {
|
|
1100
1176
|
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
1101
1177
|
static getDefaultShaderFactory(device) {
|
|
1102
|
-
device._lumaData
|
|
1103
|
-
return device._lumaData
|
|
1178
|
+
device._lumaData["defaultShaderFactory"] ||= new _ShaderFactory(device);
|
|
1179
|
+
return device._lumaData["defaultShaderFactory"];
|
|
1104
1180
|
}
|
|
1105
1181
|
device;
|
|
1182
|
+
cachingEnabled;
|
|
1106
1183
|
destroyPolicy;
|
|
1184
|
+
debug;
|
|
1107
1185
|
_cache = {};
|
|
1186
|
+
get [Symbol.toStringTag]() {
|
|
1187
|
+
return "ShaderFactory";
|
|
1188
|
+
}
|
|
1189
|
+
toString() {
|
|
1190
|
+
return `${this[Symbol.toStringTag]}(${this.device.id})`;
|
|
1191
|
+
}
|
|
1108
1192
|
/** @internal */
|
|
1109
1193
|
constructor(device) {
|
|
1110
1194
|
this.device = device;
|
|
1111
|
-
this.
|
|
1195
|
+
this.cachingEnabled = device.props._cacheShaders;
|
|
1196
|
+
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1197
|
+
this.debug = true;
|
|
1112
1198
|
}
|
|
1113
1199
|
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
1114
1200
|
createShader(props) {
|
|
1201
|
+
if (!this.cachingEnabled) {
|
|
1202
|
+
return this.device.createShader(props);
|
|
1203
|
+
}
|
|
1115
1204
|
const key = this._hashShader(props);
|
|
1116
1205
|
let cacheEntry = this._cache[key];
|
|
1117
1206
|
if (!cacheEntry) {
|
|
@@ -1119,13 +1208,24 @@ var __exports__ = (() => {
|
|
|
1119
1208
|
...props,
|
|
1120
1209
|
id: props.id ? `${props.id}-cached` : void 0
|
|
1121
1210
|
});
|
|
1122
|
-
this._cache[key] = cacheEntry = { shader, useCount:
|
|
1211
|
+
this._cache[key] = cacheEntry = { shader, useCount: 1 };
|
|
1212
|
+
if (this.debug) {
|
|
1213
|
+
import_core5.log.warn(`${this}: Created new shader ${shader.id}`)();
|
|
1214
|
+
}
|
|
1215
|
+
} else {
|
|
1216
|
+
cacheEntry.useCount++;
|
|
1217
|
+
if (this.debug) {
|
|
1218
|
+
import_core5.log.warn(`${this}: Reusing shader ${cacheEntry.shader.id} count=${cacheEntry.useCount}`)();
|
|
1219
|
+
}
|
|
1123
1220
|
}
|
|
1124
|
-
cacheEntry.useCount++;
|
|
1125
1221
|
return cacheEntry.shader;
|
|
1126
1222
|
}
|
|
1127
1223
|
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
1128
1224
|
release(shader) {
|
|
1225
|
+
if (!this.cachingEnabled) {
|
|
1226
|
+
shader.destroy();
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1129
1229
|
const key = this._hashShader(shader);
|
|
1130
1230
|
const cacheEntry = this._cache[key];
|
|
1131
1231
|
if (cacheEntry) {
|
|
@@ -1134,7 +1234,14 @@ var __exports__ = (() => {
|
|
|
1134
1234
|
if (this.destroyPolicy === "unused") {
|
|
1135
1235
|
delete this._cache[key];
|
|
1136
1236
|
cacheEntry.shader.destroy();
|
|
1237
|
+
if (this.debug) {
|
|
1238
|
+
import_core5.log.warn(`${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
1239
|
+
}
|
|
1137
1240
|
}
|
|
1241
|
+
} else if (cacheEntry.useCount < 0) {
|
|
1242
|
+
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
1243
|
+
} else if (this.debug) {
|
|
1244
|
+
import_core5.log.warn(`${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
1138
1245
|
}
|
|
1139
1246
|
}
|
|
1140
1247
|
}
|
|
@@ -1251,8 +1358,59 @@ var __exports__ = (() => {
|
|
|
1251
1358
|
return false;
|
|
1252
1359
|
}
|
|
1253
1360
|
|
|
1254
|
-
// src/
|
|
1361
|
+
// src/utils/buffer-layout-helper.ts
|
|
1255
1362
|
var import_core6 = __toESM(require_core(), 1);
|
|
1363
|
+
var BufferLayoutHelper = class {
|
|
1364
|
+
bufferLayouts;
|
|
1365
|
+
constructor(bufferLayouts) {
|
|
1366
|
+
this.bufferLayouts = bufferLayouts;
|
|
1367
|
+
}
|
|
1368
|
+
getBufferLayout(name) {
|
|
1369
|
+
return this.bufferLayouts.find((layout) => layout.name === name) || null;
|
|
1370
|
+
}
|
|
1371
|
+
/** Get attribute names from a BufferLayout */
|
|
1372
|
+
getAttributeNamesForBuffer(bufferLayout) {
|
|
1373
|
+
return bufferLayout.attributes ? bufferLayout.attributes?.map((layout) => layout.attribute) : [bufferLayout.name];
|
|
1374
|
+
}
|
|
1375
|
+
mergeBufferLayouts(bufferLayouts1, bufferLayouts2) {
|
|
1376
|
+
const mergedLayouts = [...bufferLayouts1];
|
|
1377
|
+
for (const attribute of bufferLayouts2) {
|
|
1378
|
+
const index = mergedLayouts.findIndex((attribute2) => attribute2.name === attribute.name);
|
|
1379
|
+
if (index < 0) {
|
|
1380
|
+
mergedLayouts.push(attribute);
|
|
1381
|
+
} else {
|
|
1382
|
+
mergedLayouts[index] = attribute;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
return mergedLayouts;
|
|
1386
|
+
}
|
|
1387
|
+
getBufferIndex(bufferName) {
|
|
1388
|
+
const bufferIndex = this.bufferLayouts.findIndex((layout) => layout.name === bufferName);
|
|
1389
|
+
if (bufferIndex === -1) {
|
|
1390
|
+
import_core6.log.warn(`BufferLayout: Missing buffer for "${bufferName}".`)();
|
|
1391
|
+
}
|
|
1392
|
+
return bufferIndex;
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
// src/utils/buffer-layout-order.ts
|
|
1397
|
+
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
1398
|
+
const shaderLayoutMap = Object.fromEntries(
|
|
1399
|
+
shaderLayout.attributes.map((attr) => [attr.name, attr.location])
|
|
1400
|
+
);
|
|
1401
|
+
const sortedLayout = bufferLayout.slice();
|
|
1402
|
+
sortedLayout.sort((a, b) => {
|
|
1403
|
+
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
1404
|
+
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
1405
|
+
const minLocationA = Math.min(...attributeNamesA.map((name) => shaderLayoutMap[name]));
|
|
1406
|
+
const minLocationB = Math.min(...attributeNamesB.map((name) => shaderLayoutMap[name]));
|
|
1407
|
+
return minLocationA - minLocationB;
|
|
1408
|
+
});
|
|
1409
|
+
return sortedLayout;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// src/shader-inputs.ts
|
|
1413
|
+
var import_core7 = __toESM(require_core(), 1);
|
|
1256
1414
|
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
1257
1415
|
|
|
1258
1416
|
// ../../node_modules/@math.gl/types/dist/is-array.js
|
|
@@ -1315,14 +1473,14 @@ var __exports__ = (() => {
|
|
|
1315
1473
|
for (const resolvedModule of resolvedModules) {
|
|
1316
1474
|
modules[resolvedModule.name] = resolvedModule;
|
|
1317
1475
|
}
|
|
1318
|
-
|
|
1476
|
+
import_core7.log.log(1, "Creating ShaderInputs with modules", Object.keys(modules))();
|
|
1319
1477
|
this.modules = modules;
|
|
1320
1478
|
this.moduleUniforms = {};
|
|
1321
1479
|
this.moduleBindings = {};
|
|
1322
1480
|
for (const [name, module] of Object.entries(modules)) {
|
|
1323
1481
|
this._addModule(module);
|
|
1324
1482
|
if (module.name && name !== module.name && !this.options.disableWarnings) {
|
|
1325
|
-
|
|
1483
|
+
import_core7.log.warn(`Module name: ${name} vs ${module.name}`)();
|
|
1326
1484
|
}
|
|
1327
1485
|
}
|
|
1328
1486
|
}
|
|
@@ -1339,7 +1497,7 @@ var __exports__ = (() => {
|
|
|
1339
1497
|
const module = this.modules[moduleName];
|
|
1340
1498
|
if (!module) {
|
|
1341
1499
|
if (!this.options.disableWarnings) {
|
|
1342
|
-
|
|
1500
|
+
import_core7.log.warn(`Module ${name} not found`)();
|
|
1343
1501
|
}
|
|
1344
1502
|
continue;
|
|
1345
1503
|
}
|
|
@@ -1391,6 +1549,9 @@ var __exports__ = (() => {
|
|
|
1391
1549
|
}
|
|
1392
1550
|
};
|
|
1393
1551
|
|
|
1552
|
+
// src/async-texture/async-texture.ts
|
|
1553
|
+
var import_core8 = __toESM(require_core(), 1);
|
|
1554
|
+
|
|
1394
1555
|
// src/application-utils/load-file.ts
|
|
1395
1556
|
var pathPrefix = "";
|
|
1396
1557
|
function setPathPrefix(prefix) {
|
|
@@ -1418,9 +1579,12 @@ var __exports__ = (() => {
|
|
|
1418
1579
|
}
|
|
1419
1580
|
|
|
1420
1581
|
// src/async-texture/async-texture.ts
|
|
1421
|
-
var
|
|
1582
|
+
var TextureCubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
1583
|
+
var CubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
1584
|
+
var _AsyncTexture = class {
|
|
1422
1585
|
device;
|
|
1423
1586
|
id;
|
|
1587
|
+
props;
|
|
1424
1588
|
// TODO - should we type these as possibly `null`? It will make usage harder?
|
|
1425
1589
|
// @ts-expect-error
|
|
1426
1590
|
texture;
|
|
@@ -1443,9 +1607,15 @@ var __exports__ = (() => {
|
|
|
1443
1607
|
}
|
|
1444
1608
|
constructor(device, props) {
|
|
1445
1609
|
this.device = device;
|
|
1446
|
-
|
|
1610
|
+
const id = uid("async-texture");
|
|
1611
|
+
this.props = { ..._AsyncTexture.defaultProps, id, ...props };
|
|
1612
|
+
this.id = this.props.id;
|
|
1613
|
+
props = { ...props };
|
|
1447
1614
|
if (typeof props?.data === "string" && props.dimension === "2d") {
|
|
1448
|
-
props =
|
|
1615
|
+
props.data = loadImageBitmap(props.data);
|
|
1616
|
+
}
|
|
1617
|
+
if (props.mipmaps) {
|
|
1618
|
+
props.mipLevels = "auto";
|
|
1449
1619
|
}
|
|
1450
1620
|
this.ready = new Promise((resolve, reject) => {
|
|
1451
1621
|
this.resolveReady = () => {
|
|
@@ -1457,22 +1627,50 @@ var __exports__ = (() => {
|
|
|
1457
1627
|
this.initAsync(props);
|
|
1458
1628
|
}
|
|
1459
1629
|
async initAsync(props) {
|
|
1630
|
+
let resolveReady;
|
|
1631
|
+
let rejectReady;
|
|
1460
1632
|
const asyncData = props.data;
|
|
1461
|
-
|
|
1462
|
-
try {
|
|
1463
|
-
data = await awaitAllPromises(asyncData);
|
|
1464
|
-
} catch (error) {
|
|
1465
|
-
this.rejectReady(error);
|
|
1466
|
-
}
|
|
1633
|
+
const data = await awaitAllPromises(asyncData).then(resolveReady, rejectReady);
|
|
1467
1634
|
if (this.destroyed) {
|
|
1468
1635
|
return;
|
|
1469
1636
|
}
|
|
1470
|
-
const
|
|
1637
|
+
const size = this.props.width && this.props.height ? { width: this.props.width, height: this.props.height } : this.getTextureDataSize(data);
|
|
1638
|
+
if (!size) {
|
|
1639
|
+
throw new Error("Texture size could not be determined");
|
|
1640
|
+
}
|
|
1641
|
+
const syncProps = { ...size, ...props, data: void 0, mipLevels: 1 };
|
|
1642
|
+
const maxMips = this.device.getMipLevelCount(syncProps.width, syncProps.height);
|
|
1643
|
+
syncProps.mipLevels = this.props.mipLevels === "auto" ? maxMips : Math.min(maxMips, this.props.mipLevels);
|
|
1471
1644
|
this.texture = this.device.createTexture(syncProps);
|
|
1472
1645
|
this.sampler = this.texture.sampler;
|
|
1473
1646
|
this.view = this.texture.view;
|
|
1474
1647
|
this.isReady = true;
|
|
1475
|
-
|
|
1648
|
+
if (props.data) {
|
|
1649
|
+
switch (this.props.dimension) {
|
|
1650
|
+
case "1d":
|
|
1651
|
+
this._setTexture1DData(this.texture, data);
|
|
1652
|
+
break;
|
|
1653
|
+
case "2d":
|
|
1654
|
+
this._setTexture2DData(data);
|
|
1655
|
+
break;
|
|
1656
|
+
case "3d":
|
|
1657
|
+
this._setTexture3DData(this.texture, data);
|
|
1658
|
+
break;
|
|
1659
|
+
case "2d-array":
|
|
1660
|
+
this._setTextureArrayData(this.texture, data);
|
|
1661
|
+
break;
|
|
1662
|
+
case "cube":
|
|
1663
|
+
this._setTextureCubeData(this.texture, data);
|
|
1664
|
+
break;
|
|
1665
|
+
case "cube-array":
|
|
1666
|
+
this._setTextureCubeArrayData(this.texture, data);
|
|
1667
|
+
break;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
if (this.props.mipmaps) {
|
|
1671
|
+
this.generateMipmaps();
|
|
1672
|
+
}
|
|
1673
|
+
import_core8.log.info(1, `${this} loaded`);
|
|
1476
1674
|
}
|
|
1477
1675
|
destroy() {
|
|
1478
1676
|
if (this.texture) {
|
|
@@ -1481,10 +1679,20 @@ var __exports__ = (() => {
|
|
|
1481
1679
|
}
|
|
1482
1680
|
this.destroyed = true;
|
|
1483
1681
|
}
|
|
1682
|
+
generateMipmaps() {
|
|
1683
|
+
this.texture.generateMipmapsWebGL();
|
|
1684
|
+
}
|
|
1685
|
+
/** Set sampler or create and set new Sampler from SamplerProps */
|
|
1686
|
+
setSampler(sampler = {}) {
|
|
1687
|
+
this.texture.setSampler(
|
|
1688
|
+
sampler instanceof import_core8.Sampler ? sampler : this.device.createSampler(sampler)
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1484
1691
|
/**
|
|
1485
1692
|
* Textures are immutable and cannot be resized after creation,
|
|
1486
1693
|
* but we can create a similar texture with the same parameters but a new size.
|
|
1487
1694
|
* @note Does not copy contents of the texture
|
|
1695
|
+
* @note Mipmaps may need to be regenerated after resizing / setting new data
|
|
1488
1696
|
* @todo Abort pending promise and create a texture with the new size?
|
|
1489
1697
|
*/
|
|
1490
1698
|
resize(size) {
|
|
@@ -1501,7 +1709,163 @@ var __exports__ = (() => {
|
|
|
1501
1709
|
}
|
|
1502
1710
|
return true;
|
|
1503
1711
|
}
|
|
1712
|
+
/** Check if texture data is a typed array */
|
|
1713
|
+
isTextureLevelData(data) {
|
|
1714
|
+
const typedArray = data?.data;
|
|
1715
|
+
return ArrayBuffer.isView(typedArray);
|
|
1716
|
+
}
|
|
1717
|
+
/** Get the size of the texture described by the provided TextureData */
|
|
1718
|
+
getTextureDataSize(data) {
|
|
1719
|
+
if (!data) {
|
|
1720
|
+
return null;
|
|
1721
|
+
}
|
|
1722
|
+
if (ArrayBuffer.isView(data)) {
|
|
1723
|
+
return null;
|
|
1724
|
+
}
|
|
1725
|
+
if (Array.isArray(data)) {
|
|
1726
|
+
return this.getTextureDataSize(data[0]);
|
|
1727
|
+
}
|
|
1728
|
+
if (this.device.isExternalImage(data)) {
|
|
1729
|
+
return this.device.getExternalImageSize(data);
|
|
1730
|
+
}
|
|
1731
|
+
if (data && typeof data === "object" && data.constructor === Object) {
|
|
1732
|
+
const textureDataArray = Object.values(data);
|
|
1733
|
+
const untypedData = textureDataArray[0];
|
|
1734
|
+
return { width: untypedData.width, height: untypedData.height };
|
|
1735
|
+
}
|
|
1736
|
+
throw new Error("texture size deduction failed");
|
|
1737
|
+
}
|
|
1738
|
+
/** Convert luma.gl cubemap face constants to depth index */
|
|
1739
|
+
getCubeFaceDepth(face) {
|
|
1740
|
+
switch (face) {
|
|
1741
|
+
case "+X":
|
|
1742
|
+
return 0;
|
|
1743
|
+
case "-X":
|
|
1744
|
+
return 1;
|
|
1745
|
+
case "+Y":
|
|
1746
|
+
return 2;
|
|
1747
|
+
case "-Y":
|
|
1748
|
+
return 3;
|
|
1749
|
+
case "+Z":
|
|
1750
|
+
return 4;
|
|
1751
|
+
case "-Z":
|
|
1752
|
+
return 5;
|
|
1753
|
+
default:
|
|
1754
|
+
throw new Error(face);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
// EXPERIMENTAL
|
|
1758
|
+
setTextureData(data) {
|
|
1759
|
+
}
|
|
1760
|
+
/** Experimental: Set multiple mip levels */
|
|
1761
|
+
_setTexture1DData(texture, data) {
|
|
1762
|
+
throw new Error("setTexture1DData not supported in WebGL.");
|
|
1763
|
+
}
|
|
1764
|
+
/** Experimental: Set multiple mip levels */
|
|
1765
|
+
_setTexture2DData(lodData, depth = 0) {
|
|
1766
|
+
if (!this.texture) {
|
|
1767
|
+
throw new Error("Texture not initialized");
|
|
1768
|
+
}
|
|
1769
|
+
const lodArray = this._normalizeTextureData(lodData);
|
|
1770
|
+
if (lodArray.length > 1 && this.props.mipmaps !== false) {
|
|
1771
|
+
import_core8.log.warn(`Texture ${this.id} mipmap and multiple LODs.`)();
|
|
1772
|
+
}
|
|
1773
|
+
for (let mipLevel = 0; mipLevel < lodArray.length; mipLevel++) {
|
|
1774
|
+
const imageData = lodArray[mipLevel];
|
|
1775
|
+
if (this.device.isExternalImage(imageData)) {
|
|
1776
|
+
this.texture.copyExternalImage({ image: imageData, depth, mipLevel, flipY: true });
|
|
1777
|
+
} else {
|
|
1778
|
+
this.texture.copyImageData({ data: imageData.data, mipLevel });
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
/**
|
|
1783
|
+
* Experimental: Sets 3D texture data: multiple depth slices, multiple mip levels
|
|
1784
|
+
* @param data
|
|
1785
|
+
*/
|
|
1786
|
+
_setTexture3DData(texture, data) {
|
|
1787
|
+
if (this.texture?.props.dimension !== "3d") {
|
|
1788
|
+
throw new Error(this.id);
|
|
1789
|
+
}
|
|
1790
|
+
for (let depth = 0; depth < data.length; depth++) {
|
|
1791
|
+
this._setTexture2DData(data[depth], depth);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Experimental: Set Cube texture data, multiple faces, multiple mip levels
|
|
1796
|
+
* @todo - could support TextureCubeArray with depth
|
|
1797
|
+
* @param data
|
|
1798
|
+
* @param index
|
|
1799
|
+
*/
|
|
1800
|
+
_setTextureCubeData(texture, data) {
|
|
1801
|
+
if (this.texture?.props.dimension !== "cube") {
|
|
1802
|
+
throw new Error(this.id);
|
|
1803
|
+
}
|
|
1804
|
+
for (const [face, faceData] of Object.entries(data)) {
|
|
1805
|
+
const faceDepth = CubeFaces.indexOf(face);
|
|
1806
|
+
this._setTexture2DData(faceData, faceDepth);
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
/**
|
|
1810
|
+
* Experimental: Sets texture array data, multiple levels, multiple depth slices
|
|
1811
|
+
* @param data
|
|
1812
|
+
*/
|
|
1813
|
+
_setTextureArrayData(texture, data) {
|
|
1814
|
+
if (this.texture?.props.dimension !== "2d-array") {
|
|
1815
|
+
throw new Error(this.id);
|
|
1816
|
+
}
|
|
1817
|
+
for (let depth = 0; depth < data.length; depth++) {
|
|
1818
|
+
this._setTexture2DData(data[depth], depth);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* Experimental: Sets texture cube array, multiple faces, multiple levels, multiple mip levels
|
|
1823
|
+
* @param data
|
|
1824
|
+
*/
|
|
1825
|
+
_setTextureCubeArrayData(texture, data) {
|
|
1826
|
+
throw new Error("setTextureCubeArrayData not supported in WebGL2.");
|
|
1827
|
+
}
|
|
1828
|
+
/** Experimental */
|
|
1829
|
+
_setTextureCubeFaceData(texture, lodData, face, depth = 0) {
|
|
1830
|
+
if (Array.isArray(lodData) && lodData.length > 1 && this.props.mipmaps !== false) {
|
|
1831
|
+
import_core8.log.warn(`${this.id} has mipmap and multiple LODs.`)();
|
|
1832
|
+
}
|
|
1833
|
+
const faceDepth = TextureCubeFaces.indexOf(face);
|
|
1834
|
+
this._setTexture2DData(lodData, faceDepth);
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Normalize TextureData to an array of TextureImageData / ExternalImages
|
|
1838
|
+
* @param data
|
|
1839
|
+
* @param options
|
|
1840
|
+
* @returns array of TextureImageData / ExternalImages
|
|
1841
|
+
*/
|
|
1842
|
+
_normalizeTextureData(data) {
|
|
1843
|
+
const options = this.texture;
|
|
1844
|
+
let mipLevelArray;
|
|
1845
|
+
if (ArrayBuffer.isView(data)) {
|
|
1846
|
+
mipLevelArray = [
|
|
1847
|
+
{
|
|
1848
|
+
// ts-expect-error does data really need to be Uint8ClampedArray?
|
|
1849
|
+
data,
|
|
1850
|
+
width: options.width,
|
|
1851
|
+
height: options.height
|
|
1852
|
+
// depth: options.depth
|
|
1853
|
+
}
|
|
1854
|
+
];
|
|
1855
|
+
} else if (!Array.isArray(data)) {
|
|
1856
|
+
mipLevelArray = [data];
|
|
1857
|
+
} else {
|
|
1858
|
+
mipLevelArray = data;
|
|
1859
|
+
}
|
|
1860
|
+
return mipLevelArray;
|
|
1861
|
+
}
|
|
1504
1862
|
};
|
|
1863
|
+
var AsyncTexture = _AsyncTexture;
|
|
1864
|
+
__publicField(AsyncTexture, "defaultProps", {
|
|
1865
|
+
...import_core8.Texture.defaultProps,
|
|
1866
|
+
data: null,
|
|
1867
|
+
mipmaps: false
|
|
1868
|
+
});
|
|
1505
1869
|
async function awaitAllPromises(x) {
|
|
1506
1870
|
x = await x;
|
|
1507
1871
|
if (Array.isArray(x)) {
|
|
@@ -1557,8 +1921,6 @@ var __exports__ = (() => {
|
|
|
1557
1921
|
constantAttributes = {};
|
|
1558
1922
|
/** Bindings (textures, samplers, uniform buffers) */
|
|
1559
1923
|
bindings = {};
|
|
1560
|
-
/** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
|
|
1561
|
-
uniforms = {};
|
|
1562
1924
|
/**
|
|
1563
1925
|
* VertexArray
|
|
1564
1926
|
* @note not implemented: if bufferLayout is updated, vertex array has to be rebuilt!
|
|
@@ -1576,7 +1938,6 @@ var __exports__ = (() => {
|
|
|
1576
1938
|
_uniformStore;
|
|
1577
1939
|
_attributeInfos = {};
|
|
1578
1940
|
_gpuGeometry = null;
|
|
1579
|
-
_getModuleUniforms;
|
|
1580
1941
|
props;
|
|
1581
1942
|
_pipelineNeedsUpdate = "newly created";
|
|
1582
1943
|
_needsRedraw = "initializing";
|
|
@@ -1637,7 +1998,8 @@ var __exports__ = (() => {
|
|
|
1637
1998
|
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1638
1999
|
this.pipeline = this._updatePipeline();
|
|
1639
2000
|
this.vertexArray = device.createVertexArray({
|
|
1640
|
-
|
|
2001
|
+
shaderLayout: this.pipeline.shaderLayout,
|
|
2002
|
+
bufferLayout: this.pipeline.bufferLayout
|
|
1641
2003
|
});
|
|
1642
2004
|
if (this._gpuGeometry) {
|
|
1643
2005
|
this._setGeometryAttributes(this._gpuGeometry);
|
|
@@ -1663,28 +2025,22 @@ var __exports__ = (() => {
|
|
|
1663
2025
|
if (props.bindings) {
|
|
1664
2026
|
this.setBindings(props.bindings);
|
|
1665
2027
|
}
|
|
1666
|
-
if (props.uniforms) {
|
|
1667
|
-
this.setUniformsWebGL(props.uniforms);
|
|
1668
|
-
}
|
|
1669
|
-
if (props.moduleSettings) {
|
|
1670
|
-
this.updateModuleSettingsWebGL(props.moduleSettings);
|
|
1671
|
-
}
|
|
1672
2028
|
if (props.transformFeedback) {
|
|
1673
2029
|
this.transformFeedback = props.transformFeedback;
|
|
1674
2030
|
}
|
|
1675
2031
|
Object.seal(this);
|
|
1676
2032
|
}
|
|
1677
2033
|
destroy() {
|
|
1678
|
-
if (this._destroyed)
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
2034
|
+
if (!this._destroyed) {
|
|
2035
|
+
this.pipelineFactory.release(this.pipeline);
|
|
2036
|
+
this.shaderFactory.release(this.pipeline.vs);
|
|
2037
|
+
if (this.pipeline.fs) {
|
|
2038
|
+
this.shaderFactory.release(this.pipeline.fs);
|
|
2039
|
+
}
|
|
2040
|
+
this._uniformStore.destroy();
|
|
2041
|
+
this._gpuGeometry?.destroy();
|
|
2042
|
+
this._destroyed = true;
|
|
1684
2043
|
}
|
|
1685
|
-
this._uniformStore.destroy();
|
|
1686
|
-
this._gpuGeometry?.destroy();
|
|
1687
|
-
this._destroyed = true;
|
|
1688
2044
|
}
|
|
1689
2045
|
// Draw call
|
|
1690
2046
|
/** Query redraw status. Clears the status. */
|
|
@@ -1707,7 +2063,7 @@ var __exports__ = (() => {
|
|
|
1707
2063
|
draw(renderPass) {
|
|
1708
2064
|
const loadingBinding = this._areBindingsLoading();
|
|
1709
2065
|
if (loadingBinding) {
|
|
1710
|
-
|
|
2066
|
+
import_core9.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
1711
2067
|
return false;
|
|
1712
2068
|
}
|
|
1713
2069
|
try {
|
|
@@ -1725,9 +2081,6 @@ var __exports__ = (() => {
|
|
|
1725
2081
|
this.pipeline.setBindings(syncBindings, {
|
|
1726
2082
|
disableWarnings: this.props.disableWarnings
|
|
1727
2083
|
});
|
|
1728
|
-
if (!isObjectEmpty(this.uniforms)) {
|
|
1729
|
-
this.pipeline.setUniformsWebGL(this.uniforms);
|
|
1730
|
-
}
|
|
1731
2084
|
const { indexBuffer } = this.vertexArray;
|
|
1732
2085
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
1733
2086
|
drawSuccess = this.pipeline.draw({
|
|
@@ -1768,7 +2121,7 @@ var __exports__ = (() => {
|
|
|
1768
2121
|
const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
|
|
1769
2122
|
if (gpuGeometry) {
|
|
1770
2123
|
this.setTopology(gpuGeometry.topology || "triangle-list");
|
|
1771
|
-
const bufferLayoutHelper = new
|
|
2124
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
1772
2125
|
this.bufferLayout = bufferLayoutHelper.mergeBufferLayouts(
|
|
1773
2126
|
gpuGeometry.bufferLayout,
|
|
1774
2127
|
this.bufferLayout
|
|
@@ -1794,12 +2147,13 @@ var __exports__ = (() => {
|
|
|
1794
2147
|
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
1795
2148
|
*/
|
|
1796
2149
|
setBufferLayout(bufferLayout) {
|
|
1797
|
-
const bufferLayoutHelper = new
|
|
2150
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
1798
2151
|
this.bufferLayout = this._gpuGeometry ? bufferLayoutHelper.mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout;
|
|
1799
2152
|
this._setPipelineNeedsUpdate("bufferLayout");
|
|
1800
2153
|
this.pipeline = this._updatePipeline();
|
|
1801
2154
|
this.vertexArray = this.device.createVertexArray({
|
|
1802
|
-
|
|
2155
|
+
shaderLayout: this.pipeline.shaderLayout,
|
|
2156
|
+
bufferLayout: this.pipeline.bufferLayout
|
|
1803
2157
|
});
|
|
1804
2158
|
if (this._gpuGeometry) {
|
|
1805
2159
|
this._setGeometryAttributes(this._gpuGeometry);
|
|
@@ -1839,7 +2193,7 @@ var __exports__ = (() => {
|
|
|
1839
2193
|
/** Set the shader inputs */
|
|
1840
2194
|
setShaderInputs(shaderInputs) {
|
|
1841
2195
|
this.shaderInputs = shaderInputs;
|
|
1842
|
-
this._uniformStore = new
|
|
2196
|
+
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1843
2197
|
for (const [moduleName, module] of Object.entries(this.shaderInputs.modules)) {
|
|
1844
2198
|
if (shaderModuleHasUniforms(module)) {
|
|
1845
2199
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
@@ -1882,21 +2236,21 @@ var __exports__ = (() => {
|
|
|
1882
2236
|
*/
|
|
1883
2237
|
setAttributes(buffers, options) {
|
|
1884
2238
|
const disableWarnings = options?.disableWarnings ?? this.props.disableWarnings;
|
|
1885
|
-
if (buffers
|
|
1886
|
-
|
|
2239
|
+
if (buffers["indices"]) {
|
|
2240
|
+
import_core9.log.warn(
|
|
1887
2241
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
1888
2242
|
)();
|
|
1889
2243
|
}
|
|
1890
|
-
this.bufferLayout =
|
|
2244
|
+
this.bufferLayout = sortedBufferLayoutByShaderSourceLocations(
|
|
1891
2245
|
this.pipeline.shaderLayout,
|
|
1892
2246
|
this.bufferLayout
|
|
1893
2247
|
);
|
|
1894
|
-
const bufferLayoutHelper = new
|
|
2248
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
1895
2249
|
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
1896
2250
|
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
1897
2251
|
if (!bufferLayout) {
|
|
1898
2252
|
if (!disableWarnings) {
|
|
1899
|
-
|
|
2253
|
+
import_core9.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
1900
2254
|
}
|
|
1901
2255
|
continue;
|
|
1902
2256
|
}
|
|
@@ -1911,7 +2265,7 @@ var __exports__ = (() => {
|
|
|
1911
2265
|
}
|
|
1912
2266
|
}
|
|
1913
2267
|
if (!set && !disableWarnings) {
|
|
1914
|
-
|
|
2268
|
+
import_core9.log.warn(
|
|
1915
2269
|
`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
|
|
1916
2270
|
)();
|
|
1917
2271
|
}
|
|
@@ -1932,44 +2286,14 @@ var __exports__ = (() => {
|
|
|
1932
2286
|
if (attributeInfo) {
|
|
1933
2287
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
1934
2288
|
} else if (!(options?.disableWarnings ?? this.props.disableWarnings)) {
|
|
1935
|
-
|
|
2289
|
+
import_core9.log.warn(
|
|
1936
2290
|
`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`
|
|
1937
2291
|
)();
|
|
1938
2292
|
}
|
|
1939
2293
|
}
|
|
1940
2294
|
this.setNeedsRedraw("constants");
|
|
1941
2295
|
}
|
|
1942
|
-
//
|
|
1943
|
-
/**
|
|
1944
|
-
* Sets individual uniforms
|
|
1945
|
-
* @deprecated WebGL only, use uniform buffers for portability
|
|
1946
|
-
* @param uniforms
|
|
1947
|
-
*/
|
|
1948
|
-
setUniforms(uniforms) {
|
|
1949
|
-
this.setUniformsWebGL(uniforms);
|
|
1950
|
-
}
|
|
1951
|
-
/**
|
|
1952
|
-
* Sets individual uniforms
|
|
1953
|
-
* @deprecated WebGL only, use uniform buffers for portability
|
|
1954
|
-
* @param uniforms
|
|
1955
|
-
*/
|
|
1956
|
-
setUniformsWebGL(uniforms) {
|
|
1957
|
-
if (!isObjectEmpty(uniforms)) {
|
|
1958
|
-
this.pipeline.setUniformsWebGL(uniforms);
|
|
1959
|
-
Object.assign(this.uniforms, uniforms);
|
|
1960
|
-
}
|
|
1961
|
-
this.setNeedsRedraw("uniforms");
|
|
1962
|
-
}
|
|
1963
|
-
/**
|
|
1964
|
-
* @deprecated Updates shader module settings (which results in uniforms being set)
|
|
1965
|
-
*/
|
|
1966
|
-
updateModuleSettingsWebGL(props) {
|
|
1967
|
-
const { bindings, uniforms } = splitUniformsAndBindings(this._getModuleUniforms(props));
|
|
1968
|
-
Object.assign(this.bindings, bindings);
|
|
1969
|
-
Object.assign(this.uniforms, uniforms);
|
|
1970
|
-
this.setNeedsRedraw("moduleSettings");
|
|
1971
|
-
}
|
|
1972
|
-
// Internal methods
|
|
2296
|
+
// INTERNAL METHODS
|
|
1973
2297
|
/** Check that bindings are loaded. Returns id of first binding that is still loading. */
|
|
1974
2298
|
_areBindingsLoading() {
|
|
1975
2299
|
for (const binding of Object.values(this.bindings)) {
|
|
@@ -1997,16 +2321,16 @@ var __exports__ = (() => {
|
|
|
1997
2321
|
_getBindingsUpdateTimestamp() {
|
|
1998
2322
|
let timestamp = 0;
|
|
1999
2323
|
for (const binding of Object.values(this.bindings)) {
|
|
2000
|
-
if (binding instanceof
|
|
2324
|
+
if (binding instanceof import_core9.TextureView) {
|
|
2001
2325
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
2002
|
-
} else if (binding instanceof
|
|
2326
|
+
} else if (binding instanceof import_core9.Buffer || binding instanceof import_core9.Texture) {
|
|
2003
2327
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
2004
2328
|
} else if (binding instanceof AsyncTexture) {
|
|
2005
2329
|
timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
|
|
2006
2330
|
// The texture will become available in the future
|
|
2007
2331
|
Infinity
|
|
2008
2332
|
);
|
|
2009
|
-
} else if (!(binding instanceof
|
|
2333
|
+
} else if (!(binding instanceof import_core9.Sampler)) {
|
|
2010
2334
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
2011
2335
|
}
|
|
2012
2336
|
}
|
|
@@ -2041,7 +2365,7 @@ var __exports__ = (() => {
|
|
|
2041
2365
|
let prevShaderVs = null;
|
|
2042
2366
|
let prevShaderFs = null;
|
|
2043
2367
|
if (this.pipeline) {
|
|
2044
|
-
|
|
2368
|
+
import_core9.log.log(
|
|
2045
2369
|
1,
|
|
2046
2370
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
2047
2371
|
)();
|
|
@@ -2077,7 +2401,7 @@ var __exports__ = (() => {
|
|
|
2077
2401
|
vs: vs3,
|
|
2078
2402
|
fs: fs3
|
|
2079
2403
|
});
|
|
2080
|
-
this._attributeInfos = (0,
|
|
2404
|
+
this._attributeInfos = (0, import_core9.getAttributeInfosFromLayouts)(
|
|
2081
2405
|
this.pipeline.shaderLayout,
|
|
2082
2406
|
this.bufferLayout
|
|
2083
2407
|
);
|
|
@@ -2092,27 +2416,24 @@ var __exports__ = (() => {
|
|
|
2092
2416
|
_lastLogTime = 0;
|
|
2093
2417
|
_logOpen = false;
|
|
2094
2418
|
_logDrawCallStart() {
|
|
2095
|
-
const logDrawTimeout =
|
|
2096
|
-
if (
|
|
2419
|
+
const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
2420
|
+
if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
2097
2421
|
return;
|
|
2098
2422
|
}
|
|
2099
2423
|
this._lastLogTime = Date.now();
|
|
2100
2424
|
this._logOpen = true;
|
|
2101
|
-
|
|
2425
|
+
import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
|
|
2102
2426
|
}
|
|
2103
2427
|
_logDrawCallEnd() {
|
|
2104
2428
|
if (this._logOpen) {
|
|
2105
2429
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
2106
|
-
|
|
2430
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
|
|
2107
2431
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
2108
|
-
|
|
2109
|
-
uniformTable[name] = { value };
|
|
2110
|
-
}
|
|
2111
|
-
import_core7.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
2432
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
2112
2433
|
const attributeTable = this._getAttributeDebugTable();
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2434
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
|
|
2435
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, attributeTable)();
|
|
2436
|
+
import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
2116
2437
|
this._logOpen = false;
|
|
2117
2438
|
}
|
|
2118
2439
|
}
|
|
@@ -2141,7 +2462,7 @@ var __exports__ = (() => {
|
|
|
2141
2462
|
if (this.vertexArray.indexBuffer) {
|
|
2142
2463
|
const { indexBuffer } = this.vertexArray;
|
|
2143
2464
|
const values = indexBuffer.indexType === "uint32" ? new Uint32Array(indexBuffer.debugData) : new Uint16Array(indexBuffer.debugData);
|
|
2144
|
-
table
|
|
2465
|
+
table["indices"] = {
|
|
2145
2466
|
name: "indices",
|
|
2146
2467
|
type: indexBuffer.indexType,
|
|
2147
2468
|
values: values.toString()
|
|
@@ -2151,14 +2472,14 @@ var __exports__ = (() => {
|
|
|
2151
2472
|
}
|
|
2152
2473
|
// TODO - fix typing of luma data types
|
|
2153
2474
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
2154
|
-
const TypedArrayConstructor = (0,
|
|
2155
|
-
const typedArray = attribute instanceof
|
|
2475
|
+
const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
|
|
2476
|
+
const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
2156
2477
|
return typedArray.toString();
|
|
2157
2478
|
}
|
|
2158
2479
|
};
|
|
2159
2480
|
var Model = _Model;
|
|
2160
2481
|
__publicField(Model, "defaultProps", {
|
|
2161
|
-
...
|
|
2482
|
+
...import_core9.RenderPipeline.defaultProps,
|
|
2162
2483
|
source: void 0,
|
|
2163
2484
|
vs: null,
|
|
2164
2485
|
fs: null,
|
|
@@ -2167,7 +2488,6 @@ var __exports__ = (() => {
|
|
|
2167
2488
|
userData: {},
|
|
2168
2489
|
defines: {},
|
|
2169
2490
|
modules: [],
|
|
2170
|
-
moduleSettings: void 0,
|
|
2171
2491
|
geometry: null,
|
|
2172
2492
|
indexBuffer: null,
|
|
2173
2493
|
attributes: {},
|
|
@@ -2205,7 +2525,7 @@ var __exports__ = (() => {
|
|
|
2205
2525
|
}
|
|
2206
2526
|
|
|
2207
2527
|
// src/compute/buffer-transform.ts
|
|
2208
|
-
var
|
|
2528
|
+
var import_core10 = __toESM(require_core(), 1);
|
|
2209
2529
|
var import_shadertools3 = __toESM(require_shadertools(), 1);
|
|
2210
2530
|
var _BufferTransform = class {
|
|
2211
2531
|
device;
|
|
@@ -2267,7 +2587,7 @@ var __exports__ = (() => {
|
|
|
2267
2587
|
if (!result) {
|
|
2268
2588
|
throw new Error("BufferTransform#getBuffer");
|
|
2269
2589
|
}
|
|
2270
|
-
if (result instanceof
|
|
2590
|
+
if (result instanceof import_core10.Buffer) {
|
|
2271
2591
|
return result.readAsync();
|
|
2272
2592
|
}
|
|
2273
2593
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -2304,7 +2624,7 @@ var __exports__ = (() => {
|
|
|
2304
2624
|
mipmapFilter: "nearest"
|
|
2305
2625
|
});
|
|
2306
2626
|
this.model = new Model(this.device, {
|
|
2307
|
-
id: props.id || "texture-transform-model",
|
|
2627
|
+
id: props.id || uid("texture-transform-model"),
|
|
2308
2628
|
fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
|
|
2309
2629
|
input: props.targetTextureVarying,
|
|
2310
2630
|
inputChannels: props.targetTextureChannels,
|
|
@@ -2333,6 +2653,7 @@ var __exports__ = (() => {
|
|
|
2333
2653
|
const renderPass = this.device.beginRenderPass({ framebuffer, ...options });
|
|
2334
2654
|
this.model.draw(renderPass);
|
|
2335
2655
|
renderPass.end();
|
|
2656
|
+
this.device.submit();
|
|
2336
2657
|
}
|
|
2337
2658
|
getTargetTexture() {
|
|
2338
2659
|
const { targetTexture } = this.bindings[this.currentIndex];
|
|
@@ -2422,9 +2743,9 @@ var __exports__ = (() => {
|
|
|
2422
2743
|
this.attributes[attributeName] = attribute;
|
|
2423
2744
|
}
|
|
2424
2745
|
}
|
|
2425
|
-
if (this.indices && this.indices
|
|
2746
|
+
if (this.indices && this.indices["isIndexed"] !== void 0) {
|
|
2426
2747
|
this.indices = Object.assign({}, this.indices);
|
|
2427
|
-
delete this.indices
|
|
2748
|
+
delete this.indices["isIndexed"];
|
|
2428
2749
|
}
|
|
2429
2750
|
this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
|
|
2430
2751
|
}
|
|
@@ -2550,7 +2871,7 @@ ${props.source}` };
|
|
|
2550
2871
|
@group(0) @binding(1) var backgroundTextureSampler: sampler;
|
|
2551
2872
|
|
|
2552
2873
|
fn billboardTexture_getTextureUV(coordinates: vec2<f32>) -> vec2<f32> {
|
|
2553
|
-
let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0)
|
|
2874
|
+
let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0);
|
|
2554
2875
|
let texSize: vec2<f32> = vec2<f32>(f32(iTexSize.x), f32(iTexSize.y));
|
|
2555
2876
|
var position: vec2<f32> = coordinates.xy / texSize;
|
|
2556
2877
|
return position;
|
|
@@ -2572,7 +2893,7 @@ uniform sampler2D backgroundTexture;
|
|
|
2572
2893
|
out vec4 fragColor;
|
|
2573
2894
|
|
|
2574
2895
|
vec2 billboardTexture_getTextureUV() {
|
|
2575
|
-
ivec2 iTexSize =
|
|
2896
|
+
ivec2 iTexSize = textureSize(backgroundTexture, 0);
|
|
2576
2897
|
vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
|
|
2577
2898
|
vec2 position = gl_FragCoord.xy / texSize;
|
|
2578
2899
|
return position;
|
|
@@ -2592,18 +2913,20 @@ void main(void) {
|
|
|
2592
2913
|
fs: BACKGROUND_FS,
|
|
2593
2914
|
parameters: {
|
|
2594
2915
|
depthWriteEnabled: false,
|
|
2595
|
-
depthCompare: "always",
|
|
2596
2916
|
...props.blend ? {
|
|
2597
2917
|
blend: true,
|
|
2598
2918
|
blendColorOperation: "add",
|
|
2599
2919
|
blendAlphaOperation: "add",
|
|
2600
2920
|
blendColorSrcFactor: "one",
|
|
2601
|
-
blendColorDstFactor: "one-minus-src
|
|
2921
|
+
blendColorDstFactor: "one-minus-src",
|
|
2602
2922
|
blendAlphaSrcFactor: "one",
|
|
2603
2923
|
blendAlphaDstFactor: "one-minus-src-alpha"
|
|
2604
2924
|
} : {}
|
|
2605
2925
|
}
|
|
2606
2926
|
});
|
|
2927
|
+
if (!props.backgroundTexture) {
|
|
2928
|
+
throw new Error("BackgroundTextureModel requires a backgroundTexture prop");
|
|
2929
|
+
}
|
|
2607
2930
|
this.setTexture(props.backgroundTexture);
|
|
2608
2931
|
}
|
|
2609
2932
|
setTexture(backgroundTexture) {
|
|
@@ -4796,13 +5119,13 @@ void main(void) {
|
|
|
4796
5119
|
};
|
|
4797
5120
|
|
|
4798
5121
|
// src/scenegraph/group-node.ts
|
|
4799
|
-
var
|
|
5122
|
+
var import_core13 = __toESM(require_core(), 1);
|
|
4800
5123
|
var GroupNode = class extends ScenegraphNode {
|
|
4801
5124
|
children;
|
|
4802
5125
|
constructor(props = {}) {
|
|
4803
5126
|
props = Array.isArray(props) ? { children: props } : props;
|
|
4804
5127
|
const { children = [] } = props;
|
|
4805
|
-
|
|
5128
|
+
import_core13.log.assert(
|
|
4806
5129
|
children.every((child) => child instanceof ScenegraphNode),
|
|
4807
5130
|
"every child must an instance of ScenegraphNode"
|
|
4808
5131
|
);
|
|
@@ -6020,7 +6343,7 @@ void main(void) {
|
|
|
6020
6343
|
var import_shadertools5 = __toESM(require_shadertools(), 1);
|
|
6021
6344
|
|
|
6022
6345
|
// src/compute/swap.ts
|
|
6023
|
-
var
|
|
6346
|
+
var import_core15 = __toESM(require_core(), 1);
|
|
6024
6347
|
var Swap = class {
|
|
6025
6348
|
/** The current resource - usually the source for renders or computations */
|
|
6026
6349
|
current;
|
|
@@ -6048,14 +6371,18 @@ void main(void) {
|
|
|
6048
6371
|
let colorAttachments = props.colorAttachments?.map(
|
|
6049
6372
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
6050
6373
|
format: colorAttachment,
|
|
6051
|
-
usage:
|
|
6374
|
+
usage: import_core15.Texture.SAMPLE | import_core15.Texture.RENDER | import_core15.Texture.COPY_SRC | import_core15.Texture.COPY_DST,
|
|
6375
|
+
width: 1,
|
|
6376
|
+
height: 1
|
|
6052
6377
|
})
|
|
6053
6378
|
);
|
|
6054
6379
|
const current = device.createFramebuffer({ ...props, colorAttachments });
|
|
6055
6380
|
colorAttachments = props.colorAttachments?.map(
|
|
6056
6381
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
6057
6382
|
format: colorAttachment,
|
|
6058
|
-
usage:
|
|
6383
|
+
usage: import_core15.Texture.TEXTURE | import_core15.Texture.COPY_SRC | import_core15.Texture.COPY_DST | import_core15.Texture.RENDER_ATTACHMENT,
|
|
6384
|
+
width: 1,
|
|
6385
|
+
height: 1
|
|
6059
6386
|
})
|
|
6060
6387
|
);
|
|
6061
6388
|
const next = device.createFramebuffer({ ...props, colorAttachments });
|
|
@@ -6118,11 +6445,11 @@ void main(void) {
|
|
|
6118
6445
|
return (
|
|
6119
6446
|
/* wgsl */
|
|
6120
6447
|
`// Binding 0:1 is reserved for shader passes
|
|
6121
|
-
@group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
|
|
6448
|
+
// @group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
|
|
6122
6449
|
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
6123
6450
|
@group(0) @binding(2) var sampler: sampler;
|
|
6124
6451
|
|
|
6125
|
-
struct FragmentInputs
|
|
6452
|
+
struct FragmentInputs {
|
|
6126
6453
|
@location(0) fragUV: vec2f,
|
|
6127
6454
|
@location(1) fragPosition: vec4f,
|
|
6128
6455
|
@location(2) fragCoordinate: vec4f
|
|
@@ -6227,9 +6554,9 @@ void main() {
|
|
|
6227
6554
|
{}
|
|
6228
6555
|
);
|
|
6229
6556
|
this.shaderInputs = props.shaderInputs || new ShaderInputs(modules);
|
|
6230
|
-
const size = device.getCanvasContext().
|
|
6557
|
+
const size = device.getCanvasContext().getDrawingBufferSize();
|
|
6231
6558
|
this.swapFramebuffers = new SwapFramebuffers(device, {
|
|
6232
|
-
colorAttachments: [
|
|
6559
|
+
colorAttachments: [device.preferredColorFormat],
|
|
6233
6560
|
width: size[0],
|
|
6234
6561
|
height: size[1]
|
|
6235
6562
|
});
|
|
@@ -6283,7 +6610,13 @@ void main() {
|
|
|
6283
6610
|
if (!outputTexture) {
|
|
6284
6611
|
return false;
|
|
6285
6612
|
}
|
|
6286
|
-
const
|
|
6613
|
+
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilAttachment: false });
|
|
6614
|
+
const renderPass = this.device.beginRenderPass({
|
|
6615
|
+
id: "shader-pass-renderer-to-screen",
|
|
6616
|
+
framebuffer,
|
|
6617
|
+
clearColor: [0, 0, 0, 1],
|
|
6618
|
+
clearDepth: 1
|
|
6619
|
+
});
|
|
6287
6620
|
this.clipSpace.setBindings({ sourceTexture: outputTexture });
|
|
6288
6621
|
this.clipSpace.draw(renderPass);
|
|
6289
6622
|
renderPass.end();
|
|
@@ -6302,6 +6635,7 @@ void main() {
|
|
|
6302
6635
|
backgroundTexture: sourceTexture
|
|
6303
6636
|
});
|
|
6304
6637
|
const clearTexturePass = this.device.beginRenderPass({
|
|
6638
|
+
id: "shader-pass-renderer-clear-texture",
|
|
6305
6639
|
framebuffer: this.swapFramebuffers.current,
|
|
6306
6640
|
clearColor: [0, 0, 0, 1]
|
|
6307
6641
|
});
|
|
@@ -6320,6 +6654,7 @@ void main() {
|
|
|
6320
6654
|
// texSize: [sourceTextures.width, sourceTextures.height]
|
|
6321
6655
|
};
|
|
6322
6656
|
const renderPass = this.device.beginRenderPass({
|
|
6657
|
+
id: "shader-pass-renderer-run-pass",
|
|
6323
6658
|
framebuffer: this.swapFramebuffers.next,
|
|
6324
6659
|
clearColor: [0, 0, 0, 1],
|
|
6325
6660
|
clearDepth: 1
|
|
@@ -6368,8 +6703,7 @@ void main() {
|
|
|
6368
6703
|
fs: fs3,
|
|
6369
6704
|
modules: [shaderPass],
|
|
6370
6705
|
parameters: {
|
|
6371
|
-
depthWriteEnabled: false
|
|
6372
|
-
depthCompare: "always"
|
|
6706
|
+
depthWriteEnabled: false
|
|
6373
6707
|
}
|
|
6374
6708
|
});
|
|
6375
6709
|
}
|
|
@@ -6390,7 +6724,7 @@ void main() {
|
|
|
6390
6724
|
};
|
|
6391
6725
|
|
|
6392
6726
|
// src/compute/computation.ts
|
|
6393
|
-
var
|
|
6727
|
+
var import_core16 = __toESM(require_core(), 1);
|
|
6394
6728
|
var import_shadertools6 = __toESM(require_shadertools(), 1);
|
|
6395
6729
|
var LOG_DRAW_PRIORITY2 = 2;
|
|
6396
6730
|
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
@@ -6489,7 +6823,7 @@ void main() {
|
|
|
6489
6823
|
}
|
|
6490
6824
|
setShaderInputs(shaderInputs) {
|
|
6491
6825
|
this.shaderInputs = shaderInputs;
|
|
6492
|
-
this._uniformStore = new
|
|
6826
|
+
this._uniformStore = new import_core16.UniformStore(this.shaderInputs.modules);
|
|
6493
6827
|
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
6494
6828
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
6495
6829
|
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
@@ -6526,7 +6860,7 @@ void main() {
|
|
|
6526
6860
|
if (this._pipelineNeedsUpdate) {
|
|
6527
6861
|
let prevShader = null;
|
|
6528
6862
|
if (this.pipeline) {
|
|
6529
|
-
|
|
6863
|
+
import_core16.log.log(
|
|
6530
6864
|
1,
|
|
6531
6865
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
6532
6866
|
)();
|
|
@@ -6553,33 +6887,33 @@ void main() {
|
|
|
6553
6887
|
_lastLogTime = 0;
|
|
6554
6888
|
_logOpen = false;
|
|
6555
6889
|
_logDrawCallStart() {
|
|
6556
|
-
const logDrawTimeout =
|
|
6557
|
-
if (
|
|
6890
|
+
const logDrawTimeout = import_core16.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
6891
|
+
if (import_core16.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
6558
6892
|
return;
|
|
6559
6893
|
}
|
|
6560
6894
|
this._lastLogTime = Date.now();
|
|
6561
6895
|
this._logOpen = true;
|
|
6562
|
-
|
|
6896
|
+
import_core16.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core16.log.level <= 2 })();
|
|
6563
6897
|
}
|
|
6564
6898
|
_logDrawCallEnd() {
|
|
6565
6899
|
if (this._logOpen) {
|
|
6566
6900
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
6567
|
-
|
|
6568
|
-
|
|
6901
|
+
import_core16.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
6902
|
+
import_core16.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
6569
6903
|
this._logOpen = false;
|
|
6570
6904
|
}
|
|
6571
6905
|
}
|
|
6572
6906
|
_drawCount = 0;
|
|
6573
6907
|
// TODO - fix typing of luma data types
|
|
6574
6908
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
6575
|
-
const TypedArrayConstructor = (0,
|
|
6576
|
-
const typedArray = attribute instanceof
|
|
6909
|
+
const TypedArrayConstructor = (0, import_core16.getTypedArrayConstructor)(dataType);
|
|
6910
|
+
const typedArray = attribute instanceof import_core16.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
6577
6911
|
return typedArray.toString();
|
|
6578
6912
|
}
|
|
6579
6913
|
};
|
|
6580
6914
|
var Computation = _Computation;
|
|
6581
6915
|
__publicField(Computation, "defaultProps", {
|
|
6582
|
-
...
|
|
6916
|
+
...import_core16.ComputePipeline.defaultProps,
|
|
6583
6917
|
id: "unnamed",
|
|
6584
6918
|
handle: void 0,
|
|
6585
6919
|
userData: {},
|
|
@@ -6730,7 +7064,7 @@ uniform pickingUniforms {
|
|
|
6730
7064
|
/** Prepare for rendering picking colors */
|
|
6731
7065
|
beginRenderPass() {
|
|
6732
7066
|
const framebuffer = this.getFramebuffer();
|
|
6733
|
-
framebuffer.resize(this.device.getDefaultCanvasContext().
|
|
7067
|
+
framebuffer.resize(this.device.getDefaultCanvasContext().getDevicePixelSize());
|
|
6734
7068
|
this.props.shaderInputs?.setProps({ picking: { isActive: true } });
|
|
6735
7069
|
const pickingPass = this.device.beginRenderPass({
|
|
6736
7070
|
framebuffer,
|
|
@@ -6739,7 +7073,7 @@ uniform pickingUniforms {
|
|
|
6739
7073
|
});
|
|
6740
7074
|
return pickingPass;
|
|
6741
7075
|
}
|
|
6742
|
-
|
|
7076
|
+
async updatePickInfo(mousePosition) {
|
|
6743
7077
|
const framebuffer = this.getFramebuffer();
|
|
6744
7078
|
const [pickX, pickY] = this.getPickPosition(mousePosition);
|
|
6745
7079
|
const pixelData = this.device.readPixelsToArrayWebGL(framebuffer, {
|
|
@@ -7100,7 +7434,7 @@ vec4 picking_filterColor(vec4 color) {
|
|
|
7100
7434
|
/** Prepare for rendering picking colors */
|
|
7101
7435
|
beginRenderPass() {
|
|
7102
7436
|
const framebuffer = this.getFramebuffer();
|
|
7103
|
-
framebuffer.resize(this.device.getCanvasContext().
|
|
7437
|
+
framebuffer.resize(this.device.getCanvasContext().getDevicePixelSize());
|
|
7104
7438
|
this.shaderInputs.setProps({ picking: { isActive: true } });
|
|
7105
7439
|
const pickingPass = this.device.beginRenderPass({
|
|
7106
7440
|
framebuffer,
|