@luma.gl/engine 9.3.0-alpha.4 → 9.3.0-alpha.6
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/dist/animation-loop/animation-loop.d.ts +8 -4
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +70 -43
- package/dist/animation-loop/animation-loop.js.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +7 -1
- package/dist/animation-loop/make-animation-loop.js.map +1 -1
- package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
- package/dist/animation-loop/request-animation-frame.js +23 -6
- package/dist/animation-loop/request-animation-frame.js.map +1 -1
- package/dist/dist.dev.js +679 -927
- package/dist/dist.min.js +39 -240
- package/dist/dynamic-texture/dynamic-texture.d.ts +3 -3
- package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -1
- package/dist/dynamic-texture/dynamic-texture.js +170 -52
- package/dist/dynamic-texture/dynamic-texture.js.map +1 -1
- package/dist/dynamic-texture/texture-data.d.ts +4 -0
- package/dist/dynamic-texture/texture-data.d.ts.map +1 -1
- package/dist/dynamic-texture/texture-data.js +8 -0
- package/dist/dynamic-texture/texture-data.js.map +1 -1
- package/dist/factories/pipeline-factory.d.ts +7 -5
- package/dist/factories/pipeline-factory.d.ts.map +1 -1
- package/dist/factories/pipeline-factory.js +71 -36
- package/dist/factories/pipeline-factory.js.map +1 -1
- package/dist/factories/shader-factory.d.ts +0 -3
- package/dist/factories/shader-factory.d.ts.map +1 -1
- package/dist/factories/shader-factory.js +13 -19
- package/dist/factories/shader-factory.js.map +1 -1
- package/dist/geometries/cone-geometry.d.ts +3 -1
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js.map +1 -1
- package/dist/geometries/cylinder-geometry.d.ts +2 -1
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js.map +1 -1
- package/dist/index.cjs +683 -922
- package/dist/index.cjs.map +4 -4
- package/dist/model/model.d.ts +3 -1
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +11 -9
- 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 +10 -8
- package/dist/models/billboard-texture-model.js.map +1 -1
- package/dist/models/clip-space.js +7 -7
- package/dist/modules/picking/index-picking.d.ts +1 -1
- package/dist/modules/picking/index-picking.d.ts.map +1 -1
- package/dist/modules/picking/index-picking.js +0 -6
- package/dist/modules/picking/index-picking.js.map +1 -1
- package/dist/passes/get-fragment-shader.js +11 -30
- package/dist/passes/get-fragment-shader.js.map +1 -1
- package/dist/passes/shader-pass-renderer.d.ts +0 -2
- package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
- package/dist/passes/shader-pass-renderer.js +4 -31
- package/dist/passes/shader-pass-renderer.js.map +1 -1
- package/dist/scenegraph/group-node.d.ts +5 -0
- package/dist/scenegraph/group-node.d.ts.map +1 -1
- package/dist/scenegraph/group-node.js +12 -0
- package/dist/scenegraph/group-node.js.map +1 -1
- package/dist/scenegraph/model-node.d.ts +2 -2
- package/dist/scenegraph/model-node.d.ts.map +1 -1
- package/dist/scenegraph/model-node.js.map +1 -1
- package/dist/scenegraph/scenegraph-node.d.ts +1 -1
- package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
- package/dist/scenegraph/scenegraph-node.js +23 -15
- package/dist/scenegraph/scenegraph-node.js.map +1 -1
- package/package.json +2 -2
- package/src/animation-loop/animation-loop.ts +75 -46
- package/src/animation-loop/make-animation-loop.ts +13 -5
- package/src/animation-loop/request-animation-frame.ts +32 -6
- package/src/dynamic-texture/dynamic-texture.ts +226 -65
- package/src/dynamic-texture/texture-data.ts +14 -0
- package/src/factories/pipeline-factory.ts +87 -46
- package/src/factories/shader-factory.ts +16 -20
- package/src/geometries/cone-geometry.ts +6 -1
- package/src/geometries/cylinder-geometry.ts +5 -1
- package/src/model/model.ts +14 -10
- package/src/models/billboard-texture-model.ts +10 -8
- package/src/models/clip-space.ts +7 -7
- package/src/modules/picking/index-picking.ts +0 -6
- package/src/passes/get-fragment-shader.ts +11 -30
- package/src/passes/shader-pass-renderer.ts +4 -33
- package/src/scenegraph/group-node.ts +16 -0
- package/src/scenegraph/model-node.ts +2 -2
- package/src/scenegraph/scenegraph-node.ts +27 -16
- package/dist/dynamic-texture/mipmaps.d.ts +0 -6
- package/dist/dynamic-texture/mipmaps.d.ts.map +0 -1
- package/dist/dynamic-texture/mipmaps.js +0 -441
- package/dist/dynamic-texture/mipmaps.js.map +0 -1
- package/src/dynamic-texture/mipmaps.ts +0 -517
package/dist/dist.dev.js
CHANGED
|
@@ -281,10 +281,22 @@ var __exports__ = (() => {
|
|
|
281
281
|
|
|
282
282
|
// src/animation-loop/request-animation-frame.ts
|
|
283
283
|
function requestAnimationFramePolyfill(callback) {
|
|
284
|
-
|
|
284
|
+
const browserRequestAnimationFrame = typeof window !== "undefined" ? window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame : null;
|
|
285
|
+
if (browserRequestAnimationFrame) {
|
|
286
|
+
return browserRequestAnimationFrame.call(window, callback);
|
|
287
|
+
}
|
|
288
|
+
return setTimeout(
|
|
289
|
+
() => callback(typeof performance !== "undefined" ? performance.now() : Date.now()),
|
|
290
|
+
1e3 / 60
|
|
291
|
+
);
|
|
285
292
|
}
|
|
286
293
|
function cancelAnimationFramePolyfill(timerId) {
|
|
287
|
-
|
|
294
|
+
const browserCancelAnimationFrame = typeof window !== "undefined" ? window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame : null;
|
|
295
|
+
if (browserCancelAnimationFrame) {
|
|
296
|
+
browserCancelAnimationFrame.call(window, timerId);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
clearTimeout(timerId);
|
|
288
300
|
}
|
|
289
301
|
|
|
290
302
|
// ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
|
|
@@ -482,6 +494,7 @@ var __exports__ = (() => {
|
|
|
482
494
|
|
|
483
495
|
// src/animation-loop/animation-loop.ts
|
|
484
496
|
var statIdCounter = 0;
|
|
497
|
+
var ANIMATION_LOOP_STATS = "Animation Loop";
|
|
485
498
|
var _AnimationLoop = class {
|
|
486
499
|
device = null;
|
|
487
500
|
canvas = null;
|
|
@@ -489,6 +502,7 @@ var __exports__ = (() => {
|
|
|
489
502
|
animationProps = null;
|
|
490
503
|
timeline = null;
|
|
491
504
|
stats;
|
|
505
|
+
sharedStats;
|
|
492
506
|
cpuTime;
|
|
493
507
|
gpuTime;
|
|
494
508
|
frameRate;
|
|
@@ -501,7 +515,7 @@ var __exports__ = (() => {
|
|
|
501
515
|
_resolveNextFrame = null;
|
|
502
516
|
_cpuStartTime = 0;
|
|
503
517
|
_error = null;
|
|
504
|
-
|
|
518
|
+
_lastFrameTime = 0;
|
|
505
519
|
/*
|
|
506
520
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
507
521
|
*/
|
|
@@ -511,10 +525,12 @@ var __exports__ = (() => {
|
|
|
511
525
|
if (!props.device) {
|
|
512
526
|
throw new Error("No device provided");
|
|
513
527
|
}
|
|
514
|
-
this.stats = props.stats || new Stats({ id:
|
|
528
|
+
this.stats = props.stats || new Stats({ id: `animation-loop-${statIdCounter++}` });
|
|
529
|
+
this.sharedStats = import_core.luma.stats.get(ANIMATION_LOOP_STATS);
|
|
530
|
+
this.frameRate = this.stats.get("Frame Rate");
|
|
531
|
+
this.frameRate.setSampleSize(1);
|
|
515
532
|
this.cpuTime = this.stats.get("CPU Time");
|
|
516
533
|
this.gpuTime = this.stats.get("GPU Time");
|
|
517
|
-
this.frameRate = this.stats.get("Frame Rate");
|
|
518
534
|
this.setProps({ autoResizeViewport: props.autoResizeViewport });
|
|
519
535
|
this.start = this.start.bind(this);
|
|
520
536
|
this.stop = this.stop.bind(this);
|
|
@@ -524,6 +540,7 @@ var __exports__ = (() => {
|
|
|
524
540
|
destroy() {
|
|
525
541
|
this.stop();
|
|
526
542
|
this._setDisplay(null);
|
|
543
|
+
this.device?._disableDebugGPUTime();
|
|
527
544
|
}
|
|
528
545
|
/** @deprecated Use .destroy() */
|
|
529
546
|
delete() {
|
|
@@ -588,15 +605,16 @@ var __exports__ = (() => {
|
|
|
588
605
|
this._nextFramePromise = null;
|
|
589
606
|
this._resolveNextFrame = null;
|
|
590
607
|
this._running = false;
|
|
608
|
+
this._lastFrameTime = 0;
|
|
591
609
|
}
|
|
592
610
|
return this;
|
|
593
611
|
}
|
|
594
612
|
/** Explicitly draw a frame */
|
|
595
|
-
redraw() {
|
|
613
|
+
redraw(time) {
|
|
596
614
|
if (this.device?.isLost || this._error) {
|
|
597
615
|
return this;
|
|
598
616
|
}
|
|
599
|
-
this._beginFrameTimers();
|
|
617
|
+
this._beginFrameTimers(time);
|
|
600
618
|
this._setupFrame();
|
|
601
619
|
this._updateAnimationProps();
|
|
602
620
|
this._renderFrame(this._getAnimationProps());
|
|
@@ -643,6 +661,7 @@ var __exports__ = (() => {
|
|
|
643
661
|
this._initializeAnimationProps();
|
|
644
662
|
this._updateAnimationProps();
|
|
645
663
|
this._resizeViewport();
|
|
664
|
+
this.device?._enableDebugGPUTime();
|
|
646
665
|
}
|
|
647
666
|
_setDisplay(display) {
|
|
648
667
|
if (this.display) {
|
|
@@ -667,11 +686,11 @@ var __exports__ = (() => {
|
|
|
667
686
|
cancelAnimationFramePolyfill(this._animationFrameId);
|
|
668
687
|
this._animationFrameId = null;
|
|
669
688
|
}
|
|
670
|
-
_animationFrame() {
|
|
689
|
+
_animationFrame(time) {
|
|
671
690
|
if (!this._running) {
|
|
672
691
|
return;
|
|
673
692
|
}
|
|
674
|
-
this.redraw();
|
|
693
|
+
this.redraw(time);
|
|
675
694
|
this._requestAnimationFrame();
|
|
676
695
|
}
|
|
677
696
|
// Called on each frame, can be overridden to call onRender multiple times
|
|
@@ -785,14 +804,8 @@ var __exports__ = (() => {
|
|
|
785
804
|
if (!this.device) {
|
|
786
805
|
return { width: 1, height: 1, aspect: 1 };
|
|
787
806
|
}
|
|
788
|
-
const [width, height] = this.device
|
|
789
|
-
|
|
790
|
-
const canvas2 = this.device?.getDefaultCanvasContext().canvas;
|
|
791
|
-
if (canvas2 && canvas2.clientHeight) {
|
|
792
|
-
aspect = canvas2.clientWidth / canvas2.clientHeight;
|
|
793
|
-
} else if (width > 0 && height > 0) {
|
|
794
|
-
aspect = width / height;
|
|
795
|
-
}
|
|
807
|
+
const [width, height] = this.device.getDefaultCanvasContext().getDrawingBufferSize();
|
|
808
|
+
const aspect = width > 0 && height > 0 ? width / height : 1;
|
|
796
809
|
return { width, height, aspect };
|
|
797
810
|
}
|
|
798
811
|
/** @deprecated Default viewport setup */
|
|
@@ -808,13 +821,61 @@ var __exports__ = (() => {
|
|
|
808
821
|
);
|
|
809
822
|
}
|
|
810
823
|
}
|
|
811
|
-
_beginFrameTimers() {
|
|
812
|
-
|
|
813
|
-
this.
|
|
824
|
+
_beginFrameTimers(time) {
|
|
825
|
+
const now = time ?? (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
826
|
+
if (this._lastFrameTime) {
|
|
827
|
+
const frameTime = now - this._lastFrameTime;
|
|
828
|
+
if (frameTime > 0) {
|
|
829
|
+
this.frameRate.addTime(frameTime);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
this._lastFrameTime = now;
|
|
833
|
+
if (this.device?._isDebugGPUTimeEnabled()) {
|
|
834
|
+
this._consumeEncodedGpuTime();
|
|
835
|
+
}
|
|
814
836
|
this.cpuTime.timeStart();
|
|
815
837
|
}
|
|
816
838
|
_endFrameTimers() {
|
|
839
|
+
if (this.device?._isDebugGPUTimeEnabled()) {
|
|
840
|
+
this._consumeEncodedGpuTime();
|
|
841
|
+
}
|
|
817
842
|
this.cpuTime.timeEnd();
|
|
843
|
+
this._updateSharedStats();
|
|
844
|
+
}
|
|
845
|
+
_consumeEncodedGpuTime() {
|
|
846
|
+
if (!this.device) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const gpuTimeMs = this.device.commandEncoder._gpuTimeMs;
|
|
850
|
+
if (gpuTimeMs !== void 0) {
|
|
851
|
+
this.gpuTime.addTime(gpuTimeMs);
|
|
852
|
+
this.device.commandEncoder._gpuTimeMs = void 0;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
_updateSharedStats() {
|
|
856
|
+
if (this.stats === this.sharedStats) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
for (const name of Object.keys(this.sharedStats.stats)) {
|
|
860
|
+
if (!this.stats.stats[name]) {
|
|
861
|
+
delete this.sharedStats.stats[name];
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
this.stats.forEach((sourceStat) => {
|
|
865
|
+
const targetStat = this.sharedStats.get(sourceStat.name, sourceStat.type);
|
|
866
|
+
targetStat.sampleSize = sourceStat.sampleSize;
|
|
867
|
+
targetStat.time = sourceStat.time;
|
|
868
|
+
targetStat.count = sourceStat.count;
|
|
869
|
+
targetStat.samples = sourceStat.samples;
|
|
870
|
+
targetStat.lastTiming = sourceStat.lastTiming;
|
|
871
|
+
targetStat.lastSampleTime = sourceStat.lastSampleTime;
|
|
872
|
+
targetStat.lastSampleCount = sourceStat.lastSampleCount;
|
|
873
|
+
targetStat._count = sourceStat._count;
|
|
874
|
+
targetStat._time = sourceStat._time;
|
|
875
|
+
targetStat._samples = sourceStat._samples;
|
|
876
|
+
targetStat._startTime = sourceStat._startTime;
|
|
877
|
+
targetStat._timerPending = sourceStat._timerPending;
|
|
878
|
+
});
|
|
818
879
|
}
|
|
819
880
|
// Event handling
|
|
820
881
|
_startEventHandling() {
|
|
@@ -843,7 +904,7 @@ var __exports__ = (() => {
|
|
|
843
904
|
},
|
|
844
905
|
onError: (error) => console.error(error),
|
|
845
906
|
// eslint-disable-line no-console
|
|
846
|
-
stats:
|
|
907
|
+
stats: void 0,
|
|
847
908
|
// view parameters
|
|
848
909
|
autoResizeViewport: false
|
|
849
910
|
});
|
|
@@ -875,7 +936,10 @@ var __exports__ = (() => {
|
|
|
875
936
|
return animationLoop;
|
|
876
937
|
}
|
|
877
938
|
function setError(device, error) {
|
|
878
|
-
|
|
939
|
+
if (!device) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const canvas2 = device.getDefaultCanvasContext().canvas;
|
|
879
943
|
if (canvas2 instanceof HTMLCanvasElement) {
|
|
880
944
|
canvas2.style.overflow = "visible";
|
|
881
945
|
let errorDiv = document.getElementById("animation-loop-error");
|
|
@@ -892,6 +956,9 @@ var __exports__ = (() => {
|
|
|
892
956
|
}
|
|
893
957
|
}
|
|
894
958
|
function clearError(device) {
|
|
959
|
+
if (!device) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
895
962
|
const errorDiv = document.getElementById("animation-loop-error");
|
|
896
963
|
if (errorDiv) {
|
|
897
964
|
errorDiv.remove();
|
|
@@ -899,8 +966,8 @@ var __exports__ = (() => {
|
|
|
899
966
|
}
|
|
900
967
|
|
|
901
968
|
// src/model/model.ts
|
|
902
|
-
var
|
|
903
|
-
var
|
|
969
|
+
var import_core10 = __toESM(require_core(), 1);
|
|
970
|
+
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
904
971
|
|
|
905
972
|
// src/geometry/gpu-geometry.ts
|
|
906
973
|
var import_core3 = __toESM(require_core(), 1);
|
|
@@ -1019,13 +1086,11 @@ var __exports__ = (() => {
|
|
|
1019
1086
|
return moduleData.defaultPipelineFactory;
|
|
1020
1087
|
}
|
|
1021
1088
|
device;
|
|
1022
|
-
cachingEnabled;
|
|
1023
|
-
destroyPolicy;
|
|
1024
|
-
debug;
|
|
1025
1089
|
_hashCounter = 0;
|
|
1026
1090
|
_hashes = {};
|
|
1027
1091
|
_renderPipelineCache = {};
|
|
1028
1092
|
_computePipelineCache = {};
|
|
1093
|
+
_sharedRenderPipelineCache = {};
|
|
1029
1094
|
get [Symbol.toStringTag]() {
|
|
1030
1095
|
return "PipelineFactory";
|
|
1031
1096
|
}
|
|
@@ -1034,35 +1099,34 @@ var __exports__ = (() => {
|
|
|
1034
1099
|
}
|
|
1035
1100
|
constructor(device) {
|
|
1036
1101
|
this.device = device;
|
|
1037
|
-
this.cachingEnabled = device.props._cachePipelines;
|
|
1038
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1039
|
-
this.debug = device.props.debugFactories;
|
|
1040
1102
|
}
|
|
1041
1103
|
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1042
1104
|
createRenderPipeline(props) {
|
|
1043
|
-
if (!this.
|
|
1105
|
+
if (!this.device.props._cachePipelines) {
|
|
1044
1106
|
return this.device.createRenderPipeline(props);
|
|
1045
1107
|
}
|
|
1046
1108
|
const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
|
|
1047
1109
|
const cache = this._renderPipelineCache;
|
|
1048
1110
|
const hash = this._hashRenderPipeline(allProps);
|
|
1049
|
-
let pipeline = cache[hash]?.
|
|
1111
|
+
let pipeline = cache[hash]?.resource;
|
|
1050
1112
|
if (!pipeline) {
|
|
1113
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
1051
1114
|
pipeline = this.device.createRenderPipeline({
|
|
1052
1115
|
...allProps,
|
|
1053
|
-
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
|
|
1116
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
1117
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
1054
1118
|
});
|
|
1055
1119
|
pipeline.hash = hash;
|
|
1056
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
1057
|
-
if (this.
|
|
1120
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
1121
|
+
if (this.device.props.debugFactories) {
|
|
1058
1122
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1059
1123
|
}
|
|
1060
1124
|
} else {
|
|
1061
1125
|
cache[hash].useCount++;
|
|
1062
|
-
if (this.
|
|
1126
|
+
if (this.device.props.debugFactories) {
|
|
1063
1127
|
import_core4.log.log(
|
|
1064
1128
|
3,
|
|
1065
|
-
`${this}: ${cache[hash].
|
|
1129
|
+
`${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1066
1130
|
)();
|
|
1067
1131
|
}
|
|
1068
1132
|
}
|
|
@@ -1070,36 +1134,36 @@ var __exports__ = (() => {
|
|
|
1070
1134
|
}
|
|
1071
1135
|
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1072
1136
|
createComputePipeline(props) {
|
|
1073
|
-
if (!this.
|
|
1137
|
+
if (!this.device.props._cachePipelines) {
|
|
1074
1138
|
return this.device.createComputePipeline(props);
|
|
1075
1139
|
}
|
|
1076
1140
|
const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
|
|
1077
1141
|
const cache = this._computePipelineCache;
|
|
1078
1142
|
const hash = this._hashComputePipeline(allProps);
|
|
1079
|
-
let pipeline = cache[hash]?.
|
|
1143
|
+
let pipeline = cache[hash]?.resource;
|
|
1080
1144
|
if (!pipeline) {
|
|
1081
1145
|
pipeline = this.device.createComputePipeline({
|
|
1082
1146
|
...allProps,
|
|
1083
1147
|
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
1084
1148
|
});
|
|
1085
1149
|
pipeline.hash = hash;
|
|
1086
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
1087
|
-
if (this.
|
|
1150
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
1151
|
+
if (this.device.props.debugFactories) {
|
|
1088
1152
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1089
1153
|
}
|
|
1090
1154
|
} else {
|
|
1091
1155
|
cache[hash].useCount++;
|
|
1092
|
-
if (this.
|
|
1156
|
+
if (this.device.props.debugFactories) {
|
|
1093
1157
|
import_core4.log.log(
|
|
1094
1158
|
3,
|
|
1095
|
-
`${this}: ${cache[hash].
|
|
1159
|
+
`${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1096
1160
|
)();
|
|
1097
1161
|
}
|
|
1098
1162
|
}
|
|
1099
1163
|
return pipeline;
|
|
1100
1164
|
}
|
|
1101
1165
|
release(pipeline) {
|
|
1102
|
-
if (!this.
|
|
1166
|
+
if (!this.device.props._cachePipelines) {
|
|
1103
1167
|
pipeline.destroy();
|
|
1104
1168
|
return;
|
|
1105
1169
|
}
|
|
@@ -1108,28 +1172,55 @@ var __exports__ = (() => {
|
|
|
1108
1172
|
cache[hash].useCount--;
|
|
1109
1173
|
if (cache[hash].useCount === 0) {
|
|
1110
1174
|
this._destroyPipeline(pipeline);
|
|
1111
|
-
if (this.
|
|
1175
|
+
if (this.device.props.debugFactories) {
|
|
1112
1176
|
import_core4.log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
1113
1177
|
}
|
|
1114
1178
|
} else if (cache[hash].useCount < 0) {
|
|
1115
1179
|
import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
1116
1180
|
cache[hash].useCount = 0;
|
|
1117
|
-
} else if (this.
|
|
1181
|
+
} else if (this.device.props.debugFactories) {
|
|
1118
1182
|
import_core4.log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
1119
1183
|
}
|
|
1120
1184
|
}
|
|
1185
|
+
createSharedRenderPipeline(props) {
|
|
1186
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
1187
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1188
|
+
if (!sharedCacheItem) {
|
|
1189
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
1190
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
1191
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
1192
|
+
}
|
|
1193
|
+
sharedCacheItem.useCount++;
|
|
1194
|
+
return sharedCacheItem.resource;
|
|
1195
|
+
}
|
|
1196
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
1197
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
1201
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1202
|
+
if (!sharedCacheItem) {
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
sharedCacheItem.useCount--;
|
|
1206
|
+
if (sharedCacheItem.useCount === 0) {
|
|
1207
|
+
sharedCacheItem.resource.destroy();
|
|
1208
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1121
1211
|
// PRIVATE
|
|
1122
|
-
/** Destroy a cached pipeline, removing it from the cache
|
|
1212
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
1123
1213
|
_destroyPipeline(pipeline) {
|
|
1124
1214
|
const cache = this._getCache(pipeline);
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1215
|
+
if (!this.device.props._destroyPipelines) {
|
|
1216
|
+
return false;
|
|
1217
|
+
}
|
|
1218
|
+
delete cache[pipeline.hash];
|
|
1219
|
+
pipeline.destroy();
|
|
1220
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
1221
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
1132
1222
|
}
|
|
1223
|
+
return true;
|
|
1133
1224
|
}
|
|
1134
1225
|
/** Get the appropriate cache for the type of pipeline */
|
|
1135
1226
|
_getCache(pipeline) {
|
|
@@ -1158,24 +1249,35 @@ var __exports__ = (() => {
|
|
|
1158
1249
|
_hashRenderPipeline(props) {
|
|
1159
1250
|
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
1160
1251
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1161
|
-
const varyingHash =
|
|
1252
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
1162
1253
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
1163
1254
|
const { type } = this.device;
|
|
1164
1255
|
switch (type) {
|
|
1165
1256
|
case "webgl":
|
|
1166
|
-
|
|
1257
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1258
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}BL${bufferLayoutHash}`;
|
|
1167
1259
|
case "webgpu":
|
|
1168
1260
|
default:
|
|
1169
1261
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1170
1262
|
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
1171
1263
|
}
|
|
1172
1264
|
}
|
|
1265
|
+
_hashSharedRenderPipeline(props) {
|
|
1266
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
1267
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1268
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
1269
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
1270
|
+
}
|
|
1173
1271
|
_getHash(key) {
|
|
1174
1272
|
if (this._hashes[key] === void 0) {
|
|
1175
1273
|
this._hashes[key] = this._hashCounter++;
|
|
1176
1274
|
}
|
|
1177
1275
|
return this._hashes[key];
|
|
1178
1276
|
}
|
|
1277
|
+
_getWebGLVaryingHash(props) {
|
|
1278
|
+
const { varyings = [], bufferMode = null } = props;
|
|
1279
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
1280
|
+
}
|
|
1179
1281
|
};
|
|
1180
1282
|
var PipelineFactory = _PipelineFactory;
|
|
1181
1283
|
__publicField(PipelineFactory, "defaultProps", { ...import_core4.RenderPipeline.defaultProps });
|
|
@@ -1190,9 +1292,6 @@ var __exports__ = (() => {
|
|
|
1190
1292
|
return moduleData.defaultShaderFactory;
|
|
1191
1293
|
}
|
|
1192
1294
|
device;
|
|
1193
|
-
cachingEnabled;
|
|
1194
|
-
destroyPolicy;
|
|
1195
|
-
debug;
|
|
1196
1295
|
_cache = {};
|
|
1197
1296
|
get [Symbol.toStringTag]() {
|
|
1198
1297
|
return "ShaderFactory";
|
|
@@ -1203,40 +1302,37 @@ var __exports__ = (() => {
|
|
|
1203
1302
|
/** @internal */
|
|
1204
1303
|
constructor(device) {
|
|
1205
1304
|
this.device = device;
|
|
1206
|
-
this.cachingEnabled = device.props._cacheShaders;
|
|
1207
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1208
|
-
this.debug = true;
|
|
1209
1305
|
}
|
|
1210
1306
|
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
1211
1307
|
createShader(props) {
|
|
1212
|
-
if (!this.
|
|
1308
|
+
if (!this.device.props._cacheShaders) {
|
|
1213
1309
|
return this.device.createShader(props);
|
|
1214
1310
|
}
|
|
1215
1311
|
const key = this._hashShader(props);
|
|
1216
1312
|
let cacheEntry = this._cache[key];
|
|
1217
1313
|
if (!cacheEntry) {
|
|
1218
|
-
const
|
|
1314
|
+
const resource = this.device.createShader({
|
|
1219
1315
|
...props,
|
|
1220
1316
|
id: props.id ? `${props.id}-cached` : void 0
|
|
1221
1317
|
});
|
|
1222
|
-
this._cache[key] = cacheEntry = {
|
|
1223
|
-
if (this.
|
|
1224
|
-
import_core5.log.log(3, `${this}: Created new shader ${
|
|
1318
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
1319
|
+
if (this.device.props.debugFactories) {
|
|
1320
|
+
import_core5.log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
1225
1321
|
}
|
|
1226
1322
|
} else {
|
|
1227
1323
|
cacheEntry.useCount++;
|
|
1228
|
-
if (this.
|
|
1324
|
+
if (this.device.props.debugFactories) {
|
|
1229
1325
|
import_core5.log.log(
|
|
1230
1326
|
3,
|
|
1231
|
-
`${this}: Reusing shader ${cacheEntry.
|
|
1327
|
+
`${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`
|
|
1232
1328
|
)();
|
|
1233
1329
|
}
|
|
1234
1330
|
}
|
|
1235
|
-
return cacheEntry.
|
|
1331
|
+
return cacheEntry.resource;
|
|
1236
1332
|
}
|
|
1237
1333
|
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
1238
1334
|
release(shader) {
|
|
1239
|
-
if (!this.
|
|
1335
|
+
if (!this.device.props._cacheShaders) {
|
|
1240
1336
|
shader.destroy();
|
|
1241
1337
|
return;
|
|
1242
1338
|
}
|
|
@@ -1245,16 +1341,16 @@ var __exports__ = (() => {
|
|
|
1245
1341
|
if (cacheEntry) {
|
|
1246
1342
|
cacheEntry.useCount--;
|
|
1247
1343
|
if (cacheEntry.useCount === 0) {
|
|
1248
|
-
if (this.
|
|
1344
|
+
if (this.device.props._destroyShaders) {
|
|
1249
1345
|
delete this._cache[key];
|
|
1250
|
-
cacheEntry.
|
|
1251
|
-
if (this.
|
|
1346
|
+
cacheEntry.resource.destroy();
|
|
1347
|
+
if (this.device.props.debugFactories) {
|
|
1252
1348
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
1253
1349
|
}
|
|
1254
1350
|
}
|
|
1255
1351
|
} else if (cacheEntry.useCount < 0) {
|
|
1256
1352
|
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
1257
|
-
} else if (this.
|
|
1353
|
+
} else if (this.device.props.debugFactories) {
|
|
1258
1354
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
1259
1355
|
}
|
|
1260
1356
|
}
|
|
@@ -1574,7 +1670,7 @@ var __exports__ = (() => {
|
|
|
1574
1670
|
};
|
|
1575
1671
|
|
|
1576
1672
|
// src/dynamic-texture/dynamic-texture.ts
|
|
1577
|
-
var
|
|
1673
|
+
var import_core9 = __toESM(require_core(), 1);
|
|
1578
1674
|
|
|
1579
1675
|
// src/dynamic-texture/texture-data.ts
|
|
1580
1676
|
var import_core8 = __toESM(require_core(), 1);
|
|
@@ -1642,6 +1738,15 @@ var __exports__ = (() => {
|
|
|
1642
1738
|
function isTextureImageData(data) {
|
|
1643
1739
|
return typeof data === "object" && data !== null && "data" in data && "width" in data && "height" in data;
|
|
1644
1740
|
}
|
|
1741
|
+
function resolveTextureImageFormat(data) {
|
|
1742
|
+
const { textureFormat, format } = data;
|
|
1743
|
+
if (textureFormat && format && textureFormat !== format) {
|
|
1744
|
+
throw new Error(
|
|
1745
|
+
`Conflicting texture formats "${textureFormat}" and "${format}" provided for the same mip level`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return textureFormat ?? format;
|
|
1749
|
+
}
|
|
1645
1750
|
function getCubeFaceIndex(face) {
|
|
1646
1751
|
const idx = TEXTURE_CUBE_FACE_MAP[face];
|
|
1647
1752
|
if (idx === void 0)
|
|
@@ -1674,6 +1779,7 @@ var __exports__ = (() => {
|
|
|
1674
1779
|
subresources.push({
|
|
1675
1780
|
type: "texture-data",
|
|
1676
1781
|
data: imageData,
|
|
1782
|
+
textureFormat: resolveTextureImageFormat(imageData),
|
|
1677
1783
|
z,
|
|
1678
1784
|
mipLevel
|
|
1679
1785
|
});
|
|
@@ -1716,656 +1822,6 @@ var __exports__ = (() => {
|
|
|
1716
1822
|
return subresources;
|
|
1717
1823
|
}
|
|
1718
1824
|
|
|
1719
|
-
// src/dynamic-texture/mipmaps.ts
|
|
1720
|
-
var import_core10 = __toESM(require_core(), 1);
|
|
1721
|
-
|
|
1722
|
-
// src/compute/computation.ts
|
|
1723
|
-
var import_core9 = __toESM(require_core(), 1);
|
|
1724
|
-
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
1725
|
-
var LOG_DRAW_PRIORITY = 2;
|
|
1726
|
-
var LOG_DRAW_TIMEOUT = 1e4;
|
|
1727
|
-
var _Computation = class {
|
|
1728
|
-
device;
|
|
1729
|
-
id;
|
|
1730
|
-
pipelineFactory;
|
|
1731
|
-
shaderFactory;
|
|
1732
|
-
userData = {};
|
|
1733
|
-
/** Bindings (textures, samplers, uniform buffers) */
|
|
1734
|
-
bindings = {};
|
|
1735
|
-
/** The underlying GPU pipeline. */
|
|
1736
|
-
pipeline;
|
|
1737
|
-
/** Assembled compute shader source */
|
|
1738
|
-
source;
|
|
1739
|
-
/** the underlying compiled compute shader */
|
|
1740
|
-
// @ts-ignore Set in function called from constructor
|
|
1741
|
-
shader;
|
|
1742
|
-
/** ShaderInputs instance */
|
|
1743
|
-
shaderInputs;
|
|
1744
|
-
// @ts-ignore Set in function called from constructor
|
|
1745
|
-
_uniformStore;
|
|
1746
|
-
_pipelineNeedsUpdate = "newly created";
|
|
1747
|
-
_getModuleUniforms;
|
|
1748
|
-
props;
|
|
1749
|
-
_destroyed = false;
|
|
1750
|
-
constructor(device, props) {
|
|
1751
|
-
if (device.type !== "webgpu") {
|
|
1752
|
-
throw new Error("Computation is only supported in WebGPU");
|
|
1753
|
-
}
|
|
1754
|
-
this.props = { ..._Computation.defaultProps, ...props };
|
|
1755
|
-
props = this.props;
|
|
1756
|
-
this.id = props.id || uid("model");
|
|
1757
|
-
this.device = device;
|
|
1758
|
-
Object.assign(this.userData, props.userData);
|
|
1759
|
-
const moduleMap = Object.fromEntries(
|
|
1760
|
-
this.props.modules?.map((module) => [module.name, module]) || []
|
|
1761
|
-
);
|
|
1762
|
-
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
1763
|
-
this.setShaderInputs(this.shaderInputs);
|
|
1764
|
-
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
1765
|
-
const platformInfo = getPlatformInfo(device);
|
|
1766
|
-
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
1767
|
-
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
1768
|
-
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1769
|
-
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1770
|
-
platformInfo,
|
|
1771
|
-
...this.props,
|
|
1772
|
-
modules
|
|
1773
|
-
});
|
|
1774
|
-
this.source = source3;
|
|
1775
|
-
this._getModuleUniforms = getUniforms2;
|
|
1776
|
-
this.pipeline = this._updatePipeline();
|
|
1777
|
-
if (props.bindings) {
|
|
1778
|
-
this.setBindings(props.bindings);
|
|
1779
|
-
}
|
|
1780
|
-
Object.seal(this);
|
|
1781
|
-
}
|
|
1782
|
-
destroy() {
|
|
1783
|
-
if (this._destroyed)
|
|
1784
|
-
return;
|
|
1785
|
-
this.pipelineFactory.release(this.pipeline);
|
|
1786
|
-
this.shaderFactory.release(this.shader);
|
|
1787
|
-
this._uniformStore.destroy();
|
|
1788
|
-
this._destroyed = true;
|
|
1789
|
-
}
|
|
1790
|
-
// Draw call
|
|
1791
|
-
predraw() {
|
|
1792
|
-
this.updateShaderInputs();
|
|
1793
|
-
}
|
|
1794
|
-
dispatch(computePass, x, y, z) {
|
|
1795
|
-
try {
|
|
1796
|
-
this._logDrawCallStart();
|
|
1797
|
-
this.pipeline = this._updatePipeline();
|
|
1798
|
-
this.pipeline.setBindings(this.bindings);
|
|
1799
|
-
computePass.setPipeline(this.pipeline);
|
|
1800
|
-
computePass.setBindings([]);
|
|
1801
|
-
computePass.dispatch(x, y, z);
|
|
1802
|
-
} finally {
|
|
1803
|
-
this._logDrawCallEnd();
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
// Update fixed fields (can trigger pipeline rebuild)
|
|
1807
|
-
// Update dynamic fields
|
|
1808
|
-
/**
|
|
1809
|
-
* Updates the vertex count (used in draw calls)
|
|
1810
|
-
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
1811
|
-
*/
|
|
1812
|
-
setVertexCount(vertexCount) {
|
|
1813
|
-
}
|
|
1814
|
-
/**
|
|
1815
|
-
* Updates the instance count (used in draw calls)
|
|
1816
|
-
* @note Any attributes with stepMode=instance need to be at least this big
|
|
1817
|
-
*/
|
|
1818
|
-
setInstanceCount(instanceCount) {
|
|
1819
|
-
}
|
|
1820
|
-
setShaderInputs(shaderInputs) {
|
|
1821
|
-
this.shaderInputs = shaderInputs;
|
|
1822
|
-
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1823
|
-
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
1824
|
-
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1825
|
-
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
/**
|
|
1829
|
-
* Updates shader module settings (which results in uniforms being set)
|
|
1830
|
-
*/
|
|
1831
|
-
setShaderModuleProps(props) {
|
|
1832
|
-
const uniforms = this._getModuleUniforms(props);
|
|
1833
|
-
const keys = Object.keys(uniforms).filter((k) => {
|
|
1834
|
-
const uniform = uniforms[k];
|
|
1835
|
-
return !isNumericArray(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
1836
|
-
});
|
|
1837
|
-
const bindings = {};
|
|
1838
|
-
for (const k of keys) {
|
|
1839
|
-
bindings[k] = uniforms[k];
|
|
1840
|
-
delete uniforms[k];
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
updateShaderInputs() {
|
|
1844
|
-
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1845
|
-
}
|
|
1846
|
-
/**
|
|
1847
|
-
* Sets bindings (textures, samplers, uniform buffers)
|
|
1848
|
-
*/
|
|
1849
|
-
setBindings(bindings) {
|
|
1850
|
-
Object.assign(this.bindings, bindings);
|
|
1851
|
-
}
|
|
1852
|
-
_setPipelineNeedsUpdate(reason) {
|
|
1853
|
-
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
1854
|
-
}
|
|
1855
|
-
_updatePipeline() {
|
|
1856
|
-
if (this._pipelineNeedsUpdate) {
|
|
1857
|
-
let prevShader = null;
|
|
1858
|
-
if (this.pipeline) {
|
|
1859
|
-
import_core9.log.log(
|
|
1860
|
-
1,
|
|
1861
|
-
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
1862
|
-
)();
|
|
1863
|
-
prevShader = this.shader;
|
|
1864
|
-
}
|
|
1865
|
-
this._pipelineNeedsUpdate = false;
|
|
1866
|
-
this.shader = this.shaderFactory.createShader({
|
|
1867
|
-
id: `${this.id}-fragment`,
|
|
1868
|
-
stage: "compute",
|
|
1869
|
-
source: this.source,
|
|
1870
|
-
debugShaders: this.props.debugShaders
|
|
1871
|
-
});
|
|
1872
|
-
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
1873
|
-
...this.props,
|
|
1874
|
-
shader: this.shader
|
|
1875
|
-
});
|
|
1876
|
-
if (prevShader) {
|
|
1877
|
-
this.shaderFactory.release(prevShader);
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
return this.pipeline;
|
|
1881
|
-
}
|
|
1882
|
-
/** Throttle draw call logging */
|
|
1883
|
-
_lastLogTime = 0;
|
|
1884
|
-
_logOpen = false;
|
|
1885
|
-
_logDrawCallStart() {
|
|
1886
|
-
const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1887
|
-
if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1888
|
-
return;
|
|
1889
|
-
}
|
|
1890
|
-
this._lastLogTime = Date.now();
|
|
1891
|
-
this._logOpen = true;
|
|
1892
|
-
import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
|
|
1893
|
-
}
|
|
1894
|
-
_logDrawCallEnd() {
|
|
1895
|
-
if (this._logOpen) {
|
|
1896
|
-
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1897
|
-
import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1898
|
-
import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1899
|
-
this._logOpen = false;
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
_drawCount = 0;
|
|
1903
|
-
// TODO - fix typing of luma data types
|
|
1904
|
-
_getBufferOrConstantValues(attribute, dataType) {
|
|
1905
|
-
const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
|
|
1906
|
-
const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1907
|
-
return typedArray.toString();
|
|
1908
|
-
}
|
|
1909
|
-
};
|
|
1910
|
-
var Computation = _Computation;
|
|
1911
|
-
__publicField(Computation, "defaultProps", {
|
|
1912
|
-
...import_core9.ComputePipeline.defaultProps,
|
|
1913
|
-
id: "unnamed",
|
|
1914
|
-
handle: void 0,
|
|
1915
|
-
userData: {},
|
|
1916
|
-
source: "",
|
|
1917
|
-
modules: [],
|
|
1918
|
-
defines: {},
|
|
1919
|
-
bindings: void 0,
|
|
1920
|
-
shaderInputs: void 0,
|
|
1921
|
-
pipelineFactory: void 0,
|
|
1922
|
-
shaderFactory: void 0,
|
|
1923
|
-
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
1924
|
-
debugShaders: void 0
|
|
1925
|
-
});
|
|
1926
|
-
function getPlatformInfo(device) {
|
|
1927
|
-
return {
|
|
1928
|
-
type: device.type,
|
|
1929
|
-
shaderLanguage: device.info.shadingLanguage,
|
|
1930
|
-
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
1931
|
-
gpu: device.info.gpu,
|
|
1932
|
-
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
1933
|
-
features: device.features
|
|
1934
|
-
};
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
// src/dynamic-texture/mipmaps.ts
|
|
1938
|
-
var RENDER_DIMENSIONS = [
|
|
1939
|
-
"2d",
|
|
1940
|
-
"2d-array",
|
|
1941
|
-
"cube",
|
|
1942
|
-
"cube-array"
|
|
1943
|
-
];
|
|
1944
|
-
var WORKGROUP_SIZE = {
|
|
1945
|
-
x: 4,
|
|
1946
|
-
y: 4,
|
|
1947
|
-
z: 4
|
|
1948
|
-
};
|
|
1949
|
-
function generateMipmap(device, texture) {
|
|
1950
|
-
if (texture.mipLevels <= 1) {
|
|
1951
|
-
return;
|
|
1952
|
-
}
|
|
1953
|
-
if (device.type !== "webgpu") {
|
|
1954
|
-
throw new Error(
|
|
1955
|
-
`Cannot generate mipmaps on device type "${device.type}". Use generateMipmapsWebGL for WebGL devices.`
|
|
1956
|
-
);
|
|
1957
|
-
}
|
|
1958
|
-
if (texture.dimension === "3d") {
|
|
1959
|
-
generateMipmaps3D(device, texture);
|
|
1960
|
-
return;
|
|
1961
|
-
}
|
|
1962
|
-
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
1963
|
-
generateMipmapsRender(device, texture);
|
|
1964
|
-
return;
|
|
1965
|
-
}
|
|
1966
|
-
throw new Error(
|
|
1967
|
-
`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`
|
|
1968
|
-
);
|
|
1969
|
-
}
|
|
1970
|
-
function generateMipmapsRender(device, texture) {
|
|
1971
|
-
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1972
|
-
const colorAttachmentFormat = getColorAttachmentFormat(
|
|
1973
|
-
texture.format,
|
|
1974
|
-
"render",
|
|
1975
|
-
texture.dimension
|
|
1976
|
-
);
|
|
1977
|
-
const viewDimension = texture.dimension;
|
|
1978
|
-
const shader = getRenderMipmapWGSL(viewDimension);
|
|
1979
|
-
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
1980
|
-
const uniformValues = new Uint32Array(1);
|
|
1981
|
-
const uniformsBuffer = device.createBuffer({
|
|
1982
|
-
byteLength: 16,
|
|
1983
|
-
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1984
|
-
});
|
|
1985
|
-
const model = new Model(device, {
|
|
1986
|
-
source: shader,
|
|
1987
|
-
colorAttachmentFormats: [colorAttachmentFormat],
|
|
1988
|
-
topology: "triangle-list",
|
|
1989
|
-
vertexCount: 3,
|
|
1990
|
-
shaderLayout: {
|
|
1991
|
-
attributes: [],
|
|
1992
|
-
bindings: [
|
|
1993
|
-
{ type: "sampler", name: "sourceSampler", group: 0, location: 0 },
|
|
1994
|
-
{
|
|
1995
|
-
type: "texture",
|
|
1996
|
-
name: "sourceTexture",
|
|
1997
|
-
group: 0,
|
|
1998
|
-
location: 1,
|
|
1999
|
-
viewDimension,
|
|
2000
|
-
sampleType: "float"
|
|
2001
|
-
},
|
|
2002
|
-
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
2003
|
-
]
|
|
2004
|
-
},
|
|
2005
|
-
bindings: {
|
|
2006
|
-
sourceSampler: sampler,
|
|
2007
|
-
sourceTexture: texture,
|
|
2008
|
-
uniforms: uniformsBuffer
|
|
2009
|
-
}
|
|
2010
|
-
});
|
|
2011
|
-
let sourceWidth = texture.width;
|
|
2012
|
-
let sourceHeight = texture.height;
|
|
2013
|
-
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
2014
|
-
try {
|
|
2015
|
-
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
2016
|
-
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2017
|
-
const sourceMipLevel = baseMipLevel - 1;
|
|
2018
|
-
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2019
|
-
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2020
|
-
const sourceView = texture.createView({
|
|
2021
|
-
dimension: viewDimension,
|
|
2022
|
-
baseMipLevel: sourceMipLevel,
|
|
2023
|
-
mipLevelCount: 1,
|
|
2024
|
-
baseArrayLayer: 0,
|
|
2025
|
-
arrayLayerCount: texture.depth
|
|
2026
|
-
});
|
|
2027
|
-
model.setBindings({ sourceTexture: sourceView });
|
|
2028
|
-
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
2029
|
-
uniformValues[0] = baseArrayLayer;
|
|
2030
|
-
uniformsBuffer.write(uniformValues);
|
|
2031
|
-
const destinationView = texture.createView({
|
|
2032
|
-
dimension: "2d",
|
|
2033
|
-
baseMipLevel,
|
|
2034
|
-
mipLevelCount: 1,
|
|
2035
|
-
baseArrayLayer,
|
|
2036
|
-
arrayLayerCount: 1
|
|
2037
|
-
});
|
|
2038
|
-
const framebuffer = device.createFramebuffer({
|
|
2039
|
-
colorAttachments: [destinationView]
|
|
2040
|
-
});
|
|
2041
|
-
const renderPass = device.beginRenderPass({
|
|
2042
|
-
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
2043
|
-
framebuffer
|
|
2044
|
-
});
|
|
2045
|
-
renderPass.setParameters({
|
|
2046
|
-
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
2047
|
-
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
2048
|
-
});
|
|
2049
|
-
model.draw(renderPass);
|
|
2050
|
-
renderPass.end();
|
|
2051
|
-
device.submit();
|
|
2052
|
-
destinationView.destroy();
|
|
2053
|
-
framebuffer.destroy();
|
|
2054
|
-
}
|
|
2055
|
-
sourceView.destroy();
|
|
2056
|
-
sourceWidth = destinationWidth;
|
|
2057
|
-
sourceHeight = destinationHeight;
|
|
2058
|
-
}
|
|
2059
|
-
} finally {
|
|
2060
|
-
model.destroy();
|
|
2061
|
-
sampler.destroy();
|
|
2062
|
-
uniformsBuffer.destroy();
|
|
2063
|
-
}
|
|
2064
|
-
}
|
|
2065
|
-
function getColorAttachmentFormat(format, path, dimension) {
|
|
2066
|
-
if (import_core10.textureFormatDecoder.isColor(format)) {
|
|
2067
|
-
return format;
|
|
2068
|
-
}
|
|
2069
|
-
throw new Error(
|
|
2070
|
-
`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Only color textures can be used for this operation. Required capabilities: color. Actual capabilities: color=false.`
|
|
2071
|
-
);
|
|
2072
|
-
}
|
|
2073
|
-
function generateMipmaps3D(device, texture) {
|
|
2074
|
-
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2075
|
-
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
2076
|
-
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
2077
|
-
const uniformsBuffer = device.createBuffer({
|
|
2078
|
-
byteLength: 32,
|
|
2079
|
-
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
2080
|
-
});
|
|
2081
|
-
const uniformValues = new Uint32Array(8);
|
|
2082
|
-
let sourceWidth = texture.width;
|
|
2083
|
-
let sourceHeight = texture.height;
|
|
2084
|
-
let sourceDepth = texture.depth;
|
|
2085
|
-
try {
|
|
2086
|
-
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
2087
|
-
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2088
|
-
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2089
|
-
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2090
|
-
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
2091
|
-
uniformValues[0] = sourceWidth;
|
|
2092
|
-
uniformValues[1] = sourceHeight;
|
|
2093
|
-
uniformValues[2] = sourceDepth;
|
|
2094
|
-
uniformValues[3] = destinationWidth;
|
|
2095
|
-
uniformValues[4] = destinationHeight;
|
|
2096
|
-
uniformValues[5] = destinationDepth;
|
|
2097
|
-
uniformValues[6] = 0;
|
|
2098
|
-
uniformsBuffer.write(uniformValues);
|
|
2099
|
-
const sourceView = texture.createView({
|
|
2100
|
-
dimension: "3d",
|
|
2101
|
-
baseMipLevel: destinationMipLevel - 1,
|
|
2102
|
-
mipLevelCount: 1,
|
|
2103
|
-
baseArrayLayer: 0,
|
|
2104
|
-
arrayLayerCount: 1
|
|
2105
|
-
});
|
|
2106
|
-
const destinationView = texture.createView({
|
|
2107
|
-
dimension: "3d",
|
|
2108
|
-
baseMipLevel: destinationMipLevel,
|
|
2109
|
-
mipLevelCount: 1,
|
|
2110
|
-
baseArrayLayer: 0,
|
|
2111
|
-
arrayLayerCount: 1
|
|
2112
|
-
});
|
|
2113
|
-
const computation = new Computation(device, {
|
|
2114
|
-
source: shaderSource,
|
|
2115
|
-
shaderLayout: {
|
|
2116
|
-
bindings: [
|
|
2117
|
-
{
|
|
2118
|
-
type: "texture",
|
|
2119
|
-
name: "sourceTexture",
|
|
2120
|
-
group: 0,
|
|
2121
|
-
location: 0,
|
|
2122
|
-
viewDimension: "3d",
|
|
2123
|
-
sampleType: "float"
|
|
2124
|
-
},
|
|
2125
|
-
{
|
|
2126
|
-
type: "storage",
|
|
2127
|
-
name: "destinationTexture",
|
|
2128
|
-
group: 0,
|
|
2129
|
-
location: 1,
|
|
2130
|
-
format,
|
|
2131
|
-
viewDimension: "3d",
|
|
2132
|
-
access: "write-only"
|
|
2133
|
-
},
|
|
2134
|
-
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
2135
|
-
]
|
|
2136
|
-
},
|
|
2137
|
-
bindings: {
|
|
2138
|
-
sourceTexture: sourceView,
|
|
2139
|
-
destinationTexture: destinationView,
|
|
2140
|
-
uniforms: uniformsBuffer
|
|
2141
|
-
}
|
|
2142
|
-
});
|
|
2143
|
-
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
2144
|
-
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
2145
|
-
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
2146
|
-
const computePass = device.beginComputePass({});
|
|
2147
|
-
computation.dispatch(computePass, workgroupsX, workgroupsY, workgroupsZ);
|
|
2148
|
-
computePass.end();
|
|
2149
|
-
device.submit();
|
|
2150
|
-
computation.destroy();
|
|
2151
|
-
sourceView.destroy();
|
|
2152
|
-
destinationView.destroy();
|
|
2153
|
-
sourceWidth = destinationWidth;
|
|
2154
|
-
sourceHeight = destinationHeight;
|
|
2155
|
-
sourceDepth = destinationDepth;
|
|
2156
|
-
}
|
|
2157
|
-
} finally {
|
|
2158
|
-
uniformsBuffer.destroy();
|
|
2159
|
-
}
|
|
2160
|
-
}
|
|
2161
|
-
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
2162
|
-
const { format, dimension } = texture;
|
|
2163
|
-
const capabilities = device.getTextureFormatCapabilities(format);
|
|
2164
|
-
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
2165
|
-
if (missingCapabilities.length > 0) {
|
|
2166
|
-
const required = requiredCapabilities.join(" + ");
|
|
2167
|
-
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
2168
|
-
throw new Error(
|
|
2169
|
-
`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`
|
|
2170
|
-
);
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
function getSourceTextureType(dimension) {
|
|
2174
|
-
switch (dimension) {
|
|
2175
|
-
case "2d":
|
|
2176
|
-
return "texture_2d<f32>";
|
|
2177
|
-
case "2d-array":
|
|
2178
|
-
return "texture_2d_array<f32>";
|
|
2179
|
-
case "cube":
|
|
2180
|
-
return "texture_cube<f32>";
|
|
2181
|
-
case "cube-array":
|
|
2182
|
-
return "texture_cube_array<f32>";
|
|
2183
|
-
default:
|
|
2184
|
-
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
function getRenderMipmapWGSL(dimension) {
|
|
2188
|
-
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
2189
|
-
return `
|
|
2190
|
-
struct MipmapUniforms {
|
|
2191
|
-
sourceLayer: u32,
|
|
2192
|
-
};
|
|
2193
|
-
|
|
2194
|
-
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
2195
|
-
let unusedSourceLayer = uniforms.sourceLayer;
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
const faceMat = array(
|
|
2199
|
-
mat3x3f(
|
|
2200
|
-
0.0, 0.0, -2.0,
|
|
2201
|
-
0.0, -2.0, 0.0,
|
|
2202
|
-
1.0, 1.0, 1.0
|
|
2203
|
-
), // pos-x
|
|
2204
|
-
mat3x3f(
|
|
2205
|
-
0.0, 0.0, 2.0,
|
|
2206
|
-
0.0, -2.0, 0.0,
|
|
2207
|
-
-1.0, 1.0, -1.0
|
|
2208
|
-
), // neg-x
|
|
2209
|
-
mat3x3f(
|
|
2210
|
-
2.0, 0.0, 0.0,
|
|
2211
|
-
0.0, 0.0, 2.0,
|
|
2212
|
-
-1.0, 1.0, -1.0
|
|
2213
|
-
), // pos-y
|
|
2214
|
-
mat3x3f(
|
|
2215
|
-
2.0, 0.0, 0.0,
|
|
2216
|
-
0.0, 0.0, -2.0,
|
|
2217
|
-
-1.0, -1.0, 1.0
|
|
2218
|
-
), // neg-y
|
|
2219
|
-
mat3x3f(
|
|
2220
|
-
2.0, 0.0, 0.0,
|
|
2221
|
-
0.0, -2.0, 0.0,
|
|
2222
|
-
-1.0, 1.0, 1.0
|
|
2223
|
-
), // pos-z
|
|
2224
|
-
mat3x3f(
|
|
2225
|
-
-2.0, 0.0, 0.0,
|
|
2226
|
-
0.0, -2.0, 0.0,
|
|
2227
|
-
1.0, 1.0, -1.0
|
|
2228
|
-
) // neg-z
|
|
2229
|
-
);
|
|
2230
|
-
|
|
2231
|
-
struct FragmentInputs {
|
|
2232
|
-
@builtin(position) position: vec4f,
|
|
2233
|
-
@location(0) texcoord: vec2f
|
|
2234
|
-
};
|
|
2235
|
-
|
|
2236
|
-
struct VertexOutput {
|
|
2237
|
-
@builtin(position) position: vec4f,
|
|
2238
|
-
@location(0) texcoord: vec2f
|
|
2239
|
-
};
|
|
2240
|
-
|
|
2241
|
-
@group(0) @binding(0) var sourceSampler: sampler;
|
|
2242
|
-
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
2243
|
-
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2244
|
-
|
|
2245
|
-
@vertex
|
|
2246
|
-
fn vertexMain(
|
|
2247
|
-
@builtin(vertex_index) vertexIndex: u32
|
|
2248
|
-
) -> VertexOutput {
|
|
2249
|
-
const positions = array(
|
|
2250
|
-
vec2f(-1.0, -1.0),
|
|
2251
|
-
vec2f(-1.0, 3.0),
|
|
2252
|
-
vec2f( 3.0, -1.0)
|
|
2253
|
-
);
|
|
2254
|
-
|
|
2255
|
-
let xy = positions[vertexIndex];
|
|
2256
|
-
return VertexOutput(
|
|
2257
|
-
vec4f(xy, 0.0, 1.0),
|
|
2258
|
-
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
2259
|
-
);
|
|
2260
|
-
}
|
|
2261
|
-
|
|
2262
|
-
@fragment
|
|
2263
|
-
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2264
|
-
_touchUniform(uniforms);
|
|
2265
|
-
return ${sourceSnippet};
|
|
2266
|
-
}
|
|
2267
|
-
`;
|
|
2268
|
-
}
|
|
2269
|
-
function getRenderMipmapSampleSnippet(dimension) {
|
|
2270
|
-
const layer = "uniforms.sourceLayer";
|
|
2271
|
-
switch (dimension) {
|
|
2272
|
-
case "2d":
|
|
2273
|
-
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2274
|
-
case "2d-array":
|
|
2275
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2276
|
-
case "cube":
|
|
2277
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2278
|
-
case "cube-array":
|
|
2279
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2280
|
-
default:
|
|
2281
|
-
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2282
|
-
}
|
|
2283
|
-
}
|
|
2284
|
-
function get3DComputeMipmapWGSL(format) {
|
|
2285
|
-
return `
|
|
2286
|
-
struct MipmapUniforms {
|
|
2287
|
-
sourceWidth: u32,
|
|
2288
|
-
sourceHeight: u32,
|
|
2289
|
-
sourceDepth: u32,
|
|
2290
|
-
destinationWidth: u32,
|
|
2291
|
-
destinationHeight: u32,
|
|
2292
|
-
destinationDepth: u32,
|
|
2293
|
-
padding: u32,
|
|
2294
|
-
};
|
|
2295
|
-
|
|
2296
|
-
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2297
|
-
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2298
|
-
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2299
|
-
|
|
2300
|
-
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2301
|
-
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2302
|
-
if (
|
|
2303
|
-
id.x >= uniforms.destinationWidth ||
|
|
2304
|
-
id.y >= uniforms.destinationHeight ||
|
|
2305
|
-
id.z >= uniforms.destinationDepth
|
|
2306
|
-
) {
|
|
2307
|
-
return;
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
let sourceBase = id * 2u;
|
|
2311
|
-
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2312
|
-
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2313
|
-
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2314
|
-
|
|
2315
|
-
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2316
|
-
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2317
|
-
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2318
|
-
|
|
2319
|
-
var sum = textureLoad(
|
|
2320
|
-
sourceTexture,
|
|
2321
|
-
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2322
|
-
0
|
|
2323
|
-
);
|
|
2324
|
-
sum += textureLoad(
|
|
2325
|
-
sourceTexture,
|
|
2326
|
-
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2327
|
-
0
|
|
2328
|
-
);
|
|
2329
|
-
sum += textureLoad(
|
|
2330
|
-
sourceTexture,
|
|
2331
|
-
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2332
|
-
0
|
|
2333
|
-
);
|
|
2334
|
-
sum += textureLoad(
|
|
2335
|
-
sourceTexture,
|
|
2336
|
-
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2337
|
-
0
|
|
2338
|
-
);
|
|
2339
|
-
sum += textureLoad(
|
|
2340
|
-
sourceTexture,
|
|
2341
|
-
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2342
|
-
0
|
|
2343
|
-
);
|
|
2344
|
-
sum += textureLoad(
|
|
2345
|
-
sourceTexture,
|
|
2346
|
-
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2347
|
-
0
|
|
2348
|
-
);
|
|
2349
|
-
sum += textureLoad(
|
|
2350
|
-
sourceTexture,
|
|
2351
|
-
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2352
|
-
0
|
|
2353
|
-
);
|
|
2354
|
-
sum += textureLoad(
|
|
2355
|
-
sourceTexture,
|
|
2356
|
-
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2357
|
-
0
|
|
2358
|
-
);
|
|
2359
|
-
|
|
2360
|
-
textureStore(
|
|
2361
|
-
destinationTexture,
|
|
2362
|
-
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2363
|
-
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2364
|
-
);
|
|
2365
|
-
}
|
|
2366
|
-
`;
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
1825
|
// src/dynamic-texture/dynamic-texture.ts
|
|
2370
1826
|
var _DynamicTexture = class {
|
|
2371
1827
|
device;
|
|
@@ -2422,6 +1878,9 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2422
1878
|
try {
|
|
2423
1879
|
const propsWithSyncData = await this._loadAllData(originalPropsWithAsyncData);
|
|
2424
1880
|
this._checkNotDestroyed();
|
|
1881
|
+
const subresources = propsWithSyncData.data ? getTextureSubresources(propsWithSyncData) : [];
|
|
1882
|
+
const userProvidedFormat = "format" in originalPropsWithAsyncData && originalPropsWithAsyncData.format !== void 0;
|
|
1883
|
+
const userProvidedUsage = "usage" in originalPropsWithAsyncData && originalPropsWithAsyncData.usage !== void 0;
|
|
2425
1884
|
const deduceSize = () => {
|
|
2426
1885
|
if (this.props.width && this.props.height) {
|
|
2427
1886
|
return { width: this.props.width, height: this.props.height };
|
|
@@ -2436,54 +1895,44 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2436
1895
|
if (!size || size.width <= 0 || size.height <= 0) {
|
|
2437
1896
|
throw new Error(`${this} size could not be determined or was zero`);
|
|
2438
1897
|
}
|
|
1898
|
+
const textureData = analyzeTextureSubresources(this.device, subresources, size, {
|
|
1899
|
+
format: userProvidedFormat ? originalPropsWithAsyncData.format : void 0
|
|
1900
|
+
});
|
|
1901
|
+
const resolvedFormat = textureData.format ?? this.props.format;
|
|
2439
1902
|
const baseTextureProps = {
|
|
2440
1903
|
...this.props,
|
|
2441
1904
|
...size,
|
|
1905
|
+
format: resolvedFormat,
|
|
2442
1906
|
mipLevels: 1,
|
|
2443
1907
|
// temporary; updated below
|
|
2444
1908
|
data: void 0
|
|
2445
1909
|
};
|
|
2446
|
-
if (this.device.
|
|
2447
|
-
|
|
1910
|
+
if (this.device.isTextureFormatCompressed(resolvedFormat) && !userProvidedUsage) {
|
|
1911
|
+
baseTextureProps.usage = import_core9.Texture.SAMPLE | import_core9.Texture.COPY_DST;
|
|
1912
|
+
}
|
|
1913
|
+
const shouldGenerateMipmaps = this.props.mipmaps && !textureData.hasExplicitMipChain && !this.device.isTextureFormatCompressed(resolvedFormat);
|
|
1914
|
+
if (this.device.type === "webgpu" && shouldGenerateMipmaps) {
|
|
1915
|
+
const requiredUsage = this.props.dimension === "3d" ? import_core9.Texture.SAMPLE | import_core9.Texture.STORAGE | import_core9.Texture.COPY_DST | import_core9.Texture.COPY_SRC : import_core9.Texture.SAMPLE | import_core9.Texture.RENDER | import_core9.Texture.COPY_DST | import_core9.Texture.COPY_SRC;
|
|
2448
1916
|
baseTextureProps.usage |= requiredUsage;
|
|
2449
1917
|
}
|
|
2450
1918
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
2451
|
-
const desired = this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1919
|
+
const desired = textureData.hasExplicitMipChain ? textureData.mipLevels : this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
2452
1920
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
2453
1921
|
this._texture = this.device.createTexture(finalTextureProps);
|
|
2454
1922
|
this._sampler = this.texture.sampler;
|
|
2455
1923
|
this._view = this.texture.view;
|
|
2456
|
-
if (
|
|
2457
|
-
|
|
2458
|
-
case "1d":
|
|
2459
|
-
this.setTexture1DData(propsWithSyncData.data);
|
|
2460
|
-
break;
|
|
2461
|
-
case "2d":
|
|
2462
|
-
this.setTexture2DData(propsWithSyncData.data);
|
|
2463
|
-
break;
|
|
2464
|
-
case "3d":
|
|
2465
|
-
this.setTexture3DData(propsWithSyncData.data);
|
|
2466
|
-
break;
|
|
2467
|
-
case "2d-array":
|
|
2468
|
-
this.setTextureArrayData(propsWithSyncData.data);
|
|
2469
|
-
break;
|
|
2470
|
-
case "cube":
|
|
2471
|
-
this.setTextureCubeData(propsWithSyncData.data);
|
|
2472
|
-
break;
|
|
2473
|
-
case "cube-array":
|
|
2474
|
-
this.setTextureCubeArrayData(propsWithSyncData.data);
|
|
2475
|
-
break;
|
|
2476
|
-
default: {
|
|
2477
|
-
throw new Error(`Unhandled dimension ${propsWithSyncData.dimension}`);
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
1924
|
+
if (textureData.subresources.length) {
|
|
1925
|
+
this._setTextureSubresources(textureData.subresources);
|
|
2480
1926
|
}
|
|
2481
|
-
if (this.props.mipmaps) {
|
|
1927
|
+
if (this.props.mipmaps && !textureData.hasExplicitMipChain && !shouldGenerateMipmaps) {
|
|
1928
|
+
import_core9.log.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)();
|
|
1929
|
+
}
|
|
1930
|
+
if (shouldGenerateMipmaps) {
|
|
2482
1931
|
this.generateMipmaps();
|
|
2483
1932
|
}
|
|
2484
1933
|
this.isReady = true;
|
|
2485
1934
|
this.resolveReady(this.texture);
|
|
2486
|
-
|
|
1935
|
+
import_core9.log.info(0, `${this} created`)();
|
|
2487
1936
|
} catch (e) {
|
|
2488
1937
|
const err = e instanceof Error ? e : new Error(String(e));
|
|
2489
1938
|
this.rejectReady(err);
|
|
@@ -2503,15 +1952,15 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2503
1952
|
if (this.device.type === "webgl") {
|
|
2504
1953
|
this.texture.generateMipmapsWebGL();
|
|
2505
1954
|
} else if (this.device.type === "webgpu") {
|
|
2506
|
-
|
|
1955
|
+
this.device.generateMipmapsWebGPU(this.texture);
|
|
2507
1956
|
} else {
|
|
2508
|
-
|
|
1957
|
+
import_core9.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
2509
1958
|
}
|
|
2510
1959
|
}
|
|
2511
1960
|
/** Set sampler or create one from props */
|
|
2512
1961
|
setSampler(sampler = {}) {
|
|
2513
1962
|
this._checkReady();
|
|
2514
|
-
const s = sampler instanceof
|
|
1963
|
+
const s = sampler instanceof import_core9.Sampler ? sampler : this.device.createSampler(sampler);
|
|
2515
1964
|
this.texture.setSampler(s);
|
|
2516
1965
|
this._sampler = s;
|
|
2517
1966
|
}
|
|
@@ -2529,7 +1978,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2529
1978
|
this._sampler = this.texture.sampler;
|
|
2530
1979
|
this._view = this.texture.view;
|
|
2531
1980
|
prev.destroy();
|
|
2532
|
-
|
|
1981
|
+
import_core9.log.info(`${this} resized`);
|
|
2533
1982
|
return true;
|
|
2534
1983
|
}
|
|
2535
1984
|
/** Convert cube face label to texture slice index. Index can be used with `setTexture2DData()`. */
|
|
@@ -2603,8 +2052,13 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2603
2052
|
this.texture.copyExternalImage({ image, z, mipLevel, flipY });
|
|
2604
2053
|
break;
|
|
2605
2054
|
case "texture-data":
|
|
2606
|
-
const { data } = subresource;
|
|
2607
|
-
this.texture.
|
|
2055
|
+
const { data, textureFormat } = subresource;
|
|
2056
|
+
if (textureFormat && textureFormat !== this.texture.format) {
|
|
2057
|
+
throw new Error(
|
|
2058
|
+
`${this} mip level ${mipLevel} uses format "${textureFormat}" but texture format is "${this.texture.format}"`
|
|
2059
|
+
);
|
|
2060
|
+
}
|
|
2061
|
+
this.texture.writeData(data.data, {
|
|
2608
2062
|
x: 0,
|
|
2609
2063
|
y: 0,
|
|
2610
2064
|
z,
|
|
@@ -2628,45 +2082,155 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2628
2082
|
}
|
|
2629
2083
|
_checkNotDestroyed() {
|
|
2630
2084
|
if (this.destroyed) {
|
|
2631
|
-
|
|
2085
|
+
import_core9.log.warn(`${this} already destroyed`);
|
|
2632
2086
|
}
|
|
2633
2087
|
}
|
|
2634
2088
|
_checkReady() {
|
|
2635
2089
|
if (!this.isReady) {
|
|
2636
|
-
|
|
2090
|
+
import_core9.log.warn(`${this} Cannot perform this operation before ready`);
|
|
2637
2091
|
}
|
|
2638
2092
|
}
|
|
2639
2093
|
};
|
|
2640
2094
|
var DynamicTexture = _DynamicTexture;
|
|
2641
2095
|
__publicField(DynamicTexture, "defaultProps", {
|
|
2642
|
-
...
|
|
2096
|
+
...import_core9.Texture.defaultProps,
|
|
2643
2097
|
dimension: "2d",
|
|
2644
2098
|
data: null,
|
|
2645
2099
|
mipmaps: false
|
|
2646
2100
|
});
|
|
2647
|
-
function
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2101
|
+
function getTextureSubresources(props) {
|
|
2102
|
+
if (!props.data) {
|
|
2103
|
+
return [];
|
|
2104
|
+
}
|
|
2105
|
+
switch (props.dimension) {
|
|
2106
|
+
case "1d":
|
|
2107
|
+
return getTexture1DSubresources(props.data);
|
|
2108
|
+
case "2d":
|
|
2109
|
+
return getTexture2DSubresources(0, props.data);
|
|
2110
|
+
case "3d":
|
|
2111
|
+
return getTexture3DSubresources(props.data);
|
|
2112
|
+
case "2d-array":
|
|
2113
|
+
return getTextureArraySubresources(props.data);
|
|
2114
|
+
case "cube":
|
|
2115
|
+
return getTextureCubeSubresources(props.data);
|
|
2116
|
+
case "cube-array":
|
|
2117
|
+
return getTextureCubeArraySubresources(props.data);
|
|
2118
|
+
default:
|
|
2119
|
+
throw new Error(`Unhandled dimension ${props.dimension}`);
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
function analyzeTextureSubresources(device, subresources, size, options) {
|
|
2123
|
+
if (subresources.length === 0) {
|
|
2124
|
+
return {
|
|
2125
|
+
subresources,
|
|
2126
|
+
mipLevels: 1,
|
|
2127
|
+
format: options.format,
|
|
2128
|
+
hasExplicitMipChain: false
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
const groupedSubresources = /* @__PURE__ */ new Map();
|
|
2132
|
+
for (const subresource of subresources) {
|
|
2133
|
+
const group = groupedSubresources.get(subresource.z) ?? [];
|
|
2134
|
+
group.push(subresource);
|
|
2135
|
+
groupedSubresources.set(subresource.z, group);
|
|
2136
|
+
}
|
|
2137
|
+
const hasExplicitMipChain = subresources.some((subresource) => subresource.mipLevel > 0);
|
|
2138
|
+
let resolvedFormat = options.format;
|
|
2139
|
+
let resolvedMipLevels = Number.POSITIVE_INFINITY;
|
|
2140
|
+
const validSubresources = [];
|
|
2141
|
+
for (const [z, sliceSubresources] of groupedSubresources) {
|
|
2142
|
+
const sortedSubresources = [...sliceSubresources].sort(
|
|
2143
|
+
(left, right) => left.mipLevel - right.mipLevel
|
|
2667
2144
|
);
|
|
2145
|
+
const baseLevel = sortedSubresources[0];
|
|
2146
|
+
if (!baseLevel || baseLevel.mipLevel !== 0) {
|
|
2147
|
+
throw new Error(`DynamicTexture: slice ${z} is missing mip level 0`);
|
|
2148
|
+
}
|
|
2149
|
+
const baseSize = getTextureSubresourceSize(device, baseLevel);
|
|
2150
|
+
if (baseSize.width !== size.width || baseSize.height !== size.height) {
|
|
2151
|
+
throw new Error(
|
|
2152
|
+
`DynamicTexture: slice ${z} base level dimensions ${baseSize.width}x${baseSize.height} do not match expected ${size.width}x${size.height}`
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
const baseFormat = getTextureSubresourceFormat(baseLevel);
|
|
2156
|
+
if (baseFormat) {
|
|
2157
|
+
if (resolvedFormat && resolvedFormat !== baseFormat) {
|
|
2158
|
+
throw new Error(
|
|
2159
|
+
`DynamicTexture: slice ${z} base level format "${baseFormat}" does not match texture format "${resolvedFormat}"`
|
|
2160
|
+
);
|
|
2161
|
+
}
|
|
2162
|
+
resolvedFormat = baseFormat;
|
|
2163
|
+
}
|
|
2164
|
+
const mipLevelLimit = resolvedFormat && device.isTextureFormatCompressed(resolvedFormat) ? (
|
|
2165
|
+
// Block-compressed formats cannot have mips smaller than a single compression block.
|
|
2166
|
+
getMaxCompressedMipLevels(device, baseSize.width, baseSize.height, resolvedFormat)
|
|
2167
|
+
) : device.getMipLevelCount(baseSize.width, baseSize.height);
|
|
2168
|
+
let validMipLevelsForSlice = 0;
|
|
2169
|
+
for (let expectedMipLevel = 0; expectedMipLevel < sortedSubresources.length; expectedMipLevel++) {
|
|
2170
|
+
const subresource = sortedSubresources[expectedMipLevel];
|
|
2171
|
+
if (!subresource || subresource.mipLevel !== expectedMipLevel) {
|
|
2172
|
+
break;
|
|
2173
|
+
}
|
|
2174
|
+
if (expectedMipLevel >= mipLevelLimit) {
|
|
2175
|
+
break;
|
|
2176
|
+
}
|
|
2177
|
+
const subresourceSize = getTextureSubresourceSize(device, subresource);
|
|
2178
|
+
const expectedWidth = Math.max(1, baseSize.width >> expectedMipLevel);
|
|
2179
|
+
const expectedHeight = Math.max(1, baseSize.height >> expectedMipLevel);
|
|
2180
|
+
if (subresourceSize.width !== expectedWidth || subresourceSize.height !== expectedHeight) {
|
|
2181
|
+
break;
|
|
2182
|
+
}
|
|
2183
|
+
const subresourceFormat = getTextureSubresourceFormat(subresource);
|
|
2184
|
+
if (subresourceFormat) {
|
|
2185
|
+
if (!resolvedFormat) {
|
|
2186
|
+
resolvedFormat = subresourceFormat;
|
|
2187
|
+
}
|
|
2188
|
+
if (subresourceFormat !== resolvedFormat) {
|
|
2189
|
+
break;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
validMipLevelsForSlice++;
|
|
2193
|
+
validSubresources.push(subresource);
|
|
2194
|
+
}
|
|
2195
|
+
resolvedMipLevels = Math.min(resolvedMipLevels, validMipLevelsForSlice);
|
|
2196
|
+
}
|
|
2197
|
+
const mipLevels = Number.isFinite(resolvedMipLevels) ? Math.max(1, resolvedMipLevels) : 1;
|
|
2198
|
+
return {
|
|
2199
|
+
// Keep every slice trimmed to the same mip count so the texture shape stays internally consistent.
|
|
2200
|
+
subresources: validSubresources.filter((subresource) => subresource.mipLevel < mipLevels),
|
|
2201
|
+
mipLevels,
|
|
2202
|
+
format: resolvedFormat,
|
|
2203
|
+
hasExplicitMipChain
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
function getTextureSubresourceFormat(subresource) {
|
|
2207
|
+
if (subresource.type !== "texture-data") {
|
|
2208
|
+
return void 0;
|
|
2209
|
+
}
|
|
2210
|
+
return subresource.textureFormat ?? resolveTextureImageFormat(subresource.data);
|
|
2211
|
+
}
|
|
2212
|
+
function getTextureSubresourceSize(device, subresource) {
|
|
2213
|
+
switch (subresource.type) {
|
|
2214
|
+
case "external-image":
|
|
2215
|
+
return device.getExternalImageSize(subresource.image);
|
|
2216
|
+
case "texture-data":
|
|
2217
|
+
return { width: subresource.data.width, height: subresource.data.height };
|
|
2218
|
+
default:
|
|
2219
|
+
throw new Error("Unsupported texture subresource");
|
|
2668
2220
|
}
|
|
2669
|
-
|
|
2221
|
+
}
|
|
2222
|
+
function getMaxCompressedMipLevels(device, baseWidth, baseHeight, format) {
|
|
2223
|
+
const { blockWidth = 1, blockHeight = 1 } = device.getTextureFormatInfo(format);
|
|
2224
|
+
let mipLevels = 1;
|
|
2225
|
+
for (let mipLevel = 1; ; mipLevel++) {
|
|
2226
|
+
const width = Math.max(1, baseWidth >> mipLevel);
|
|
2227
|
+
const height = Math.max(1, baseHeight >> mipLevel);
|
|
2228
|
+
if (width < blockWidth || height < blockHeight) {
|
|
2229
|
+
break;
|
|
2230
|
+
}
|
|
2231
|
+
mipLevels++;
|
|
2232
|
+
}
|
|
2233
|
+
return mipLevels;
|
|
2670
2234
|
}
|
|
2671
2235
|
async function awaitAllPromises(x) {
|
|
2672
2236
|
x = await x;
|
|
@@ -2687,8 +2251,8 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2687
2251
|
}
|
|
2688
2252
|
|
|
2689
2253
|
// src/model/model.ts
|
|
2690
|
-
var
|
|
2691
|
-
var
|
|
2254
|
+
var LOG_DRAW_PRIORITY = 2;
|
|
2255
|
+
var LOG_DRAW_TIMEOUT = 1e4;
|
|
2692
2256
|
var _Model = class {
|
|
2693
2257
|
/** Device that created this model */
|
|
2694
2258
|
device;
|
|
@@ -2771,7 +2335,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2771
2335
|
);
|
|
2772
2336
|
const shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap, { disableWarnings: this.props.disableWarnings });
|
|
2773
2337
|
this.setShaderInputs(shaderInputs);
|
|
2774
|
-
const platformInfo =
|
|
2338
|
+
const platformInfo = getPlatformInfo(device);
|
|
2775
2339
|
const modules = (
|
|
2776
2340
|
// @ts-ignore shaderInputs is assigned in setShaderInputs above.
|
|
2777
2341
|
(this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || []
|
|
@@ -2843,7 +2407,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2843
2407
|
if (!this._destroyed) {
|
|
2844
2408
|
this.pipelineFactory.release(this.pipeline);
|
|
2845
2409
|
this.shaderFactory.release(this.pipeline.vs);
|
|
2846
|
-
if (this.pipeline.fs) {
|
|
2410
|
+
if (this.pipeline.fs && this.pipeline.fs !== this.pipeline.vs) {
|
|
2847
2411
|
this.shaderFactory.release(this.pipeline.fs);
|
|
2848
2412
|
}
|
|
2849
2413
|
this._uniformStore.destroy();
|
|
@@ -2878,7 +2442,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2878
2442
|
draw(renderPass) {
|
|
2879
2443
|
const loadingBinding = this._areBindingsLoading();
|
|
2880
2444
|
if (loadingBinding) {
|
|
2881
|
-
|
|
2445
|
+
import_core10.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
2882
2446
|
return false;
|
|
2883
2447
|
}
|
|
2884
2448
|
try {
|
|
@@ -2893,9 +2457,6 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2893
2457
|
this._logDrawCallStart();
|
|
2894
2458
|
this.pipeline = this._updatePipeline();
|
|
2895
2459
|
const syncBindings = this._getBindings();
|
|
2896
|
-
this.pipeline.setBindings(syncBindings, {
|
|
2897
|
-
disableWarnings: this.props.disableWarnings
|
|
2898
|
-
});
|
|
2899
2460
|
const { indexBuffer } = this.vertexArray;
|
|
2900
2461
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
2901
2462
|
drawSuccess = this.pipeline.draw({
|
|
@@ -2906,6 +2467,11 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
2906
2467
|
instanceCount: this.instanceCount,
|
|
2907
2468
|
indexCount,
|
|
2908
2469
|
transformFeedback: this.transformFeedback || void 0,
|
|
2470
|
+
// Pipelines may be shared across models when caching is enabled, so bindings
|
|
2471
|
+
// and WebGL uniforms must be supplied on every draw instead of being stored
|
|
2472
|
+
// on the pipeline instance.
|
|
2473
|
+
bindings: syncBindings,
|
|
2474
|
+
uniforms: this.props.uniforms,
|
|
2909
2475
|
// WebGL shares underlying cached pipelines even for models that have different parameters and topology,
|
|
2910
2476
|
// so we must provide our unique parameters to each draw
|
|
2911
2477
|
// (In WebGPU most parameters are encoded in the pipeline and cannot be changed per draw call)
|
|
@@ -3008,7 +2574,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3008
2574
|
/** Set the shader inputs */
|
|
3009
2575
|
setShaderInputs(shaderInputs) {
|
|
3010
2576
|
this.shaderInputs = shaderInputs;
|
|
3011
|
-
this._uniformStore = new
|
|
2577
|
+
this._uniformStore = new import_core10.UniformStore(this.shaderInputs.modules);
|
|
3012
2578
|
for (const [moduleName, module] of Object.entries(this.shaderInputs.modules)) {
|
|
3013
2579
|
if (shaderModuleHasUniforms(module)) {
|
|
3014
2580
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
@@ -3052,7 +2618,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3052
2618
|
setAttributes(buffers, options) {
|
|
3053
2619
|
const disableWarnings = options?.disableWarnings ?? this.props.disableWarnings;
|
|
3054
2620
|
if (buffers["indices"]) {
|
|
3055
|
-
|
|
2621
|
+
import_core10.log.warn(
|
|
3056
2622
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
3057
2623
|
)();
|
|
3058
2624
|
}
|
|
@@ -3065,7 +2631,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3065
2631
|
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
3066
2632
|
if (!bufferLayout) {
|
|
3067
2633
|
if (!disableWarnings) {
|
|
3068
|
-
|
|
2634
|
+
import_core10.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
3069
2635
|
}
|
|
3070
2636
|
continue;
|
|
3071
2637
|
}
|
|
@@ -3080,7 +2646,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3080
2646
|
}
|
|
3081
2647
|
}
|
|
3082
2648
|
if (!set && !disableWarnings) {
|
|
3083
|
-
|
|
2649
|
+
import_core10.log.warn(
|
|
3084
2650
|
`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
|
|
3085
2651
|
)();
|
|
3086
2652
|
}
|
|
@@ -3101,7 +2667,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3101
2667
|
if (attributeInfo) {
|
|
3102
2668
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
3103
2669
|
} else if (!(options?.disableWarnings ?? this.props.disableWarnings)) {
|
|
3104
|
-
|
|
2670
|
+
import_core10.log.warn(
|
|
3105
2671
|
`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`
|
|
3106
2672
|
)();
|
|
3107
2673
|
}
|
|
@@ -3136,16 +2702,16 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3136
2702
|
_getBindingsUpdateTimestamp() {
|
|
3137
2703
|
let timestamp = 0;
|
|
3138
2704
|
for (const binding of Object.values(this.bindings)) {
|
|
3139
|
-
if (binding instanceof
|
|
2705
|
+
if (binding instanceof import_core10.TextureView) {
|
|
3140
2706
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
3141
|
-
} else if (binding instanceof
|
|
2707
|
+
} else if (binding instanceof import_core10.Buffer || binding instanceof import_core10.Texture) {
|
|
3142
2708
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
3143
2709
|
} else if (binding instanceof DynamicTexture) {
|
|
3144
2710
|
timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
|
|
3145
2711
|
// The texture will become available in the future
|
|
3146
2712
|
Infinity
|
|
3147
2713
|
);
|
|
3148
|
-
} else if (!(binding instanceof
|
|
2714
|
+
} else if (!(binding instanceof import_core10.Sampler)) {
|
|
3149
2715
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
3150
2716
|
}
|
|
3151
2717
|
}
|
|
@@ -3180,7 +2746,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3180
2746
|
let prevShaderVs = null;
|
|
3181
2747
|
let prevShaderFs = null;
|
|
3182
2748
|
if (this.pipeline) {
|
|
3183
|
-
|
|
2749
|
+
import_core10.log.log(
|
|
3184
2750
|
1,
|
|
3185
2751
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
3186
2752
|
)();
|
|
@@ -3216,14 +2782,15 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3216
2782
|
vs: vs3,
|
|
3217
2783
|
fs: fs3
|
|
3218
2784
|
});
|
|
3219
|
-
this._attributeInfos = (0,
|
|
2785
|
+
this._attributeInfos = (0, import_core10.getAttributeInfosFromLayouts)(
|
|
3220
2786
|
this.pipeline.shaderLayout,
|
|
3221
2787
|
this.bufferLayout
|
|
3222
2788
|
);
|
|
3223
2789
|
if (prevShaderVs)
|
|
3224
2790
|
this.shaderFactory.release(prevShaderVs);
|
|
3225
|
-
if (prevShaderFs)
|
|
2791
|
+
if (prevShaderFs && prevShaderFs !== prevShaderVs) {
|
|
3226
2792
|
this.shaderFactory.release(prevShaderFs);
|
|
2793
|
+
}
|
|
3227
2794
|
}
|
|
3228
2795
|
return this.pipeline;
|
|
3229
2796
|
}
|
|
@@ -3231,24 +2798,24 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3231
2798
|
_lastLogTime = 0;
|
|
3232
2799
|
_logOpen = false;
|
|
3233
2800
|
_logDrawCallStart() {
|
|
3234
|
-
const logDrawTimeout =
|
|
3235
|
-
if (
|
|
2801
|
+
const logDrawTimeout = import_core10.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
2802
|
+
if (import_core10.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
3236
2803
|
return;
|
|
3237
2804
|
}
|
|
3238
2805
|
this._lastLogTime = Date.now();
|
|
3239
2806
|
this._logOpen = true;
|
|
3240
|
-
|
|
2807
|
+
import_core10.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core10.log.level <= 2 })();
|
|
3241
2808
|
}
|
|
3242
2809
|
_logDrawCallEnd() {
|
|
3243
2810
|
if (this._logOpen) {
|
|
3244
2811
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
3245
|
-
|
|
2812
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
|
|
3246
2813
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
3247
|
-
|
|
2814
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
3248
2815
|
const attributeTable = this._getAttributeDebugTable();
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
2816
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
|
|
2817
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, attributeTable)();
|
|
2818
|
+
import_core10.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
3252
2819
|
this._logOpen = false;
|
|
3253
2820
|
}
|
|
3254
2821
|
}
|
|
@@ -3287,14 +2854,14 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3287
2854
|
}
|
|
3288
2855
|
// TODO - fix typing of luma data types
|
|
3289
2856
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
3290
|
-
const TypedArrayConstructor = (0,
|
|
3291
|
-
const typedArray = attribute instanceof
|
|
2857
|
+
const TypedArrayConstructor = (0, import_core10.getTypedArrayConstructor)(dataType);
|
|
2858
|
+
const typedArray = attribute instanceof import_core10.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
3292
2859
|
return typedArray.toString();
|
|
3293
2860
|
}
|
|
3294
2861
|
};
|
|
3295
2862
|
var Model = _Model;
|
|
3296
2863
|
__publicField(Model, "defaultProps", {
|
|
3297
|
-
...
|
|
2864
|
+
...import_core10.RenderPipeline.defaultProps,
|
|
3298
2865
|
source: void 0,
|
|
3299
2866
|
vs: null,
|
|
3300
2867
|
fs: null,
|
|
@@ -3307,6 +2874,8 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3307
2874
|
indexBuffer: null,
|
|
3308
2875
|
attributes: {},
|
|
3309
2876
|
constantAttributes: {},
|
|
2877
|
+
bindings: {},
|
|
2878
|
+
uniforms: {},
|
|
3310
2879
|
varyings: [],
|
|
3311
2880
|
isInstanced: void 0,
|
|
3312
2881
|
instanceCount: 0,
|
|
@@ -3315,14 +2884,14 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3315
2884
|
pipelineFactory: void 0,
|
|
3316
2885
|
shaderFactory: void 0,
|
|
3317
2886
|
transformFeedback: void 0,
|
|
3318
|
-
shaderAssembler:
|
|
2887
|
+
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
3319
2888
|
debugShaders: void 0,
|
|
3320
2889
|
disableWarnings: void 0
|
|
3321
2890
|
});
|
|
3322
2891
|
function shaderModuleHasUniforms(module) {
|
|
3323
2892
|
return Boolean(module.uniformTypes && !isObjectEmpty(module.uniformTypes));
|
|
3324
2893
|
}
|
|
3325
|
-
function
|
|
2894
|
+
function getPlatformInfo(device) {
|
|
3326
2895
|
return {
|
|
3327
2896
|
type: device.type,
|
|
3328
2897
|
shaderLanguage: device.info.shadingLanguage,
|
|
@@ -3340,8 +2909,8 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3340
2909
|
}
|
|
3341
2910
|
|
|
3342
2911
|
// src/compute/buffer-transform.ts
|
|
3343
|
-
var
|
|
3344
|
-
var
|
|
2912
|
+
var import_core11 = __toESM(require_core(), 1);
|
|
2913
|
+
var import_shadertools3 = __toESM(require_shadertools(), 1);
|
|
3345
2914
|
var _BufferTransform = class {
|
|
3346
2915
|
device;
|
|
3347
2916
|
model;
|
|
@@ -3356,7 +2925,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3356
2925
|
this.device = device;
|
|
3357
2926
|
this.model = new Model(this.device, {
|
|
3358
2927
|
id: props.id || "buffer-transform-model",
|
|
3359
|
-
fs: props.fs || (0,
|
|
2928
|
+
fs: props.fs || (0, import_shadertools3.getPassthroughFS)(),
|
|
3360
2929
|
topology: props.topology || "point-list",
|
|
3361
2930
|
varyings: props.outputs || props.varyings,
|
|
3362
2931
|
...props
|
|
@@ -3402,7 +2971,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3402
2971
|
if (!result) {
|
|
3403
2972
|
throw new Error("BufferTransform#getBuffer");
|
|
3404
2973
|
}
|
|
3405
|
-
if (result instanceof
|
|
2974
|
+
if (result instanceof import_core11.Buffer) {
|
|
3406
2975
|
return result.readAsync();
|
|
3407
2976
|
}
|
|
3408
2977
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -3417,7 +2986,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3417
2986
|
});
|
|
3418
2987
|
|
|
3419
2988
|
// src/compute/texture-transform.ts
|
|
3420
|
-
var
|
|
2989
|
+
var import_shadertools4 = __toESM(require_shadertools(), 1);
|
|
3421
2990
|
var FS_OUTPUT_VARIABLE = "transform_output";
|
|
3422
2991
|
var TextureTransform = class {
|
|
3423
2992
|
device;
|
|
@@ -3440,7 +3009,7 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3440
3009
|
});
|
|
3441
3010
|
this.model = new Model(this.device, {
|
|
3442
3011
|
id: props.id || uid("texture-transform-model"),
|
|
3443
|
-
fs: props.fs || (0,
|
|
3012
|
+
fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
|
|
3444
3013
|
input: props.targetTextureVarying,
|
|
3445
3014
|
inputChannels: props.targetTextureChannels,
|
|
3446
3015
|
output: FS_OUTPUT_VARIABLE
|
|
@@ -3611,9 +3180,9 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
|
3611
3180
|
var CLIPSPACE_VERTEX_SHADER_WGSL = (
|
|
3612
3181
|
/* wgsl */
|
|
3613
3182
|
`struct VertexInputs {
|
|
3614
|
-
@location(0)
|
|
3615
|
-
@location(1)
|
|
3616
|
-
@location(2)
|
|
3183
|
+
@location(0) clipSpacePositions: vec2<f32>,
|
|
3184
|
+
@location(1) texCoords: vec2<f32>,
|
|
3185
|
+
@location(2) coordinates: vec2<f32>
|
|
3617
3186
|
}
|
|
3618
3187
|
|
|
3619
3188
|
struct FragmentInputs {
|
|
@@ -3626,10 +3195,10 @@ struct FragmentInputs {
|
|
|
3626
3195
|
@vertex
|
|
3627
3196
|
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
3628
3197
|
var outputs: FragmentInputs;
|
|
3629
|
-
outputs.Position = vec4(inputs.
|
|
3630
|
-
outputs.position = inputs.
|
|
3631
|
-
outputs.coordinate = inputs.
|
|
3632
|
-
outputs.uv = inputs.
|
|
3198
|
+
outputs.Position = vec4(inputs.clipSpacePositions, 0., 1.);
|
|
3199
|
+
outputs.position = inputs.clipSpacePositions;
|
|
3200
|
+
outputs.coordinate = inputs.coordinates;
|
|
3201
|
+
outputs.uv = inputs.texCoords;
|
|
3633
3202
|
return outputs;
|
|
3634
3203
|
}
|
|
3635
3204
|
`
|
|
@@ -3695,15 +3264,15 @@ struct backgroundUniforms {
|
|
|
3695
3264
|
};
|
|
3696
3265
|
@group(0) @binding(2) var<uniform> background: backgroundUniforms;
|
|
3697
3266
|
|
|
3698
|
-
fn billboardTexture_getTextureUV(
|
|
3267
|
+
fn billboardTexture_getTextureUV(uv: vec2<f32>) -> vec2<f32> {
|
|
3699
3268
|
let scale: vec2<f32> = background.scale;
|
|
3700
|
-
var position: vec2<f32> = (
|
|
3269
|
+
var position: vec2<f32> = (uv - vec2<f32>(0.5, 0.5)) / scale + vec2<f32>(0.5, 0.5);
|
|
3701
3270
|
return position;
|
|
3702
3271
|
}
|
|
3703
3272
|
|
|
3704
3273
|
@fragment
|
|
3705
3274
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
3706
|
-
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.
|
|
3275
|
+
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.uv);
|
|
3707
3276
|
return textureSample(backgroundTexture, backgroundTextureSampler, position);
|
|
3708
3277
|
}
|
|
3709
3278
|
`
|
|
@@ -3737,20 +3306,22 @@ void main(void) {
|
|
|
3737
3306
|
backgroundTexture = null;
|
|
3738
3307
|
constructor(device, props) {
|
|
3739
3308
|
super(device, {
|
|
3309
|
+
...props,
|
|
3740
3310
|
id: props.id || "background-texture-model",
|
|
3741
3311
|
source: BACKGROUND_FS_WGSL,
|
|
3742
3312
|
fs: BACKGROUND_FS,
|
|
3743
|
-
modules: [backgroundModule],
|
|
3313
|
+
modules: [...props.modules || [], backgroundModule],
|
|
3744
3314
|
parameters: {
|
|
3745
3315
|
depthWriteEnabled: false,
|
|
3316
|
+
...props.parameters || {},
|
|
3746
3317
|
...props.blend ? {
|
|
3747
3318
|
blend: true,
|
|
3748
3319
|
blendColorOperation: "add",
|
|
3749
3320
|
blendAlphaOperation: "add",
|
|
3750
|
-
blendColorSrcFactor: "one",
|
|
3751
|
-
blendColorDstFactor: "one
|
|
3752
|
-
blendAlphaSrcFactor: "one",
|
|
3753
|
-
blendAlphaDstFactor: "one
|
|
3321
|
+
blendColorSrcFactor: "one-minus-dst-alpha",
|
|
3322
|
+
blendColorDstFactor: "one",
|
|
3323
|
+
blendAlphaSrcFactor: "one-minus-dst-alpha",
|
|
3324
|
+
blendAlphaDstFactor: "one"
|
|
3754
3325
|
} : {}
|
|
3755
3326
|
}
|
|
3756
3327
|
});
|
|
@@ -5836,6 +5407,11 @@ void main(void) {
|
|
|
5836
5407
|
}
|
|
5837
5408
|
|
|
5838
5409
|
// src/scenegraph/scenegraph-node.ts
|
|
5410
|
+
function assert2(condition, message) {
|
|
5411
|
+
if (!condition) {
|
|
5412
|
+
throw new Error(message);
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5839
5415
|
var ScenegraphNode = class {
|
|
5840
5416
|
id;
|
|
5841
5417
|
matrix = new Matrix4();
|
|
@@ -5867,14 +5443,17 @@ void main(void) {
|
|
|
5867
5443
|
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
5868
5444
|
}
|
|
5869
5445
|
setPosition(position) {
|
|
5446
|
+
assert2(position.length === 3, "setPosition requires vector argument");
|
|
5870
5447
|
this.position = position;
|
|
5871
5448
|
return this;
|
|
5872
5449
|
}
|
|
5873
5450
|
setRotation(rotation) {
|
|
5451
|
+
assert2(rotation.length === 3 || rotation.length === 4, "setRotation requires vector argument");
|
|
5874
5452
|
this.rotation = rotation;
|
|
5875
5453
|
return this;
|
|
5876
5454
|
}
|
|
5877
5455
|
setScale(scale2) {
|
|
5456
|
+
assert2(scale2.length === 3, "setScale requires vector argument");
|
|
5878
5457
|
this.scale = scale2;
|
|
5879
5458
|
return this;
|
|
5880
5459
|
}
|
|
@@ -5902,17 +5481,18 @@ void main(void) {
|
|
|
5902
5481
|
return this;
|
|
5903
5482
|
}
|
|
5904
5483
|
updateMatrix() {
|
|
5905
|
-
const pos = this.position;
|
|
5906
|
-
const rot = this.rotation;
|
|
5907
|
-
const scale2 = this.scale;
|
|
5908
5484
|
this.matrix.identity();
|
|
5909
|
-
this.matrix.translate(
|
|
5910
|
-
this.
|
|
5911
|
-
|
|
5485
|
+
this.matrix.translate(this.position);
|
|
5486
|
+
if (this.rotation.length === 4) {
|
|
5487
|
+
const rotationMatrix = new Matrix4().fromQuaternion(this.rotation);
|
|
5488
|
+
this.matrix.multiplyRight(rotationMatrix);
|
|
5489
|
+
} else {
|
|
5490
|
+
this.matrix.rotateXYZ(this.rotation);
|
|
5491
|
+
}
|
|
5492
|
+
this.matrix.scale(this.scale);
|
|
5912
5493
|
return this;
|
|
5913
5494
|
}
|
|
5914
|
-
update(
|
|
5915
|
-
const { position, rotation, scale: scale2 } = options;
|
|
5495
|
+
update({ position, rotation, scale: scale2 } = {}) {
|
|
5916
5496
|
if (position) {
|
|
5917
5497
|
this.setPosition(position);
|
|
5918
5498
|
}
|
|
@@ -5962,16 +5542,17 @@ void main(void) {
|
|
|
5962
5542
|
}
|
|
5963
5543
|
*/
|
|
5964
5544
|
_setScenegraphNodeProps(props) {
|
|
5965
|
-
if (
|
|
5545
|
+
if (props?.position) {
|
|
5966
5546
|
this.setPosition(props.position);
|
|
5967
5547
|
}
|
|
5968
|
-
if (
|
|
5548
|
+
if (props?.rotation) {
|
|
5969
5549
|
this.setRotation(props.rotation);
|
|
5970
5550
|
}
|
|
5971
|
-
if (
|
|
5551
|
+
if (props?.scale) {
|
|
5972
5552
|
this.setScale(props.scale);
|
|
5973
5553
|
}
|
|
5974
|
-
|
|
5554
|
+
this.updateMatrix();
|
|
5555
|
+
if (props?.matrix) {
|
|
5975
5556
|
this.setMatrix(props.matrix);
|
|
5976
5557
|
}
|
|
5977
5558
|
Object.assign(this.props, props);
|
|
@@ -5979,13 +5560,13 @@ void main(void) {
|
|
|
5979
5560
|
};
|
|
5980
5561
|
|
|
5981
5562
|
// src/scenegraph/group-node.ts
|
|
5982
|
-
var
|
|
5563
|
+
var import_core14 = __toESM(require_core(), 1);
|
|
5983
5564
|
var GroupNode = class extends ScenegraphNode {
|
|
5984
5565
|
children;
|
|
5985
5566
|
constructor(props = {}) {
|
|
5986
5567
|
props = Array.isArray(props) ? { children: props } : props;
|
|
5987
5568
|
const { children = [] } = props;
|
|
5988
|
-
|
|
5569
|
+
import_core14.log.assert(
|
|
5989
5570
|
children.every((child) => child instanceof ScenegraphNode),
|
|
5990
5571
|
"every child must an instance of ScenegraphNode"
|
|
5991
5572
|
);
|
|
@@ -6058,6 +5639,17 @@ void main(void) {
|
|
|
6058
5639
|
}
|
|
6059
5640
|
}
|
|
6060
5641
|
}
|
|
5642
|
+
preorderTraversal(visitor, { worldMatrix = new Matrix4() } = {}) {
|
|
5643
|
+
const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
5644
|
+
visitor(this, { worldMatrix: modelMatrix });
|
|
5645
|
+
for (const child of this.children) {
|
|
5646
|
+
if (child instanceof GroupNode) {
|
|
5647
|
+
child.preorderTraversal(visitor, { worldMatrix: modelMatrix });
|
|
5648
|
+
} else {
|
|
5649
|
+
visitor(child, { worldMatrix: modelMatrix });
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
}
|
|
6061
5653
|
};
|
|
6062
5654
|
|
|
6063
5655
|
// src/scenegraph/model-node.ts
|
|
@@ -7226,10 +6818,10 @@ void main(void) {
|
|
|
7226
6818
|
}
|
|
7227
6819
|
|
|
7228
6820
|
// src/passes/shader-pass-renderer.ts
|
|
7229
|
-
var
|
|
6821
|
+
var import_shadertools5 = __toESM(require_shadertools(), 1);
|
|
7230
6822
|
|
|
7231
6823
|
// src/compute/swap.ts
|
|
7232
|
-
var
|
|
6824
|
+
var import_core16 = __toESM(require_core(), 1);
|
|
7233
6825
|
var Swap = class {
|
|
7234
6826
|
id;
|
|
7235
6827
|
/** The current resource - usually the source for renders or computations */
|
|
@@ -7261,7 +6853,7 @@ void main(void) {
|
|
|
7261
6853
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
7262
6854
|
id: `${props.id}-texture-0`,
|
|
7263
6855
|
format: colorAttachment,
|
|
7264
|
-
usage:
|
|
6856
|
+
usage: import_core16.Texture.SAMPLE | import_core16.Texture.RENDER | import_core16.Texture.COPY_SRC | import_core16.Texture.COPY_DST,
|
|
7265
6857
|
width,
|
|
7266
6858
|
height
|
|
7267
6859
|
})
|
|
@@ -7271,7 +6863,7 @@ void main(void) {
|
|
|
7271
6863
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
7272
6864
|
id: `${props.id}-texture-1`,
|
|
7273
6865
|
format: colorAttachment,
|
|
7274
|
-
usage:
|
|
6866
|
+
usage: import_core16.Texture.SAMPLE | import_core16.Texture.RENDER | import_core16.Texture.COPY_SRC | import_core16.Texture.COPY_DST,
|
|
7275
6867
|
width,
|
|
7276
6868
|
height
|
|
7277
6869
|
})
|
|
@@ -7335,26 +6927,16 @@ void main(void) {
|
|
|
7335
6927
|
function getFilterShaderWGSL(func) {
|
|
7336
6928
|
return (
|
|
7337
6929
|
/* wgsl */
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
7341
|
-
@group(0) @binding(2) var textureSampler: sampler;
|
|
7342
|
-
|
|
7343
|
-
// This needs to be aligned with
|
|
7344
|
-
// struct FragmentInputs {
|
|
7345
|
-
// @location(0) fragUV: vec2f,
|
|
7346
|
-
// @location(1) fragPosition: vec4f,
|
|
7347
|
-
// @location(2) fragCoordinate: vec4f
|
|
7348
|
-
// };
|
|
6930
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
6931
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
7349
6932
|
|
|
7350
6933
|
@fragment
|
|
7351
6934
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
7352
|
-
let
|
|
7353
|
-
let
|
|
7354
|
-
let texSize = vec2f(textureDimensions(texture, 0));
|
|
6935
|
+
let texCoord = inputs.coordinate;
|
|
6936
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
7355
6937
|
|
|
7356
|
-
var fragColor = textureSample(
|
|
7357
|
-
fragColor = ${func}(fragColor, texSize,
|
|
6938
|
+
var fragColor = textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
6939
|
+
fragColor = ${func}(fragColor, texSize, texCoord);
|
|
7358
6940
|
return fragColor;
|
|
7359
6941
|
}
|
|
7360
6942
|
`
|
|
@@ -7363,23 +6945,14 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
7363
6945
|
function getSamplerShaderWGSL(func) {
|
|
7364
6946
|
return (
|
|
7365
6947
|
/* wgsl */
|
|
7366
|
-
|
|
7367
|
-
@group(0) @binding(
|
|
7368
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
7369
|
-
@group(0) @binding(2) var sampler: sampler;
|
|
7370
|
-
|
|
7371
|
-
struct FragmentInputs = {
|
|
7372
|
-
@location(0) fragUV: vec2f,
|
|
7373
|
-
@location(1) fragPosition: vec4f,
|
|
7374
|
-
@location(2) fragCoordinate: vec4f
|
|
7375
|
-
};
|
|
6948
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
6949
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
7376
6950
|
|
|
7377
6951
|
@fragment
|
|
7378
6952
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
7379
|
-
let
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
return fragColor;
|
|
6953
|
+
let texCoord = inputs.coordinate;
|
|
6954
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
6955
|
+
return ${func}(sourceTexture, sourceTextureSampler, texSize, texCoord);
|
|
7383
6956
|
}
|
|
7384
6957
|
`
|
|
7385
6958
|
);
|
|
@@ -7438,12 +7011,10 @@ void main() {
|
|
|
7438
7011
|
shaderInputs;
|
|
7439
7012
|
passRenderers;
|
|
7440
7013
|
swapFramebuffers;
|
|
7441
|
-
/** For rendering to the screen */
|
|
7442
|
-
clipSpace;
|
|
7443
7014
|
textureModel;
|
|
7444
7015
|
constructor(device, props) {
|
|
7445
7016
|
this.device = device;
|
|
7446
|
-
props.shaderPasses.map((shaderPass) => (0,
|
|
7017
|
+
props.shaderPasses.map((shaderPass) => (0, import_shadertools5.initializeShaderModule)(shaderPass));
|
|
7447
7018
|
const modules = props.shaderPasses.reduce(
|
|
7448
7019
|
(object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }),
|
|
7449
7020
|
{}
|
|
@@ -7458,33 +7029,6 @@ void main() {
|
|
|
7458
7029
|
this.textureModel = new BackgroundTextureModel(device, {
|
|
7459
7030
|
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
7460
7031
|
});
|
|
7461
|
-
this.clipSpace = new ClipSpace(device, {
|
|
7462
|
-
source: (
|
|
7463
|
-
/* wgsl */
|
|
7464
|
-
` @group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
7465
|
-
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
7466
|
-
|
|
7467
|
-
@fragment
|
|
7468
|
-
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
7469
|
-
let texCoord: vec2<f32> = inputs.coordinate;
|
|
7470
|
-
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
7471
|
-
}
|
|
7472
|
-
`
|
|
7473
|
-
),
|
|
7474
|
-
fs: (
|
|
7475
|
-
/* glsl */
|
|
7476
|
-
`#version 300 es
|
|
7477
|
-
|
|
7478
|
-
uniform sampler2D sourceTexture;
|
|
7479
|
-
in vec2 uv;
|
|
7480
|
-
out vec4 fragColor;
|
|
7481
|
-
|
|
7482
|
-
void main() {
|
|
7483
|
-
fragColor = texture(sourceTexture, uv);
|
|
7484
|
-
}
|
|
7485
|
-
`
|
|
7486
|
-
)
|
|
7487
|
-
});
|
|
7488
7032
|
this.passRenderers = props.shaderPasses.map((shaderPass) => new PassRenderer(device, shaderPass));
|
|
7489
7033
|
}
|
|
7490
7034
|
/** Destroys resources created by this ShaderPassRenderer */
|
|
@@ -7493,7 +7037,6 @@ void main() {
|
|
|
7493
7037
|
subPassRenderer.destroy();
|
|
7494
7038
|
}
|
|
7495
7039
|
this.swapFramebuffers.destroy();
|
|
7496
|
-
this.clipSpace.destroy();
|
|
7497
7040
|
this.textureModel.destroy();
|
|
7498
7041
|
}
|
|
7499
7042
|
resize(size) {
|
|
@@ -7505,15 +7048,15 @@ void main() {
|
|
|
7505
7048
|
if (!outputTexture) {
|
|
7506
7049
|
return false;
|
|
7507
7050
|
}
|
|
7508
|
-
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({
|
|
7051
|
+
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilFormat: false });
|
|
7509
7052
|
const renderPass = this.device.beginRenderPass({
|
|
7510
7053
|
id: "shader-pass-renderer-to-screen",
|
|
7511
7054
|
framebuffer,
|
|
7512
7055
|
// clearColor: [1, 1, 0, 1],
|
|
7513
|
-
clearDepth:
|
|
7056
|
+
clearDepth: false
|
|
7514
7057
|
});
|
|
7515
|
-
this.
|
|
7516
|
-
this.
|
|
7058
|
+
this.textureModel.setProps({ backgroundTexture: outputTexture });
|
|
7059
|
+
this.textureModel.draw(renderPass);
|
|
7517
7060
|
renderPass.end();
|
|
7518
7061
|
return true;
|
|
7519
7062
|
}
|
|
@@ -7618,6 +7161,221 @@ void main() {
|
|
|
7618
7161
|
}
|
|
7619
7162
|
};
|
|
7620
7163
|
|
|
7164
|
+
// src/compute/computation.ts
|
|
7165
|
+
var import_core17 = __toESM(require_core(), 1);
|
|
7166
|
+
var import_shadertools6 = __toESM(require_shadertools(), 1);
|
|
7167
|
+
var LOG_DRAW_PRIORITY2 = 2;
|
|
7168
|
+
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
7169
|
+
var _Computation = class {
|
|
7170
|
+
device;
|
|
7171
|
+
id;
|
|
7172
|
+
pipelineFactory;
|
|
7173
|
+
shaderFactory;
|
|
7174
|
+
userData = {};
|
|
7175
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
7176
|
+
bindings = {};
|
|
7177
|
+
/** The underlying GPU pipeline. */
|
|
7178
|
+
pipeline;
|
|
7179
|
+
/** Assembled compute shader source */
|
|
7180
|
+
source;
|
|
7181
|
+
/** the underlying compiled compute shader */
|
|
7182
|
+
// @ts-ignore Set in function called from constructor
|
|
7183
|
+
shader;
|
|
7184
|
+
/** ShaderInputs instance */
|
|
7185
|
+
shaderInputs;
|
|
7186
|
+
// @ts-ignore Set in function called from constructor
|
|
7187
|
+
_uniformStore;
|
|
7188
|
+
_pipelineNeedsUpdate = "newly created";
|
|
7189
|
+
_getModuleUniforms;
|
|
7190
|
+
props;
|
|
7191
|
+
_destroyed = false;
|
|
7192
|
+
constructor(device, props) {
|
|
7193
|
+
if (device.type !== "webgpu") {
|
|
7194
|
+
throw new Error("Computation is only supported in WebGPU");
|
|
7195
|
+
}
|
|
7196
|
+
this.props = { ..._Computation.defaultProps, ...props };
|
|
7197
|
+
props = this.props;
|
|
7198
|
+
this.id = props.id || uid("model");
|
|
7199
|
+
this.device = device;
|
|
7200
|
+
Object.assign(this.userData, props.userData);
|
|
7201
|
+
const moduleMap = Object.fromEntries(
|
|
7202
|
+
this.props.modules?.map((module) => [module.name, module]) || []
|
|
7203
|
+
);
|
|
7204
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
7205
|
+
this.setShaderInputs(this.shaderInputs);
|
|
7206
|
+
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
7207
|
+
const platformInfo = getPlatformInfo2(device);
|
|
7208
|
+
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
7209
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
7210
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
7211
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
7212
|
+
platformInfo,
|
|
7213
|
+
...this.props,
|
|
7214
|
+
modules
|
|
7215
|
+
});
|
|
7216
|
+
this.source = source3;
|
|
7217
|
+
this._getModuleUniforms = getUniforms2;
|
|
7218
|
+
this.pipeline = this._updatePipeline();
|
|
7219
|
+
if (props.bindings) {
|
|
7220
|
+
this.setBindings(props.bindings);
|
|
7221
|
+
}
|
|
7222
|
+
Object.seal(this);
|
|
7223
|
+
}
|
|
7224
|
+
destroy() {
|
|
7225
|
+
if (this._destroyed)
|
|
7226
|
+
return;
|
|
7227
|
+
this.pipelineFactory.release(this.pipeline);
|
|
7228
|
+
this.shaderFactory.release(this.shader);
|
|
7229
|
+
this._uniformStore.destroy();
|
|
7230
|
+
this._destroyed = true;
|
|
7231
|
+
}
|
|
7232
|
+
// Draw call
|
|
7233
|
+
predraw() {
|
|
7234
|
+
this.updateShaderInputs();
|
|
7235
|
+
}
|
|
7236
|
+
dispatch(computePass, x, y, z) {
|
|
7237
|
+
try {
|
|
7238
|
+
this._logDrawCallStart();
|
|
7239
|
+
this.pipeline = this._updatePipeline();
|
|
7240
|
+
this.pipeline.setBindings(this.bindings);
|
|
7241
|
+
computePass.setPipeline(this.pipeline);
|
|
7242
|
+
computePass.setBindings([]);
|
|
7243
|
+
computePass.dispatch(x, y, z);
|
|
7244
|
+
} finally {
|
|
7245
|
+
this._logDrawCallEnd();
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
7249
|
+
// Update dynamic fields
|
|
7250
|
+
/**
|
|
7251
|
+
* Updates the vertex count (used in draw calls)
|
|
7252
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
7253
|
+
*/
|
|
7254
|
+
setVertexCount(vertexCount) {
|
|
7255
|
+
}
|
|
7256
|
+
/**
|
|
7257
|
+
* Updates the instance count (used in draw calls)
|
|
7258
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
7259
|
+
*/
|
|
7260
|
+
setInstanceCount(instanceCount) {
|
|
7261
|
+
}
|
|
7262
|
+
setShaderInputs(shaderInputs) {
|
|
7263
|
+
this.shaderInputs = shaderInputs;
|
|
7264
|
+
this._uniformStore = new import_core17.UniformStore(this.shaderInputs.modules);
|
|
7265
|
+
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
7266
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
7267
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
/**
|
|
7271
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
7272
|
+
*/
|
|
7273
|
+
setShaderModuleProps(props) {
|
|
7274
|
+
const uniforms = this._getModuleUniforms(props);
|
|
7275
|
+
const keys = Object.keys(uniforms).filter((k) => {
|
|
7276
|
+
const uniform = uniforms[k];
|
|
7277
|
+
return !isNumericArray(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
7278
|
+
});
|
|
7279
|
+
const bindings = {};
|
|
7280
|
+
for (const k of keys) {
|
|
7281
|
+
bindings[k] = uniforms[k];
|
|
7282
|
+
delete uniforms[k];
|
|
7283
|
+
}
|
|
7284
|
+
}
|
|
7285
|
+
updateShaderInputs() {
|
|
7286
|
+
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
7287
|
+
}
|
|
7288
|
+
/**
|
|
7289
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
7290
|
+
*/
|
|
7291
|
+
setBindings(bindings) {
|
|
7292
|
+
Object.assign(this.bindings, bindings);
|
|
7293
|
+
}
|
|
7294
|
+
_setPipelineNeedsUpdate(reason) {
|
|
7295
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
7296
|
+
}
|
|
7297
|
+
_updatePipeline() {
|
|
7298
|
+
if (this._pipelineNeedsUpdate) {
|
|
7299
|
+
let prevShader = null;
|
|
7300
|
+
if (this.pipeline) {
|
|
7301
|
+
import_core17.log.log(
|
|
7302
|
+
1,
|
|
7303
|
+
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
7304
|
+
)();
|
|
7305
|
+
prevShader = this.shader;
|
|
7306
|
+
}
|
|
7307
|
+
this._pipelineNeedsUpdate = false;
|
|
7308
|
+
this.shader = this.shaderFactory.createShader({
|
|
7309
|
+
id: `${this.id}-fragment`,
|
|
7310
|
+
stage: "compute",
|
|
7311
|
+
source: this.source,
|
|
7312
|
+
debugShaders: this.props.debugShaders
|
|
7313
|
+
});
|
|
7314
|
+
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
7315
|
+
...this.props,
|
|
7316
|
+
shader: this.shader
|
|
7317
|
+
});
|
|
7318
|
+
if (prevShader) {
|
|
7319
|
+
this.shaderFactory.release(prevShader);
|
|
7320
|
+
}
|
|
7321
|
+
}
|
|
7322
|
+
return this.pipeline;
|
|
7323
|
+
}
|
|
7324
|
+
/** Throttle draw call logging */
|
|
7325
|
+
_lastLogTime = 0;
|
|
7326
|
+
_logOpen = false;
|
|
7327
|
+
_logDrawCallStart() {
|
|
7328
|
+
const logDrawTimeout = import_core17.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
7329
|
+
if (import_core17.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
7330
|
+
return;
|
|
7331
|
+
}
|
|
7332
|
+
this._lastLogTime = Date.now();
|
|
7333
|
+
this._logOpen = true;
|
|
7334
|
+
import_core17.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core17.log.level <= 2 })();
|
|
7335
|
+
}
|
|
7336
|
+
_logDrawCallEnd() {
|
|
7337
|
+
if (this._logOpen) {
|
|
7338
|
+
const uniformTable = this.shaderInputs.getDebugTable();
|
|
7339
|
+
import_core17.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
7340
|
+
import_core17.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
7341
|
+
this._logOpen = false;
|
|
7342
|
+
}
|
|
7343
|
+
}
|
|
7344
|
+
_drawCount = 0;
|
|
7345
|
+
// TODO - fix typing of luma data types
|
|
7346
|
+
_getBufferOrConstantValues(attribute, dataType) {
|
|
7347
|
+
const TypedArrayConstructor = (0, import_core17.getTypedArrayConstructor)(dataType);
|
|
7348
|
+
const typedArray = attribute instanceof import_core17.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
7349
|
+
return typedArray.toString();
|
|
7350
|
+
}
|
|
7351
|
+
};
|
|
7352
|
+
var Computation = _Computation;
|
|
7353
|
+
__publicField(Computation, "defaultProps", {
|
|
7354
|
+
...import_core17.ComputePipeline.defaultProps,
|
|
7355
|
+
id: "unnamed",
|
|
7356
|
+
handle: void 0,
|
|
7357
|
+
userData: {},
|
|
7358
|
+
source: "",
|
|
7359
|
+
modules: [],
|
|
7360
|
+
defines: {},
|
|
7361
|
+
bindings: void 0,
|
|
7362
|
+
shaderInputs: void 0,
|
|
7363
|
+
pipelineFactory: void 0,
|
|
7364
|
+
shaderFactory: void 0,
|
|
7365
|
+
shaderAssembler: import_shadertools6.ShaderAssembler.getDefaultShaderAssembler(),
|
|
7366
|
+
debugShaders: void 0
|
|
7367
|
+
});
|
|
7368
|
+
function getPlatformInfo2(device) {
|
|
7369
|
+
return {
|
|
7370
|
+
type: device.type,
|
|
7371
|
+
shaderLanguage: device.info.shadingLanguage,
|
|
7372
|
+
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
7373
|
+
gpu: device.info.gpu,
|
|
7374
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
7375
|
+
features: device.features
|
|
7376
|
+
};
|
|
7377
|
+
}
|
|
7378
|
+
|
|
7621
7379
|
// src/modules/picking/picking-uniforms.ts
|
|
7622
7380
|
var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
|
|
7623
7381
|
var INVALID_INDEX = -1;
|
|
@@ -7810,12 +7568,6 @@ const INDEX_PICKING_MODE_INSTANCE = 0;
|
|
|
7810
7568
|
const INDEX_PICKING_MODE_CUSTOM = 1;
|
|
7811
7569
|
const INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
7812
7570
|
|
|
7813
|
-
struct indexPickingFragmentInputs = {
|
|
7814
|
-
objectIndex: int32;
|
|
7815
|
-
};
|
|
7816
|
-
|
|
7817
|
-
let indexPickingFragmentInputs: indexPickingFragmentInputs;
|
|
7818
|
-
|
|
7819
7571
|
/**
|
|
7820
7572
|
* Vertex shaders should call this function to set the object index.
|
|
7821
7573
|
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|