@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/index.cjs
CHANGED
|
@@ -246,15 +246,25 @@ var import_core = require("@luma.gl/core");
|
|
|
246
246
|
|
|
247
247
|
// dist/animation-loop/request-animation-frame.js
|
|
248
248
|
function requestAnimationFramePolyfill(callback) {
|
|
249
|
-
|
|
249
|
+
const browserRequestAnimationFrame = typeof window !== "undefined" ? window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame : null;
|
|
250
|
+
if (browserRequestAnimationFrame) {
|
|
251
|
+
return browserRequestAnimationFrame.call(window, callback);
|
|
252
|
+
}
|
|
253
|
+
return setTimeout(() => callback(typeof performance !== "undefined" ? performance.now() : Date.now()), 1e3 / 60);
|
|
250
254
|
}
|
|
251
255
|
function cancelAnimationFramePolyfill(timerId) {
|
|
252
|
-
|
|
256
|
+
const browserCancelAnimationFrame = typeof window !== "undefined" ? window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame : null;
|
|
257
|
+
if (browserCancelAnimationFrame) {
|
|
258
|
+
browserCancelAnimationFrame.call(window, timerId);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
clearTimeout(timerId);
|
|
253
262
|
}
|
|
254
263
|
|
|
255
264
|
// dist/animation-loop/animation-loop.js
|
|
256
265
|
var import_stats = require("@probe.gl/stats");
|
|
257
266
|
var statIdCounter = 0;
|
|
267
|
+
var ANIMATION_LOOP_STATS = "Animation Loop";
|
|
258
268
|
var _AnimationLoop = class {
|
|
259
269
|
device = null;
|
|
260
270
|
canvas = null;
|
|
@@ -262,6 +272,7 @@ var _AnimationLoop = class {
|
|
|
262
272
|
animationProps = null;
|
|
263
273
|
timeline = null;
|
|
264
274
|
stats;
|
|
275
|
+
sharedStats;
|
|
265
276
|
cpuTime;
|
|
266
277
|
gpuTime;
|
|
267
278
|
frameRate;
|
|
@@ -274,7 +285,7 @@ var _AnimationLoop = class {
|
|
|
274
285
|
_resolveNextFrame = null;
|
|
275
286
|
_cpuStartTime = 0;
|
|
276
287
|
_error = null;
|
|
277
|
-
|
|
288
|
+
_lastFrameTime = 0;
|
|
278
289
|
/*
|
|
279
290
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
280
291
|
*/
|
|
@@ -284,10 +295,12 @@ var _AnimationLoop = class {
|
|
|
284
295
|
if (!props.device) {
|
|
285
296
|
throw new Error("No device provided");
|
|
286
297
|
}
|
|
287
|
-
this.stats = props.stats || new import_stats.Stats({ id:
|
|
298
|
+
this.stats = props.stats || new import_stats.Stats({ id: `animation-loop-${statIdCounter++}` });
|
|
299
|
+
this.sharedStats = import_core.luma.stats.get(ANIMATION_LOOP_STATS);
|
|
300
|
+
this.frameRate = this.stats.get("Frame Rate");
|
|
301
|
+
this.frameRate.setSampleSize(1);
|
|
288
302
|
this.cpuTime = this.stats.get("CPU Time");
|
|
289
303
|
this.gpuTime = this.stats.get("GPU Time");
|
|
290
|
-
this.frameRate = this.stats.get("Frame Rate");
|
|
291
304
|
this.setProps({ autoResizeViewport: props.autoResizeViewport });
|
|
292
305
|
this.start = this.start.bind(this);
|
|
293
306
|
this.stop = this.stop.bind(this);
|
|
@@ -295,8 +308,10 @@ var _AnimationLoop = class {
|
|
|
295
308
|
this._onMouseleave = this._onMouseleave.bind(this);
|
|
296
309
|
}
|
|
297
310
|
destroy() {
|
|
311
|
+
var _a;
|
|
298
312
|
this.stop();
|
|
299
313
|
this._setDisplay(null);
|
|
314
|
+
(_a = this.device) == null ? void 0 : _a._disableDebugGPUTime();
|
|
300
315
|
}
|
|
301
316
|
/** @deprecated Use .destroy() */
|
|
302
317
|
delete() {
|
|
@@ -361,16 +376,17 @@ var _AnimationLoop = class {
|
|
|
361
376
|
this._nextFramePromise = null;
|
|
362
377
|
this._resolveNextFrame = null;
|
|
363
378
|
this._running = false;
|
|
379
|
+
this._lastFrameTime = 0;
|
|
364
380
|
}
|
|
365
381
|
return this;
|
|
366
382
|
}
|
|
367
383
|
/** Explicitly draw a frame */
|
|
368
|
-
redraw() {
|
|
384
|
+
redraw(time) {
|
|
369
385
|
var _a;
|
|
370
386
|
if (((_a = this.device) == null ? void 0 : _a.isLost) || this._error) {
|
|
371
387
|
return this;
|
|
372
388
|
}
|
|
373
|
-
this._beginFrameTimers();
|
|
389
|
+
this._beginFrameTimers(time);
|
|
374
390
|
this._setupFrame();
|
|
375
391
|
this._updateAnimationProps();
|
|
376
392
|
this._renderFrame(this._getAnimationProps());
|
|
@@ -413,10 +429,12 @@ var _AnimationLoop = class {
|
|
|
413
429
|
}
|
|
414
430
|
// PRIVATE METHODS
|
|
415
431
|
_initialize() {
|
|
432
|
+
var _a;
|
|
416
433
|
this._startEventHandling();
|
|
417
434
|
this._initializeAnimationProps();
|
|
418
435
|
this._updateAnimationProps();
|
|
419
436
|
this._resizeViewport();
|
|
437
|
+
(_a = this.device) == null ? void 0 : _a._enableDebugGPUTime();
|
|
420
438
|
}
|
|
421
439
|
_setDisplay(display) {
|
|
422
440
|
if (this.display) {
|
|
@@ -441,11 +459,11 @@ var _AnimationLoop = class {
|
|
|
441
459
|
cancelAnimationFramePolyfill(this._animationFrameId);
|
|
442
460
|
this._animationFrameId = null;
|
|
443
461
|
}
|
|
444
|
-
_animationFrame() {
|
|
462
|
+
_animationFrame(time) {
|
|
445
463
|
if (!this._running) {
|
|
446
464
|
return;
|
|
447
465
|
}
|
|
448
|
-
this.redraw();
|
|
466
|
+
this.redraw(time);
|
|
449
467
|
this._requestAnimationFrame();
|
|
450
468
|
}
|
|
451
469
|
// Called on each frame, can be overridden to call onRender multiple times
|
|
@@ -558,18 +576,11 @@ var _AnimationLoop = class {
|
|
|
558
576
|
}
|
|
559
577
|
}
|
|
560
578
|
_getSizeAndAspect() {
|
|
561
|
-
var _a, _b;
|
|
562
579
|
if (!this.device) {
|
|
563
580
|
return { width: 1, height: 1, aspect: 1 };
|
|
564
581
|
}
|
|
565
|
-
const [width, height] =
|
|
566
|
-
|
|
567
|
-
const canvas2 = (_b = this.device) == null ? void 0 : _b.getDefaultCanvasContext().canvas;
|
|
568
|
-
if (canvas2 && canvas2.clientHeight) {
|
|
569
|
-
aspect = canvas2.clientWidth / canvas2.clientHeight;
|
|
570
|
-
} else if (width > 0 && height > 0) {
|
|
571
|
-
aspect = width / height;
|
|
572
|
-
}
|
|
582
|
+
const [width, height] = this.device.getDefaultCanvasContext().getDrawingBufferSize();
|
|
583
|
+
const aspect = width > 0 && height > 0 ? width / height : 1;
|
|
573
584
|
return { width, height, aspect };
|
|
574
585
|
}
|
|
575
586
|
/** @deprecated Default viewport setup */
|
|
@@ -585,13 +596,63 @@ var _AnimationLoop = class {
|
|
|
585
596
|
);
|
|
586
597
|
}
|
|
587
598
|
}
|
|
588
|
-
_beginFrameTimers() {
|
|
589
|
-
|
|
590
|
-
|
|
599
|
+
_beginFrameTimers(time) {
|
|
600
|
+
var _a;
|
|
601
|
+
const now = time ?? (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
602
|
+
if (this._lastFrameTime) {
|
|
603
|
+
const frameTime = now - this._lastFrameTime;
|
|
604
|
+
if (frameTime > 0) {
|
|
605
|
+
this.frameRate.addTime(frameTime);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
this._lastFrameTime = now;
|
|
609
|
+
if ((_a = this.device) == null ? void 0 : _a._isDebugGPUTimeEnabled()) {
|
|
610
|
+
this._consumeEncodedGpuTime();
|
|
611
|
+
}
|
|
591
612
|
this.cpuTime.timeStart();
|
|
592
613
|
}
|
|
593
614
|
_endFrameTimers() {
|
|
615
|
+
var _a;
|
|
616
|
+
if ((_a = this.device) == null ? void 0 : _a._isDebugGPUTimeEnabled()) {
|
|
617
|
+
this._consumeEncodedGpuTime();
|
|
618
|
+
}
|
|
594
619
|
this.cpuTime.timeEnd();
|
|
620
|
+
this._updateSharedStats();
|
|
621
|
+
}
|
|
622
|
+
_consumeEncodedGpuTime() {
|
|
623
|
+
if (!this.device) {
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
const gpuTimeMs = this.device.commandEncoder._gpuTimeMs;
|
|
627
|
+
if (gpuTimeMs !== void 0) {
|
|
628
|
+
this.gpuTime.addTime(gpuTimeMs);
|
|
629
|
+
this.device.commandEncoder._gpuTimeMs = void 0;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
_updateSharedStats() {
|
|
633
|
+
if (this.stats === this.sharedStats) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
for (const name of Object.keys(this.sharedStats.stats)) {
|
|
637
|
+
if (!this.stats.stats[name]) {
|
|
638
|
+
delete this.sharedStats.stats[name];
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
this.stats.forEach((sourceStat) => {
|
|
642
|
+
const targetStat = this.sharedStats.get(sourceStat.name, sourceStat.type);
|
|
643
|
+
targetStat.sampleSize = sourceStat.sampleSize;
|
|
644
|
+
targetStat.time = sourceStat.time;
|
|
645
|
+
targetStat.count = sourceStat.count;
|
|
646
|
+
targetStat.samples = sourceStat.samples;
|
|
647
|
+
targetStat.lastTiming = sourceStat.lastTiming;
|
|
648
|
+
targetStat.lastSampleTime = sourceStat.lastSampleTime;
|
|
649
|
+
targetStat.lastSampleCount = sourceStat.lastSampleCount;
|
|
650
|
+
targetStat._count = sourceStat._count;
|
|
651
|
+
targetStat._time = sourceStat._time;
|
|
652
|
+
targetStat._samples = sourceStat._samples;
|
|
653
|
+
targetStat._startTime = sourceStat._startTime;
|
|
654
|
+
targetStat._timerPending = sourceStat._timerPending;
|
|
655
|
+
});
|
|
595
656
|
}
|
|
596
657
|
// Event handling
|
|
597
658
|
_startEventHandling() {
|
|
@@ -620,7 +681,7 @@ __publicField(AnimationLoop, "defaultAnimationLoopProps", {
|
|
|
620
681
|
},
|
|
621
682
|
onError: (error) => console.error(error),
|
|
622
683
|
// eslint-disable-line no-console
|
|
623
|
-
stats:
|
|
684
|
+
stats: void 0,
|
|
624
685
|
// view parameters
|
|
625
686
|
autoResizeViewport: false
|
|
626
687
|
});
|
|
@@ -653,7 +714,10 @@ function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
|
|
|
653
714
|
}
|
|
654
715
|
function setError(device, error) {
|
|
655
716
|
var _a;
|
|
656
|
-
|
|
717
|
+
if (!device) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
const canvas2 = device.getDefaultCanvasContext().canvas;
|
|
657
721
|
if (canvas2 instanceof HTMLCanvasElement) {
|
|
658
722
|
canvas2.style.overflow = "visible";
|
|
659
723
|
let errorDiv = document.getElementById("animation-loop-error");
|
|
@@ -670,6 +734,9 @@ function setError(device, error) {
|
|
|
670
734
|
}
|
|
671
735
|
}
|
|
672
736
|
function clearError(device) {
|
|
737
|
+
if (!device) {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
673
740
|
const errorDiv = document.getElementById("animation-loop-error");
|
|
674
741
|
if (errorDiv) {
|
|
675
742
|
errorDiv.remove();
|
|
@@ -677,8 +744,8 @@ function clearError(device) {
|
|
|
677
744
|
}
|
|
678
745
|
|
|
679
746
|
// dist/model/model.js
|
|
680
|
-
var
|
|
681
|
-
var
|
|
747
|
+
var import_core10 = require("@luma.gl/core");
|
|
748
|
+
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
682
749
|
|
|
683
750
|
// dist/geometry/gpu-geometry.js
|
|
684
751
|
var import_core3 = require("@luma.gl/core");
|
|
@@ -798,13 +865,11 @@ var _PipelineFactory = class {
|
|
|
798
865
|
return moduleData.defaultPipelineFactory;
|
|
799
866
|
}
|
|
800
867
|
device;
|
|
801
|
-
cachingEnabled;
|
|
802
|
-
destroyPolicy;
|
|
803
|
-
debug;
|
|
804
868
|
_hashCounter = 0;
|
|
805
869
|
_hashes = {};
|
|
806
870
|
_renderPipelineCache = {};
|
|
807
871
|
_computePipelineCache = {};
|
|
872
|
+
_sharedRenderPipelineCache = {};
|
|
808
873
|
get [Symbol.toStringTag]() {
|
|
809
874
|
return "PipelineFactory";
|
|
810
875
|
}
|
|
@@ -813,34 +878,33 @@ var _PipelineFactory = class {
|
|
|
813
878
|
}
|
|
814
879
|
constructor(device) {
|
|
815
880
|
this.device = device;
|
|
816
|
-
this.cachingEnabled = device.props._cachePipelines;
|
|
817
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
818
|
-
this.debug = device.props.debugFactories;
|
|
819
881
|
}
|
|
820
882
|
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
821
883
|
createRenderPipeline(props) {
|
|
822
884
|
var _a;
|
|
823
|
-
if (!this.
|
|
885
|
+
if (!this.device.props._cachePipelines) {
|
|
824
886
|
return this.device.createRenderPipeline(props);
|
|
825
887
|
}
|
|
826
888
|
const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
|
|
827
889
|
const cache = this._renderPipelineCache;
|
|
828
890
|
const hash = this._hashRenderPipeline(allProps);
|
|
829
|
-
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.
|
|
891
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
830
892
|
if (!pipeline) {
|
|
893
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
831
894
|
pipeline = this.device.createRenderPipeline({
|
|
832
895
|
...allProps,
|
|
833
|
-
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
|
|
896
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
897
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
834
898
|
});
|
|
835
899
|
pipeline.hash = hash;
|
|
836
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
837
|
-
if (this.
|
|
900
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
901
|
+
if (this.device.props.debugFactories) {
|
|
838
902
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
839
903
|
}
|
|
840
904
|
} else {
|
|
841
905
|
cache[hash].useCount++;
|
|
842
|
-
if (this.
|
|
843
|
-
import_core4.log.log(3, `${this}: ${cache[hash].
|
|
906
|
+
if (this.device.props.debugFactories) {
|
|
907
|
+
import_core4.log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
844
908
|
}
|
|
845
909
|
}
|
|
846
910
|
return pipeline;
|
|
@@ -848,33 +912,33 @@ var _PipelineFactory = class {
|
|
|
848
912
|
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
849
913
|
createComputePipeline(props) {
|
|
850
914
|
var _a;
|
|
851
|
-
if (!this.
|
|
915
|
+
if (!this.device.props._cachePipelines) {
|
|
852
916
|
return this.device.createComputePipeline(props);
|
|
853
917
|
}
|
|
854
918
|
const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
|
|
855
919
|
const cache = this._computePipelineCache;
|
|
856
920
|
const hash = this._hashComputePipeline(allProps);
|
|
857
|
-
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.
|
|
921
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
858
922
|
if (!pipeline) {
|
|
859
923
|
pipeline = this.device.createComputePipeline({
|
|
860
924
|
...allProps,
|
|
861
925
|
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
862
926
|
});
|
|
863
927
|
pipeline.hash = hash;
|
|
864
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
865
|
-
if (this.
|
|
928
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
929
|
+
if (this.device.props.debugFactories) {
|
|
866
930
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
867
931
|
}
|
|
868
932
|
} else {
|
|
869
933
|
cache[hash].useCount++;
|
|
870
|
-
if (this.
|
|
871
|
-
import_core4.log.log(3, `${this}: ${cache[hash].
|
|
934
|
+
if (this.device.props.debugFactories) {
|
|
935
|
+
import_core4.log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
872
936
|
}
|
|
873
937
|
}
|
|
874
938
|
return pipeline;
|
|
875
939
|
}
|
|
876
940
|
release(pipeline) {
|
|
877
|
-
if (!this.
|
|
941
|
+
if (!this.device.props._cachePipelines) {
|
|
878
942
|
pipeline.destroy();
|
|
879
943
|
return;
|
|
880
944
|
}
|
|
@@ -883,28 +947,55 @@ var _PipelineFactory = class {
|
|
|
883
947
|
cache[hash].useCount--;
|
|
884
948
|
if (cache[hash].useCount === 0) {
|
|
885
949
|
this._destroyPipeline(pipeline);
|
|
886
|
-
if (this.
|
|
950
|
+
if (this.device.props.debugFactories) {
|
|
887
951
|
import_core4.log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
888
952
|
}
|
|
889
953
|
} else if (cache[hash].useCount < 0) {
|
|
890
954
|
import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
891
955
|
cache[hash].useCount = 0;
|
|
892
|
-
} else if (this.
|
|
956
|
+
} else if (this.device.props.debugFactories) {
|
|
893
957
|
import_core4.log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
894
958
|
}
|
|
895
959
|
}
|
|
960
|
+
createSharedRenderPipeline(props) {
|
|
961
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
962
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
963
|
+
if (!sharedCacheItem) {
|
|
964
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
965
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
966
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
967
|
+
}
|
|
968
|
+
sharedCacheItem.useCount++;
|
|
969
|
+
return sharedCacheItem.resource;
|
|
970
|
+
}
|
|
971
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
972
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
976
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
977
|
+
if (!sharedCacheItem) {
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
sharedCacheItem.useCount--;
|
|
981
|
+
if (sharedCacheItem.useCount === 0) {
|
|
982
|
+
sharedCacheItem.resource.destroy();
|
|
983
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
984
|
+
}
|
|
985
|
+
}
|
|
896
986
|
// PRIVATE
|
|
897
|
-
/** Destroy a cached pipeline, removing it from the cache
|
|
987
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
898
988
|
_destroyPipeline(pipeline) {
|
|
899
989
|
const cache = this._getCache(pipeline);
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
990
|
+
if (!this.device.props._destroyPipelines) {
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
delete cache[pipeline.hash];
|
|
994
|
+
pipeline.destroy();
|
|
995
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
996
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
907
997
|
}
|
|
998
|
+
return true;
|
|
908
999
|
}
|
|
909
1000
|
/** Get the appropriate cache for the type of pipeline */
|
|
910
1001
|
_getCache(pipeline) {
|
|
@@ -933,24 +1024,35 @@ var _PipelineFactory = class {
|
|
|
933
1024
|
_hashRenderPipeline(props) {
|
|
934
1025
|
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
935
1026
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
936
|
-
const varyingHash =
|
|
1027
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
937
1028
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
938
1029
|
const { type } = this.device;
|
|
939
1030
|
switch (type) {
|
|
940
1031
|
case "webgl":
|
|
941
|
-
|
|
1032
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1033
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}BL${bufferLayoutHash}`;
|
|
942
1034
|
case "webgpu":
|
|
943
1035
|
default:
|
|
944
1036
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
945
1037
|
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
946
1038
|
}
|
|
947
1039
|
}
|
|
1040
|
+
_hashSharedRenderPipeline(props) {
|
|
1041
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
1042
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1043
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
1044
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
1045
|
+
}
|
|
948
1046
|
_getHash(key) {
|
|
949
1047
|
if (this._hashes[key] === void 0) {
|
|
950
1048
|
this._hashes[key] = this._hashCounter++;
|
|
951
1049
|
}
|
|
952
1050
|
return this._hashes[key];
|
|
953
1051
|
}
|
|
1052
|
+
_getWebGLVaryingHash(props) {
|
|
1053
|
+
const { varyings = [], bufferMode = null } = props;
|
|
1054
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
1055
|
+
}
|
|
954
1056
|
};
|
|
955
1057
|
var PipelineFactory = _PipelineFactory;
|
|
956
1058
|
__publicField(PipelineFactory, "defaultProps", { ...import_core4.RenderPipeline.defaultProps });
|
|
@@ -965,9 +1067,6 @@ var _ShaderFactory = class {
|
|
|
965
1067
|
return moduleData.defaultShaderFactory;
|
|
966
1068
|
}
|
|
967
1069
|
device;
|
|
968
|
-
cachingEnabled;
|
|
969
|
-
destroyPolicy;
|
|
970
|
-
debug;
|
|
971
1070
|
_cache = {};
|
|
972
1071
|
get [Symbol.toStringTag]() {
|
|
973
1072
|
return "ShaderFactory";
|
|
@@ -978,37 +1077,34 @@ var _ShaderFactory = class {
|
|
|
978
1077
|
/** @internal */
|
|
979
1078
|
constructor(device) {
|
|
980
1079
|
this.device = device;
|
|
981
|
-
this.cachingEnabled = device.props._cacheShaders;
|
|
982
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
983
|
-
this.debug = true;
|
|
984
1080
|
}
|
|
985
1081
|
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
986
1082
|
createShader(props) {
|
|
987
|
-
if (!this.
|
|
1083
|
+
if (!this.device.props._cacheShaders) {
|
|
988
1084
|
return this.device.createShader(props);
|
|
989
1085
|
}
|
|
990
1086
|
const key = this._hashShader(props);
|
|
991
1087
|
let cacheEntry = this._cache[key];
|
|
992
1088
|
if (!cacheEntry) {
|
|
993
|
-
const
|
|
1089
|
+
const resource = this.device.createShader({
|
|
994
1090
|
...props,
|
|
995
1091
|
id: props.id ? `${props.id}-cached` : void 0
|
|
996
1092
|
});
|
|
997
|
-
this._cache[key] = cacheEntry = {
|
|
998
|
-
if (this.
|
|
999
|
-
import_core5.log.log(3, `${this}: Created new shader ${
|
|
1093
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
1094
|
+
if (this.device.props.debugFactories) {
|
|
1095
|
+
import_core5.log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
1000
1096
|
}
|
|
1001
1097
|
} else {
|
|
1002
1098
|
cacheEntry.useCount++;
|
|
1003
|
-
if (this.
|
|
1004
|
-
import_core5.log.log(3, `${this}: Reusing shader ${cacheEntry.
|
|
1099
|
+
if (this.device.props.debugFactories) {
|
|
1100
|
+
import_core5.log.log(3, `${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`)();
|
|
1005
1101
|
}
|
|
1006
1102
|
}
|
|
1007
|
-
return cacheEntry.
|
|
1103
|
+
return cacheEntry.resource;
|
|
1008
1104
|
}
|
|
1009
1105
|
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
1010
1106
|
release(shader) {
|
|
1011
|
-
if (!this.
|
|
1107
|
+
if (!this.device.props._cacheShaders) {
|
|
1012
1108
|
shader.destroy();
|
|
1013
1109
|
return;
|
|
1014
1110
|
}
|
|
@@ -1017,16 +1113,16 @@ var _ShaderFactory = class {
|
|
|
1017
1113
|
if (cacheEntry) {
|
|
1018
1114
|
cacheEntry.useCount--;
|
|
1019
1115
|
if (cacheEntry.useCount === 0) {
|
|
1020
|
-
if (this.
|
|
1116
|
+
if (this.device.props._destroyShaders) {
|
|
1021
1117
|
delete this._cache[key];
|
|
1022
|
-
cacheEntry.
|
|
1023
|
-
if (this.
|
|
1118
|
+
cacheEntry.resource.destroy();
|
|
1119
|
+
if (this.device.props.debugFactories) {
|
|
1024
1120
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
1025
1121
|
}
|
|
1026
1122
|
}
|
|
1027
1123
|
} else if (cacheEntry.useCount < 0) {
|
|
1028
1124
|
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
1029
|
-
} else if (this.
|
|
1125
|
+
} else if (this.device.props.debugFactories) {
|
|
1030
1126
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
1031
1127
|
}
|
|
1032
1128
|
}
|
|
@@ -1326,7 +1422,7 @@ var ShaderInputs = class {
|
|
|
1326
1422
|
};
|
|
1327
1423
|
|
|
1328
1424
|
// dist/dynamic-texture/dynamic-texture.js
|
|
1329
|
-
var
|
|
1425
|
+
var import_core9 = require("@luma.gl/core");
|
|
1330
1426
|
|
|
1331
1427
|
// dist/dynamic-texture/texture-data.js
|
|
1332
1428
|
var import_core8 = require("@luma.gl/core");
|
|
@@ -1394,6 +1490,13 @@ function getTextureMipLevelSize(data) {
|
|
|
1394
1490
|
function isTextureImageData(data) {
|
|
1395
1491
|
return typeof data === "object" && data !== null && "data" in data && "width" in data && "height" in data;
|
|
1396
1492
|
}
|
|
1493
|
+
function resolveTextureImageFormat(data) {
|
|
1494
|
+
const { textureFormat, format } = data;
|
|
1495
|
+
if (textureFormat && format && textureFormat !== format) {
|
|
1496
|
+
throw new Error(`Conflicting texture formats "${textureFormat}" and "${format}" provided for the same mip level`);
|
|
1497
|
+
}
|
|
1498
|
+
return textureFormat ?? format;
|
|
1499
|
+
}
|
|
1397
1500
|
function getCubeFaceIndex(face) {
|
|
1398
1501
|
const idx = TEXTURE_CUBE_FACE_MAP[face];
|
|
1399
1502
|
if (idx === void 0)
|
|
@@ -1426,6 +1529,7 @@ function getTexture2DSubresources(slice, lodData) {
|
|
|
1426
1529
|
subresources.push({
|
|
1427
1530
|
type: "texture-data",
|
|
1428
1531
|
data: imageData,
|
|
1532
|
+
textureFormat: resolveTextureImageFormat(imageData),
|
|
1429
1533
|
z,
|
|
1430
1534
|
mipLevel
|
|
1431
1535
|
});
|
|
@@ -1468,641 +1572,6 @@ function getTextureCubeArraySubresources(data) {
|
|
|
1468
1572
|
return subresources;
|
|
1469
1573
|
}
|
|
1470
1574
|
|
|
1471
|
-
// dist/dynamic-texture/mipmaps.js
|
|
1472
|
-
var import_core10 = require("@luma.gl/core");
|
|
1473
|
-
|
|
1474
|
-
// dist/compute/computation.js
|
|
1475
|
-
var import_core9 = require("@luma.gl/core");
|
|
1476
|
-
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
1477
|
-
var import_types2 = require("@math.gl/types");
|
|
1478
|
-
var LOG_DRAW_PRIORITY = 2;
|
|
1479
|
-
var LOG_DRAW_TIMEOUT = 1e4;
|
|
1480
|
-
var _Computation = class {
|
|
1481
|
-
device;
|
|
1482
|
-
id;
|
|
1483
|
-
pipelineFactory;
|
|
1484
|
-
shaderFactory;
|
|
1485
|
-
userData = {};
|
|
1486
|
-
/** Bindings (textures, samplers, uniform buffers) */
|
|
1487
|
-
bindings = {};
|
|
1488
|
-
/** The underlying GPU pipeline. */
|
|
1489
|
-
pipeline;
|
|
1490
|
-
/** Assembled compute shader source */
|
|
1491
|
-
source;
|
|
1492
|
-
/** the underlying compiled compute shader */
|
|
1493
|
-
// @ts-ignore Set in function called from constructor
|
|
1494
|
-
shader;
|
|
1495
|
-
/** ShaderInputs instance */
|
|
1496
|
-
shaderInputs;
|
|
1497
|
-
// @ts-ignore Set in function called from constructor
|
|
1498
|
-
_uniformStore;
|
|
1499
|
-
_pipelineNeedsUpdate = "newly created";
|
|
1500
|
-
_getModuleUniforms;
|
|
1501
|
-
props;
|
|
1502
|
-
_destroyed = false;
|
|
1503
|
-
constructor(device, props) {
|
|
1504
|
-
var _a, _b, _c;
|
|
1505
|
-
if (device.type !== "webgpu") {
|
|
1506
|
-
throw new Error("Computation is only supported in WebGPU");
|
|
1507
|
-
}
|
|
1508
|
-
this.props = { ..._Computation.defaultProps, ...props };
|
|
1509
|
-
props = this.props;
|
|
1510
|
-
this.id = props.id || uid("model");
|
|
1511
|
-
this.device = device;
|
|
1512
|
-
Object.assign(this.userData, props.userData);
|
|
1513
|
-
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
1514
|
-
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
1515
|
-
this.setShaderInputs(this.shaderInputs);
|
|
1516
|
-
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
1517
|
-
const platformInfo = getPlatformInfo(device);
|
|
1518
|
-
const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
|
|
1519
|
-
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
1520
|
-
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1521
|
-
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1522
|
-
platformInfo,
|
|
1523
|
-
...this.props,
|
|
1524
|
-
modules
|
|
1525
|
-
});
|
|
1526
|
-
this.source = source3;
|
|
1527
|
-
this._getModuleUniforms = getUniforms2;
|
|
1528
|
-
this.pipeline = this._updatePipeline();
|
|
1529
|
-
if (props.bindings) {
|
|
1530
|
-
this.setBindings(props.bindings);
|
|
1531
|
-
}
|
|
1532
|
-
Object.seal(this);
|
|
1533
|
-
}
|
|
1534
|
-
destroy() {
|
|
1535
|
-
if (this._destroyed)
|
|
1536
|
-
return;
|
|
1537
|
-
this.pipelineFactory.release(this.pipeline);
|
|
1538
|
-
this.shaderFactory.release(this.shader);
|
|
1539
|
-
this._uniformStore.destroy();
|
|
1540
|
-
this._destroyed = true;
|
|
1541
|
-
}
|
|
1542
|
-
// Draw call
|
|
1543
|
-
predraw() {
|
|
1544
|
-
this.updateShaderInputs();
|
|
1545
|
-
}
|
|
1546
|
-
dispatch(computePass, x, y, z) {
|
|
1547
|
-
try {
|
|
1548
|
-
this._logDrawCallStart();
|
|
1549
|
-
this.pipeline = this._updatePipeline();
|
|
1550
|
-
this.pipeline.setBindings(this.bindings);
|
|
1551
|
-
computePass.setPipeline(this.pipeline);
|
|
1552
|
-
computePass.setBindings([]);
|
|
1553
|
-
computePass.dispatch(x, y, z);
|
|
1554
|
-
} finally {
|
|
1555
|
-
this._logDrawCallEnd();
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
// Update fixed fields (can trigger pipeline rebuild)
|
|
1559
|
-
// Update dynamic fields
|
|
1560
|
-
/**
|
|
1561
|
-
* Updates the vertex count (used in draw calls)
|
|
1562
|
-
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
1563
|
-
*/
|
|
1564
|
-
setVertexCount(vertexCount) {
|
|
1565
|
-
}
|
|
1566
|
-
/**
|
|
1567
|
-
* Updates the instance count (used in draw calls)
|
|
1568
|
-
* @note Any attributes with stepMode=instance need to be at least this big
|
|
1569
|
-
*/
|
|
1570
|
-
setInstanceCount(instanceCount) {
|
|
1571
|
-
}
|
|
1572
|
-
setShaderInputs(shaderInputs) {
|
|
1573
|
-
this.shaderInputs = shaderInputs;
|
|
1574
|
-
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1575
|
-
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
1576
|
-
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1577
|
-
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
/**
|
|
1581
|
-
* Updates shader module settings (which results in uniforms being set)
|
|
1582
|
-
*/
|
|
1583
|
-
setShaderModuleProps(props) {
|
|
1584
|
-
const uniforms = this._getModuleUniforms(props);
|
|
1585
|
-
const keys = Object.keys(uniforms).filter((k) => {
|
|
1586
|
-
const uniform = uniforms[k];
|
|
1587
|
-
return !(0, import_types2.isNumericArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
1588
|
-
});
|
|
1589
|
-
const bindings = {};
|
|
1590
|
-
for (const k of keys) {
|
|
1591
|
-
bindings[k] = uniforms[k];
|
|
1592
|
-
delete uniforms[k];
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
updateShaderInputs() {
|
|
1596
|
-
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1597
|
-
}
|
|
1598
|
-
/**
|
|
1599
|
-
* Sets bindings (textures, samplers, uniform buffers)
|
|
1600
|
-
*/
|
|
1601
|
-
setBindings(bindings) {
|
|
1602
|
-
Object.assign(this.bindings, bindings);
|
|
1603
|
-
}
|
|
1604
|
-
_setPipelineNeedsUpdate(reason) {
|
|
1605
|
-
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
1606
|
-
}
|
|
1607
|
-
_updatePipeline() {
|
|
1608
|
-
if (this._pipelineNeedsUpdate) {
|
|
1609
|
-
let prevShader = null;
|
|
1610
|
-
if (this.pipeline) {
|
|
1611
|
-
import_core9.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
1612
|
-
prevShader = this.shader;
|
|
1613
|
-
}
|
|
1614
|
-
this._pipelineNeedsUpdate = false;
|
|
1615
|
-
this.shader = this.shaderFactory.createShader({
|
|
1616
|
-
id: `${this.id}-fragment`,
|
|
1617
|
-
stage: "compute",
|
|
1618
|
-
source: this.source,
|
|
1619
|
-
debugShaders: this.props.debugShaders
|
|
1620
|
-
});
|
|
1621
|
-
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
1622
|
-
...this.props,
|
|
1623
|
-
shader: this.shader
|
|
1624
|
-
});
|
|
1625
|
-
if (prevShader) {
|
|
1626
|
-
this.shaderFactory.release(prevShader);
|
|
1627
|
-
}
|
|
1628
|
-
}
|
|
1629
|
-
return this.pipeline;
|
|
1630
|
-
}
|
|
1631
|
-
/** Throttle draw call logging */
|
|
1632
|
-
_lastLogTime = 0;
|
|
1633
|
-
_logOpen = false;
|
|
1634
|
-
_logDrawCallStart() {
|
|
1635
|
-
const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1636
|
-
if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1637
|
-
return;
|
|
1638
|
-
}
|
|
1639
|
-
this._lastLogTime = Date.now();
|
|
1640
|
-
this._logOpen = true;
|
|
1641
|
-
import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
|
|
1642
|
-
}
|
|
1643
|
-
_logDrawCallEnd() {
|
|
1644
|
-
if (this._logOpen) {
|
|
1645
|
-
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1646
|
-
import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1647
|
-
import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1648
|
-
this._logOpen = false;
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
_drawCount = 0;
|
|
1652
|
-
// TODO - fix typing of luma data types
|
|
1653
|
-
_getBufferOrConstantValues(attribute, dataType) {
|
|
1654
|
-
const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
|
|
1655
|
-
const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1656
|
-
return typedArray.toString();
|
|
1657
|
-
}
|
|
1658
|
-
};
|
|
1659
|
-
var Computation = _Computation;
|
|
1660
|
-
__publicField(Computation, "defaultProps", {
|
|
1661
|
-
...import_core9.ComputePipeline.defaultProps,
|
|
1662
|
-
id: "unnamed",
|
|
1663
|
-
handle: void 0,
|
|
1664
|
-
userData: {},
|
|
1665
|
-
source: "",
|
|
1666
|
-
modules: [],
|
|
1667
|
-
defines: {},
|
|
1668
|
-
bindings: void 0,
|
|
1669
|
-
shaderInputs: void 0,
|
|
1670
|
-
pipelineFactory: void 0,
|
|
1671
|
-
shaderFactory: void 0,
|
|
1672
|
-
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
1673
|
-
debugShaders: void 0
|
|
1674
|
-
});
|
|
1675
|
-
function getPlatformInfo(device) {
|
|
1676
|
-
return {
|
|
1677
|
-
type: device.type,
|
|
1678
|
-
shaderLanguage: device.info.shadingLanguage,
|
|
1679
|
-
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
1680
|
-
gpu: device.info.gpu,
|
|
1681
|
-
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
1682
|
-
features: device.features
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
// dist/dynamic-texture/mipmaps.js
|
|
1687
|
-
var RENDER_DIMENSIONS = [
|
|
1688
|
-
"2d",
|
|
1689
|
-
"2d-array",
|
|
1690
|
-
"cube",
|
|
1691
|
-
"cube-array"
|
|
1692
|
-
];
|
|
1693
|
-
var WORKGROUP_SIZE = {
|
|
1694
|
-
x: 4,
|
|
1695
|
-
y: 4,
|
|
1696
|
-
z: 4
|
|
1697
|
-
};
|
|
1698
|
-
function generateMipmap(device, texture) {
|
|
1699
|
-
if (texture.mipLevels <= 1) {
|
|
1700
|
-
return;
|
|
1701
|
-
}
|
|
1702
|
-
if (device.type !== "webgpu") {
|
|
1703
|
-
throw new Error(`Cannot generate mipmaps on device type "${device.type}". Use generateMipmapsWebGL for WebGL devices.`);
|
|
1704
|
-
}
|
|
1705
|
-
if (texture.dimension === "3d") {
|
|
1706
|
-
generateMipmaps3D(device, texture);
|
|
1707
|
-
return;
|
|
1708
|
-
}
|
|
1709
|
-
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
1710
|
-
generateMipmapsRender(device, texture);
|
|
1711
|
-
return;
|
|
1712
|
-
}
|
|
1713
|
-
throw new Error(`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`);
|
|
1714
|
-
}
|
|
1715
|
-
function generateMipmapsRender(device, texture) {
|
|
1716
|
-
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1717
|
-
const colorAttachmentFormat = getColorAttachmentFormat(texture.format, "render", texture.dimension);
|
|
1718
|
-
const viewDimension = texture.dimension;
|
|
1719
|
-
const shader = getRenderMipmapWGSL(viewDimension);
|
|
1720
|
-
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
1721
|
-
const uniformValues = new Uint32Array(1);
|
|
1722
|
-
const uniformsBuffer = device.createBuffer({
|
|
1723
|
-
byteLength: 16,
|
|
1724
|
-
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1725
|
-
});
|
|
1726
|
-
const model = new Model(device, {
|
|
1727
|
-
source: shader,
|
|
1728
|
-
colorAttachmentFormats: [colorAttachmentFormat],
|
|
1729
|
-
topology: "triangle-list",
|
|
1730
|
-
vertexCount: 3,
|
|
1731
|
-
shaderLayout: {
|
|
1732
|
-
attributes: [],
|
|
1733
|
-
bindings: [
|
|
1734
|
-
{ type: "sampler", name: "sourceSampler", group: 0, location: 0 },
|
|
1735
|
-
{
|
|
1736
|
-
type: "texture",
|
|
1737
|
-
name: "sourceTexture",
|
|
1738
|
-
group: 0,
|
|
1739
|
-
location: 1,
|
|
1740
|
-
viewDimension,
|
|
1741
|
-
sampleType: "float"
|
|
1742
|
-
},
|
|
1743
|
-
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
1744
|
-
]
|
|
1745
|
-
},
|
|
1746
|
-
bindings: {
|
|
1747
|
-
sourceSampler: sampler,
|
|
1748
|
-
sourceTexture: texture,
|
|
1749
|
-
uniforms: uniformsBuffer
|
|
1750
|
-
}
|
|
1751
|
-
});
|
|
1752
|
-
let sourceWidth = texture.width;
|
|
1753
|
-
let sourceHeight = texture.height;
|
|
1754
|
-
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
1755
|
-
try {
|
|
1756
|
-
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
1757
|
-
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1758
|
-
const sourceMipLevel = baseMipLevel - 1;
|
|
1759
|
-
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
1760
|
-
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
1761
|
-
const sourceView = texture.createView({
|
|
1762
|
-
dimension: viewDimension,
|
|
1763
|
-
baseMipLevel: sourceMipLevel,
|
|
1764
|
-
mipLevelCount: 1,
|
|
1765
|
-
baseArrayLayer: 0,
|
|
1766
|
-
arrayLayerCount: texture.depth
|
|
1767
|
-
});
|
|
1768
|
-
model.setBindings({ sourceTexture: sourceView });
|
|
1769
|
-
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
1770
|
-
uniformValues[0] = baseArrayLayer;
|
|
1771
|
-
uniformsBuffer.write(uniformValues);
|
|
1772
|
-
const destinationView = texture.createView({
|
|
1773
|
-
dimension: "2d",
|
|
1774
|
-
baseMipLevel,
|
|
1775
|
-
mipLevelCount: 1,
|
|
1776
|
-
baseArrayLayer,
|
|
1777
|
-
arrayLayerCount: 1
|
|
1778
|
-
});
|
|
1779
|
-
const framebuffer = device.createFramebuffer({
|
|
1780
|
-
colorAttachments: [destinationView]
|
|
1781
|
-
});
|
|
1782
|
-
const renderPass = device.beginRenderPass({
|
|
1783
|
-
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
1784
|
-
framebuffer
|
|
1785
|
-
});
|
|
1786
|
-
renderPass.setParameters({
|
|
1787
|
-
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
1788
|
-
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
1789
|
-
});
|
|
1790
|
-
model.draw(renderPass);
|
|
1791
|
-
renderPass.end();
|
|
1792
|
-
device.submit();
|
|
1793
|
-
destinationView.destroy();
|
|
1794
|
-
framebuffer.destroy();
|
|
1795
|
-
}
|
|
1796
|
-
sourceView.destroy();
|
|
1797
|
-
sourceWidth = destinationWidth;
|
|
1798
|
-
sourceHeight = destinationHeight;
|
|
1799
|
-
}
|
|
1800
|
-
} finally {
|
|
1801
|
-
model.destroy();
|
|
1802
|
-
sampler.destroy();
|
|
1803
|
-
uniformsBuffer.destroy();
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
function getColorAttachmentFormat(format, path, dimension) {
|
|
1807
|
-
if (import_core10.textureFormatDecoder.isColor(format)) {
|
|
1808
|
-
return format;
|
|
1809
|
-
}
|
|
1810
|
-
throw new Error(`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.`);
|
|
1811
|
-
}
|
|
1812
|
-
function generateMipmaps3D(device, texture) {
|
|
1813
|
-
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
1814
|
-
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
1815
|
-
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
1816
|
-
const uniformsBuffer = device.createBuffer({
|
|
1817
|
-
byteLength: 32,
|
|
1818
|
-
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1819
|
-
});
|
|
1820
|
-
const uniformValues = new Uint32Array(8);
|
|
1821
|
-
let sourceWidth = texture.width;
|
|
1822
|
-
let sourceHeight = texture.height;
|
|
1823
|
-
let sourceDepth = texture.depth;
|
|
1824
|
-
try {
|
|
1825
|
-
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
1826
|
-
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
1827
|
-
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
1828
|
-
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
1829
|
-
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
1830
|
-
uniformValues[0] = sourceWidth;
|
|
1831
|
-
uniformValues[1] = sourceHeight;
|
|
1832
|
-
uniformValues[2] = sourceDepth;
|
|
1833
|
-
uniformValues[3] = destinationWidth;
|
|
1834
|
-
uniformValues[4] = destinationHeight;
|
|
1835
|
-
uniformValues[5] = destinationDepth;
|
|
1836
|
-
uniformValues[6] = 0;
|
|
1837
|
-
uniformsBuffer.write(uniformValues);
|
|
1838
|
-
const sourceView = texture.createView({
|
|
1839
|
-
dimension: "3d",
|
|
1840
|
-
baseMipLevel: destinationMipLevel - 1,
|
|
1841
|
-
mipLevelCount: 1,
|
|
1842
|
-
baseArrayLayer: 0,
|
|
1843
|
-
arrayLayerCount: 1
|
|
1844
|
-
});
|
|
1845
|
-
const destinationView = texture.createView({
|
|
1846
|
-
dimension: "3d",
|
|
1847
|
-
baseMipLevel: destinationMipLevel,
|
|
1848
|
-
mipLevelCount: 1,
|
|
1849
|
-
baseArrayLayer: 0,
|
|
1850
|
-
arrayLayerCount: 1
|
|
1851
|
-
});
|
|
1852
|
-
const computation = new Computation(device, {
|
|
1853
|
-
source: shaderSource,
|
|
1854
|
-
shaderLayout: {
|
|
1855
|
-
bindings: [
|
|
1856
|
-
{
|
|
1857
|
-
type: "texture",
|
|
1858
|
-
name: "sourceTexture",
|
|
1859
|
-
group: 0,
|
|
1860
|
-
location: 0,
|
|
1861
|
-
viewDimension: "3d",
|
|
1862
|
-
sampleType: "float"
|
|
1863
|
-
},
|
|
1864
|
-
{
|
|
1865
|
-
type: "storage",
|
|
1866
|
-
name: "destinationTexture",
|
|
1867
|
-
group: 0,
|
|
1868
|
-
location: 1,
|
|
1869
|
-
format,
|
|
1870
|
-
viewDimension: "3d",
|
|
1871
|
-
access: "write-only"
|
|
1872
|
-
},
|
|
1873
|
-
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
1874
|
-
]
|
|
1875
|
-
},
|
|
1876
|
-
bindings: {
|
|
1877
|
-
sourceTexture: sourceView,
|
|
1878
|
-
destinationTexture: destinationView,
|
|
1879
|
-
uniforms: uniformsBuffer
|
|
1880
|
-
}
|
|
1881
|
-
});
|
|
1882
|
-
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
1883
|
-
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
1884
|
-
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
1885
|
-
const computePass = device.beginComputePass({});
|
|
1886
|
-
computation.dispatch(computePass, workgroupsX, workgroupsY, workgroupsZ);
|
|
1887
|
-
computePass.end();
|
|
1888
|
-
device.submit();
|
|
1889
|
-
computation.destroy();
|
|
1890
|
-
sourceView.destroy();
|
|
1891
|
-
destinationView.destroy();
|
|
1892
|
-
sourceWidth = destinationWidth;
|
|
1893
|
-
sourceHeight = destinationHeight;
|
|
1894
|
-
sourceDepth = destinationDepth;
|
|
1895
|
-
}
|
|
1896
|
-
} finally {
|
|
1897
|
-
uniformsBuffer.destroy();
|
|
1898
|
-
}
|
|
1899
|
-
}
|
|
1900
|
-
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
1901
|
-
const { format, dimension } = texture;
|
|
1902
|
-
const capabilities = device.getTextureFormatCapabilities(format);
|
|
1903
|
-
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
1904
|
-
if (missingCapabilities.length > 0) {
|
|
1905
|
-
const required = requiredCapabilities.join(" + ");
|
|
1906
|
-
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
1907
|
-
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`);
|
|
1908
|
-
}
|
|
1909
|
-
}
|
|
1910
|
-
function getSourceTextureType(dimension) {
|
|
1911
|
-
switch (dimension) {
|
|
1912
|
-
case "2d":
|
|
1913
|
-
return "texture_2d<f32>";
|
|
1914
|
-
case "2d-array":
|
|
1915
|
-
return "texture_2d_array<f32>";
|
|
1916
|
-
case "cube":
|
|
1917
|
-
return "texture_cube<f32>";
|
|
1918
|
-
case "cube-array":
|
|
1919
|
-
return "texture_cube_array<f32>";
|
|
1920
|
-
default:
|
|
1921
|
-
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
function getRenderMipmapWGSL(dimension) {
|
|
1925
|
-
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
1926
|
-
return `
|
|
1927
|
-
struct MipmapUniforms {
|
|
1928
|
-
sourceLayer: u32,
|
|
1929
|
-
};
|
|
1930
|
-
|
|
1931
|
-
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
1932
|
-
let unusedSourceLayer = uniforms.sourceLayer;
|
|
1933
|
-
}
|
|
1934
|
-
|
|
1935
|
-
const faceMat = array(
|
|
1936
|
-
mat3x3f(
|
|
1937
|
-
0.0, 0.0, -2.0,
|
|
1938
|
-
0.0, -2.0, 0.0,
|
|
1939
|
-
1.0, 1.0, 1.0
|
|
1940
|
-
), // pos-x
|
|
1941
|
-
mat3x3f(
|
|
1942
|
-
0.0, 0.0, 2.0,
|
|
1943
|
-
0.0, -2.0, 0.0,
|
|
1944
|
-
-1.0, 1.0, -1.0
|
|
1945
|
-
), // neg-x
|
|
1946
|
-
mat3x3f(
|
|
1947
|
-
2.0, 0.0, 0.0,
|
|
1948
|
-
0.0, 0.0, 2.0,
|
|
1949
|
-
-1.0, 1.0, -1.0
|
|
1950
|
-
), // pos-y
|
|
1951
|
-
mat3x3f(
|
|
1952
|
-
2.0, 0.0, 0.0,
|
|
1953
|
-
0.0, 0.0, -2.0,
|
|
1954
|
-
-1.0, -1.0, 1.0
|
|
1955
|
-
), // neg-y
|
|
1956
|
-
mat3x3f(
|
|
1957
|
-
2.0, 0.0, 0.0,
|
|
1958
|
-
0.0, -2.0, 0.0,
|
|
1959
|
-
-1.0, 1.0, 1.0
|
|
1960
|
-
), // pos-z
|
|
1961
|
-
mat3x3f(
|
|
1962
|
-
-2.0, 0.0, 0.0,
|
|
1963
|
-
0.0, -2.0, 0.0,
|
|
1964
|
-
1.0, 1.0, -1.0
|
|
1965
|
-
) // neg-z
|
|
1966
|
-
);
|
|
1967
|
-
|
|
1968
|
-
struct FragmentInputs {
|
|
1969
|
-
@builtin(position) position: vec4f,
|
|
1970
|
-
@location(0) texcoord: vec2f
|
|
1971
|
-
};
|
|
1972
|
-
|
|
1973
|
-
struct VertexOutput {
|
|
1974
|
-
@builtin(position) position: vec4f,
|
|
1975
|
-
@location(0) texcoord: vec2f
|
|
1976
|
-
};
|
|
1977
|
-
|
|
1978
|
-
@group(0) @binding(0) var sourceSampler: sampler;
|
|
1979
|
-
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
1980
|
-
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
1981
|
-
|
|
1982
|
-
@vertex
|
|
1983
|
-
fn vertexMain(
|
|
1984
|
-
@builtin(vertex_index) vertexIndex: u32
|
|
1985
|
-
) -> VertexOutput {
|
|
1986
|
-
const positions = array(
|
|
1987
|
-
vec2f(-1.0, -1.0),
|
|
1988
|
-
vec2f(-1.0, 3.0),
|
|
1989
|
-
vec2f( 3.0, -1.0)
|
|
1990
|
-
);
|
|
1991
|
-
|
|
1992
|
-
let xy = positions[vertexIndex];
|
|
1993
|
-
return VertexOutput(
|
|
1994
|
-
vec4f(xy, 0.0, 1.0),
|
|
1995
|
-
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
1996
|
-
);
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
@fragment
|
|
2000
|
-
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2001
|
-
_touchUniform(uniforms);
|
|
2002
|
-
return ${sourceSnippet};
|
|
2003
|
-
}
|
|
2004
|
-
`;
|
|
2005
|
-
}
|
|
2006
|
-
function getRenderMipmapSampleSnippet(dimension) {
|
|
2007
|
-
const layer = "uniforms.sourceLayer";
|
|
2008
|
-
switch (dimension) {
|
|
2009
|
-
case "2d":
|
|
2010
|
-
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2011
|
-
case "2d-array":
|
|
2012
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2013
|
-
case "cube":
|
|
2014
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2015
|
-
case "cube-array":
|
|
2016
|
-
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2017
|
-
default:
|
|
2018
|
-
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
function get3DComputeMipmapWGSL(format) {
|
|
2022
|
-
return `
|
|
2023
|
-
struct MipmapUniforms {
|
|
2024
|
-
sourceWidth: u32,
|
|
2025
|
-
sourceHeight: u32,
|
|
2026
|
-
sourceDepth: u32,
|
|
2027
|
-
destinationWidth: u32,
|
|
2028
|
-
destinationHeight: u32,
|
|
2029
|
-
destinationDepth: u32,
|
|
2030
|
-
padding: u32,
|
|
2031
|
-
};
|
|
2032
|
-
|
|
2033
|
-
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2034
|
-
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2035
|
-
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2036
|
-
|
|
2037
|
-
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2038
|
-
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2039
|
-
if (
|
|
2040
|
-
id.x >= uniforms.destinationWidth ||
|
|
2041
|
-
id.y >= uniforms.destinationHeight ||
|
|
2042
|
-
id.z >= uniforms.destinationDepth
|
|
2043
|
-
) {
|
|
2044
|
-
return;
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
let sourceBase = id * 2u;
|
|
2048
|
-
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2049
|
-
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2050
|
-
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2051
|
-
|
|
2052
|
-
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2053
|
-
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2054
|
-
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2055
|
-
|
|
2056
|
-
var sum = textureLoad(
|
|
2057
|
-
sourceTexture,
|
|
2058
|
-
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2059
|
-
0
|
|
2060
|
-
);
|
|
2061
|
-
sum += textureLoad(
|
|
2062
|
-
sourceTexture,
|
|
2063
|
-
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2064
|
-
0
|
|
2065
|
-
);
|
|
2066
|
-
sum += textureLoad(
|
|
2067
|
-
sourceTexture,
|
|
2068
|
-
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2069
|
-
0
|
|
2070
|
-
);
|
|
2071
|
-
sum += textureLoad(
|
|
2072
|
-
sourceTexture,
|
|
2073
|
-
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2074
|
-
0
|
|
2075
|
-
);
|
|
2076
|
-
sum += textureLoad(
|
|
2077
|
-
sourceTexture,
|
|
2078
|
-
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2079
|
-
0
|
|
2080
|
-
);
|
|
2081
|
-
sum += textureLoad(
|
|
2082
|
-
sourceTexture,
|
|
2083
|
-
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2084
|
-
0
|
|
2085
|
-
);
|
|
2086
|
-
sum += textureLoad(
|
|
2087
|
-
sourceTexture,
|
|
2088
|
-
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2089
|
-
0
|
|
2090
|
-
);
|
|
2091
|
-
sum += textureLoad(
|
|
2092
|
-
sourceTexture,
|
|
2093
|
-
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2094
|
-
0
|
|
2095
|
-
);
|
|
2096
|
-
|
|
2097
|
-
textureStore(
|
|
2098
|
-
destinationTexture,
|
|
2099
|
-
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2100
|
-
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2101
|
-
);
|
|
2102
|
-
}
|
|
2103
|
-
`;
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2106
1575
|
// dist/dynamic-texture/dynamic-texture.js
|
|
2107
1576
|
var _DynamicTexture = class {
|
|
2108
1577
|
device;
|
|
@@ -2159,6 +1628,9 @@ var _DynamicTexture = class {
|
|
|
2159
1628
|
try {
|
|
2160
1629
|
const propsWithSyncData = await this._loadAllData(originalPropsWithAsyncData);
|
|
2161
1630
|
this._checkNotDestroyed();
|
|
1631
|
+
const subresources = propsWithSyncData.data ? getTextureSubresources(propsWithSyncData) : [];
|
|
1632
|
+
const userProvidedFormat = "format" in originalPropsWithAsyncData && originalPropsWithAsyncData.format !== void 0;
|
|
1633
|
+
const userProvidedUsage = "usage" in originalPropsWithAsyncData && originalPropsWithAsyncData.usage !== void 0;
|
|
2162
1634
|
const deduceSize = () => {
|
|
2163
1635
|
if (this.props.width && this.props.height) {
|
|
2164
1636
|
return { width: this.props.width, height: this.props.height };
|
|
@@ -2173,54 +1645,44 @@ var _DynamicTexture = class {
|
|
|
2173
1645
|
if (!size || size.width <= 0 || size.height <= 0) {
|
|
2174
1646
|
throw new Error(`${this} size could not be determined or was zero`);
|
|
2175
1647
|
}
|
|
1648
|
+
const textureData = analyzeTextureSubresources(this.device, subresources, size, {
|
|
1649
|
+
format: userProvidedFormat ? originalPropsWithAsyncData.format : void 0
|
|
1650
|
+
});
|
|
1651
|
+
const resolvedFormat = textureData.format ?? this.props.format;
|
|
2176
1652
|
const baseTextureProps = {
|
|
2177
1653
|
...this.props,
|
|
2178
1654
|
...size,
|
|
1655
|
+
format: resolvedFormat,
|
|
2179
1656
|
mipLevels: 1,
|
|
2180
1657
|
// temporary; updated below
|
|
2181
1658
|
data: void 0
|
|
2182
1659
|
};
|
|
2183
|
-
if (this.device.
|
|
2184
|
-
|
|
1660
|
+
if (this.device.isTextureFormatCompressed(resolvedFormat) && !userProvidedUsage) {
|
|
1661
|
+
baseTextureProps.usage = import_core9.Texture.SAMPLE | import_core9.Texture.COPY_DST;
|
|
1662
|
+
}
|
|
1663
|
+
const shouldGenerateMipmaps = this.props.mipmaps && !textureData.hasExplicitMipChain && !this.device.isTextureFormatCompressed(resolvedFormat);
|
|
1664
|
+
if (this.device.type === "webgpu" && shouldGenerateMipmaps) {
|
|
1665
|
+
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;
|
|
2185
1666
|
baseTextureProps.usage |= requiredUsage;
|
|
2186
1667
|
}
|
|
2187
1668
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
2188
|
-
const desired = this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1669
|
+
const desired = textureData.hasExplicitMipChain ? textureData.mipLevels : this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
2189
1670
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
2190
1671
|
this._texture = this.device.createTexture(finalTextureProps);
|
|
2191
1672
|
this._sampler = this.texture.sampler;
|
|
2192
1673
|
this._view = this.texture.view;
|
|
2193
|
-
if (
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
case "2d":
|
|
2199
|
-
this.setTexture2DData(propsWithSyncData.data);
|
|
2200
|
-
break;
|
|
2201
|
-
case "3d":
|
|
2202
|
-
this.setTexture3DData(propsWithSyncData.data);
|
|
2203
|
-
break;
|
|
2204
|
-
case "2d-array":
|
|
2205
|
-
this.setTextureArrayData(propsWithSyncData.data);
|
|
2206
|
-
break;
|
|
2207
|
-
case "cube":
|
|
2208
|
-
this.setTextureCubeData(propsWithSyncData.data);
|
|
2209
|
-
break;
|
|
2210
|
-
case "cube-array":
|
|
2211
|
-
this.setTextureCubeArrayData(propsWithSyncData.data);
|
|
2212
|
-
break;
|
|
2213
|
-
default: {
|
|
2214
|
-
throw new Error(`Unhandled dimension ${propsWithSyncData.dimension}`);
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
1674
|
+
if (textureData.subresources.length) {
|
|
1675
|
+
this._setTextureSubresources(textureData.subresources);
|
|
1676
|
+
}
|
|
1677
|
+
if (this.props.mipmaps && !textureData.hasExplicitMipChain && !shouldGenerateMipmaps) {
|
|
1678
|
+
import_core9.log.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)();
|
|
2217
1679
|
}
|
|
2218
|
-
if (
|
|
1680
|
+
if (shouldGenerateMipmaps) {
|
|
2219
1681
|
this.generateMipmaps();
|
|
2220
1682
|
}
|
|
2221
1683
|
this.isReady = true;
|
|
2222
1684
|
this.resolveReady(this.texture);
|
|
2223
|
-
|
|
1685
|
+
import_core9.log.info(0, `${this} created`)();
|
|
2224
1686
|
} catch (e) {
|
|
2225
1687
|
const err = e instanceof Error ? e : new Error(String(e));
|
|
2226
1688
|
this.rejectReady(err);
|
|
@@ -2240,15 +1702,15 @@ var _DynamicTexture = class {
|
|
|
2240
1702
|
if (this.device.type === "webgl") {
|
|
2241
1703
|
this.texture.generateMipmapsWebGL();
|
|
2242
1704
|
} else if (this.device.type === "webgpu") {
|
|
2243
|
-
|
|
1705
|
+
this.device.generateMipmapsWebGPU(this.texture);
|
|
2244
1706
|
} else {
|
|
2245
|
-
|
|
1707
|
+
import_core9.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
2246
1708
|
}
|
|
2247
1709
|
}
|
|
2248
1710
|
/** Set sampler or create one from props */
|
|
2249
1711
|
setSampler(sampler = {}) {
|
|
2250
1712
|
this._checkReady();
|
|
2251
|
-
const s = sampler instanceof
|
|
1713
|
+
const s = sampler instanceof import_core9.Sampler ? sampler : this.device.createSampler(sampler);
|
|
2252
1714
|
this.texture.setSampler(s);
|
|
2253
1715
|
this._sampler = s;
|
|
2254
1716
|
}
|
|
@@ -2266,7 +1728,7 @@ var _DynamicTexture = class {
|
|
|
2266
1728
|
this._sampler = this.texture.sampler;
|
|
2267
1729
|
this._view = this.texture.view;
|
|
2268
1730
|
prev.destroy();
|
|
2269
|
-
|
|
1731
|
+
import_core9.log.info(`${this} resized`);
|
|
2270
1732
|
return true;
|
|
2271
1733
|
}
|
|
2272
1734
|
/** Convert cube face label to texture slice index. Index can be used with `setTexture2DData()`. */
|
|
@@ -2340,8 +1802,11 @@ var _DynamicTexture = class {
|
|
|
2340
1802
|
this.texture.copyExternalImage({ image, z, mipLevel, flipY });
|
|
2341
1803
|
break;
|
|
2342
1804
|
case "texture-data":
|
|
2343
|
-
const { data } = subresource;
|
|
2344
|
-
this.texture.
|
|
1805
|
+
const { data, textureFormat } = subresource;
|
|
1806
|
+
if (textureFormat && textureFormat !== this.texture.format) {
|
|
1807
|
+
throw new Error(`${this} mip level ${mipLevel} uses format "${textureFormat}" but texture format is "${this.texture.format}"`);
|
|
1808
|
+
}
|
|
1809
|
+
this.texture.writeData(data.data, {
|
|
2345
1810
|
x: 0,
|
|
2346
1811
|
y: 0,
|
|
2347
1812
|
z,
|
|
@@ -2365,38 +1830,149 @@ var _DynamicTexture = class {
|
|
|
2365
1830
|
}
|
|
2366
1831
|
_checkNotDestroyed() {
|
|
2367
1832
|
if (this.destroyed) {
|
|
2368
|
-
|
|
1833
|
+
import_core9.log.warn(`${this} already destroyed`);
|
|
2369
1834
|
}
|
|
2370
1835
|
}
|
|
2371
1836
|
_checkReady() {
|
|
2372
1837
|
if (!this.isReady) {
|
|
2373
|
-
|
|
1838
|
+
import_core9.log.warn(`${this} Cannot perform this operation before ready`);
|
|
2374
1839
|
}
|
|
2375
1840
|
}
|
|
2376
1841
|
};
|
|
2377
1842
|
var DynamicTexture = _DynamicTexture;
|
|
2378
1843
|
__publicField(DynamicTexture, "defaultProps", {
|
|
2379
|
-
...
|
|
1844
|
+
...import_core9.Texture.defaultProps,
|
|
2380
1845
|
dimension: "2d",
|
|
2381
1846
|
data: null,
|
|
2382
1847
|
mipmaps: false
|
|
2383
1848
|
});
|
|
2384
|
-
function
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
1849
|
+
function getTextureSubresources(props) {
|
|
1850
|
+
if (!props.data) {
|
|
1851
|
+
return [];
|
|
1852
|
+
}
|
|
1853
|
+
switch (props.dimension) {
|
|
1854
|
+
case "1d":
|
|
1855
|
+
return getTexture1DSubresources(props.data);
|
|
1856
|
+
case "2d":
|
|
1857
|
+
return getTexture2DSubresources(0, props.data);
|
|
1858
|
+
case "3d":
|
|
1859
|
+
return getTexture3DSubresources(props.data);
|
|
1860
|
+
case "2d-array":
|
|
1861
|
+
return getTextureArraySubresources(props.data);
|
|
1862
|
+
case "cube":
|
|
1863
|
+
return getTextureCubeSubresources(props.data);
|
|
1864
|
+
case "cube-array":
|
|
1865
|
+
return getTextureCubeArraySubresources(props.data);
|
|
1866
|
+
default:
|
|
1867
|
+
throw new Error(`Unhandled dimension ${props.dimension}`);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
function analyzeTextureSubresources(device, subresources, size, options) {
|
|
1871
|
+
if (subresources.length === 0) {
|
|
1872
|
+
return {
|
|
1873
|
+
subresources,
|
|
1874
|
+
mipLevels: 1,
|
|
1875
|
+
format: options.format,
|
|
1876
|
+
hasExplicitMipChain: false
|
|
1877
|
+
};
|
|
1878
|
+
}
|
|
1879
|
+
const groupedSubresources = /* @__PURE__ */ new Map();
|
|
1880
|
+
for (const subresource of subresources) {
|
|
1881
|
+
const group = groupedSubresources.get(subresource.z) ?? [];
|
|
1882
|
+
group.push(subresource);
|
|
1883
|
+
groupedSubresources.set(subresource.z, group);
|
|
1884
|
+
}
|
|
1885
|
+
const hasExplicitMipChain = subresources.some((subresource) => subresource.mipLevel > 0);
|
|
1886
|
+
let resolvedFormat = options.format;
|
|
1887
|
+
let resolvedMipLevels = Number.POSITIVE_INFINITY;
|
|
1888
|
+
const validSubresources = [];
|
|
1889
|
+
for (const [z, sliceSubresources] of groupedSubresources) {
|
|
1890
|
+
const sortedSubresources = [...sliceSubresources].sort((left, right) => left.mipLevel - right.mipLevel);
|
|
1891
|
+
const baseLevel = sortedSubresources[0];
|
|
1892
|
+
if (!baseLevel || baseLevel.mipLevel !== 0) {
|
|
1893
|
+
throw new Error(`DynamicTexture: slice ${z} is missing mip level 0`);
|
|
1894
|
+
}
|
|
1895
|
+
const baseSize = getTextureSubresourceSize(device, baseLevel);
|
|
1896
|
+
if (baseSize.width !== size.width || baseSize.height !== size.height) {
|
|
1897
|
+
throw new Error(`DynamicTexture: slice ${z} base level dimensions ${baseSize.width}x${baseSize.height} do not match expected ${size.width}x${size.height}`);
|
|
1898
|
+
}
|
|
1899
|
+
const baseFormat = getTextureSubresourceFormat(baseLevel);
|
|
1900
|
+
if (baseFormat) {
|
|
1901
|
+
if (resolvedFormat && resolvedFormat !== baseFormat) {
|
|
1902
|
+
throw new Error(`DynamicTexture: slice ${z} base level format "${baseFormat}" does not match texture format "${resolvedFormat}"`);
|
|
1903
|
+
}
|
|
1904
|
+
resolvedFormat = baseFormat;
|
|
1905
|
+
}
|
|
1906
|
+
const mipLevelLimit = resolvedFormat && device.isTextureFormatCompressed(resolvedFormat) ? (
|
|
1907
|
+
// Block-compressed formats cannot have mips smaller than a single compression block.
|
|
1908
|
+
getMaxCompressedMipLevels(device, baseSize.width, baseSize.height, resolvedFormat)
|
|
1909
|
+
) : device.getMipLevelCount(baseSize.width, baseSize.height);
|
|
1910
|
+
let validMipLevelsForSlice = 0;
|
|
1911
|
+
for (let expectedMipLevel = 0; expectedMipLevel < sortedSubresources.length; expectedMipLevel++) {
|
|
1912
|
+
const subresource = sortedSubresources[expectedMipLevel];
|
|
1913
|
+
if (!subresource || subresource.mipLevel !== expectedMipLevel) {
|
|
1914
|
+
break;
|
|
1915
|
+
}
|
|
1916
|
+
if (expectedMipLevel >= mipLevelLimit) {
|
|
1917
|
+
break;
|
|
1918
|
+
}
|
|
1919
|
+
const subresourceSize = getTextureSubresourceSize(device, subresource);
|
|
1920
|
+
const expectedWidth = Math.max(1, baseSize.width >> expectedMipLevel);
|
|
1921
|
+
const expectedHeight = Math.max(1, baseSize.height >> expectedMipLevel);
|
|
1922
|
+
if (subresourceSize.width !== expectedWidth || subresourceSize.height !== expectedHeight) {
|
|
1923
|
+
break;
|
|
1924
|
+
}
|
|
1925
|
+
const subresourceFormat = getTextureSubresourceFormat(subresource);
|
|
1926
|
+
if (subresourceFormat) {
|
|
1927
|
+
if (!resolvedFormat) {
|
|
1928
|
+
resolvedFormat = subresourceFormat;
|
|
1929
|
+
}
|
|
1930
|
+
if (subresourceFormat !== resolvedFormat) {
|
|
1931
|
+
break;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
validMipLevelsForSlice++;
|
|
1935
|
+
validSubresources.push(subresource);
|
|
1936
|
+
}
|
|
1937
|
+
resolvedMipLevels = Math.min(resolvedMipLevels, validMipLevelsForSlice);
|
|
1938
|
+
}
|
|
1939
|
+
const mipLevels = Number.isFinite(resolvedMipLevels) ? Math.max(1, resolvedMipLevels) : 1;
|
|
1940
|
+
return {
|
|
1941
|
+
// Keep every slice trimmed to the same mip count so the texture shape stays internally consistent.
|
|
1942
|
+
subresources: validSubresources.filter((subresource) => subresource.mipLevel < mipLevels),
|
|
1943
|
+
mipLevels,
|
|
1944
|
+
format: resolvedFormat,
|
|
1945
|
+
hasExplicitMipChain
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
function getTextureSubresourceFormat(subresource) {
|
|
1949
|
+
if (subresource.type !== "texture-data") {
|
|
1950
|
+
return void 0;
|
|
1951
|
+
}
|
|
1952
|
+
return subresource.textureFormat ?? resolveTextureImageFormat(subresource.data);
|
|
1953
|
+
}
|
|
1954
|
+
function getTextureSubresourceSize(device, subresource) {
|
|
1955
|
+
switch (subresource.type) {
|
|
1956
|
+
case "external-image":
|
|
1957
|
+
return device.getExternalImageSize(subresource.image);
|
|
1958
|
+
case "texture-data":
|
|
1959
|
+
return { width: subresource.data.width, height: subresource.data.height };
|
|
1960
|
+
default:
|
|
1961
|
+
throw new Error("Unsupported texture subresource");
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
function getMaxCompressedMipLevels(device, baseWidth, baseHeight, format) {
|
|
1965
|
+
const { blockWidth = 1, blockHeight = 1 } = device.getTextureFormatInfo(format);
|
|
1966
|
+
let mipLevels = 1;
|
|
1967
|
+
for (let mipLevel = 1; ; mipLevel++) {
|
|
1968
|
+
const width = Math.max(1, baseWidth >> mipLevel);
|
|
1969
|
+
const height = Math.max(1, baseHeight >> mipLevel);
|
|
1970
|
+
if (width < blockWidth || height < blockHeight) {
|
|
1971
|
+
break;
|
|
1972
|
+
}
|
|
1973
|
+
mipLevels++;
|
|
1974
|
+
}
|
|
1975
|
+
return mipLevels;
|
|
2400
1976
|
}
|
|
2401
1977
|
async function awaitAllPromises(x) {
|
|
2402
1978
|
x = await x;
|
|
@@ -2417,8 +1993,8 @@ async function awaitAllPromises(x) {
|
|
|
2417
1993
|
}
|
|
2418
1994
|
|
|
2419
1995
|
// dist/model/model.js
|
|
2420
|
-
var
|
|
2421
|
-
var
|
|
1996
|
+
var LOG_DRAW_PRIORITY = 2;
|
|
1997
|
+
var LOG_DRAW_TIMEOUT = 1e4;
|
|
2422
1998
|
var _Model = class {
|
|
2423
1999
|
/** Device that created this model */
|
|
2424
2000
|
device;
|
|
@@ -2500,7 +2076,7 @@ var _Model = class {
|
|
|
2500
2076
|
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
2501
2077
|
const shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap, { disableWarnings: this.props.disableWarnings });
|
|
2502
2078
|
this.setShaderInputs(shaderInputs);
|
|
2503
|
-
const platformInfo =
|
|
2079
|
+
const platformInfo = getPlatformInfo(device);
|
|
2504
2080
|
const modules = (
|
|
2505
2081
|
// @ts-ignore shaderInputs is assigned in setShaderInputs above.
|
|
2506
2082
|
(((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || []
|
|
@@ -2573,7 +2149,7 @@ var _Model = class {
|
|
|
2573
2149
|
if (!this._destroyed) {
|
|
2574
2150
|
this.pipelineFactory.release(this.pipeline);
|
|
2575
2151
|
this.shaderFactory.release(this.pipeline.vs);
|
|
2576
|
-
if (this.pipeline.fs) {
|
|
2152
|
+
if (this.pipeline.fs && this.pipeline.fs !== this.pipeline.vs) {
|
|
2577
2153
|
this.shaderFactory.release(this.pipeline.fs);
|
|
2578
2154
|
}
|
|
2579
2155
|
this._uniformStore.destroy();
|
|
@@ -2608,7 +2184,7 @@ var _Model = class {
|
|
|
2608
2184
|
draw(renderPass) {
|
|
2609
2185
|
const loadingBinding = this._areBindingsLoading();
|
|
2610
2186
|
if (loadingBinding) {
|
|
2611
|
-
|
|
2187
|
+
import_core10.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
2612
2188
|
return false;
|
|
2613
2189
|
}
|
|
2614
2190
|
try {
|
|
@@ -2623,9 +2199,6 @@ var _Model = class {
|
|
|
2623
2199
|
this._logDrawCallStart();
|
|
2624
2200
|
this.pipeline = this._updatePipeline();
|
|
2625
2201
|
const syncBindings = this._getBindings();
|
|
2626
|
-
this.pipeline.setBindings(syncBindings, {
|
|
2627
|
-
disableWarnings: this.props.disableWarnings
|
|
2628
|
-
});
|
|
2629
2202
|
const { indexBuffer } = this.vertexArray;
|
|
2630
2203
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
2631
2204
|
drawSuccess = this.pipeline.draw({
|
|
@@ -2636,6 +2209,11 @@ var _Model = class {
|
|
|
2636
2209
|
instanceCount: this.instanceCount,
|
|
2637
2210
|
indexCount,
|
|
2638
2211
|
transformFeedback: this.transformFeedback || void 0,
|
|
2212
|
+
// Pipelines may be shared across models when caching is enabled, so bindings
|
|
2213
|
+
// and WebGL uniforms must be supplied on every draw instead of being stored
|
|
2214
|
+
// on the pipeline instance.
|
|
2215
|
+
bindings: syncBindings,
|
|
2216
|
+
uniforms: this.props.uniforms,
|
|
2639
2217
|
// WebGL shares underlying cached pipelines even for models that have different parameters and topology,
|
|
2640
2218
|
// so we must provide our unique parameters to each draw
|
|
2641
2219
|
// (In WebGPU most parameters are encoded in the pipeline and cannot be changed per draw call)
|
|
@@ -2736,7 +2314,7 @@ var _Model = class {
|
|
|
2736
2314
|
/** Set the shader inputs */
|
|
2737
2315
|
setShaderInputs(shaderInputs) {
|
|
2738
2316
|
this.shaderInputs = shaderInputs;
|
|
2739
|
-
this._uniformStore = new
|
|
2317
|
+
this._uniformStore = new import_core10.UniformStore(this.shaderInputs.modules);
|
|
2740
2318
|
for (const [moduleName, module2] of Object.entries(this.shaderInputs.modules)) {
|
|
2741
2319
|
if (shaderModuleHasUniforms(module2)) {
|
|
2742
2320
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
@@ -2780,7 +2358,7 @@ var _Model = class {
|
|
|
2780
2358
|
setAttributes(buffers, options) {
|
|
2781
2359
|
const disableWarnings = (options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings;
|
|
2782
2360
|
if (buffers["indices"]) {
|
|
2783
|
-
|
|
2361
|
+
import_core10.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
|
|
2784
2362
|
}
|
|
2785
2363
|
this.bufferLayout = sortedBufferLayoutByShaderSourceLocations(this.pipeline.shaderLayout, this.bufferLayout);
|
|
2786
2364
|
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
@@ -2788,7 +2366,7 @@ var _Model = class {
|
|
|
2788
2366
|
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
2789
2367
|
if (!bufferLayout) {
|
|
2790
2368
|
if (!disableWarnings) {
|
|
2791
|
-
|
|
2369
|
+
import_core10.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
2792
2370
|
}
|
|
2793
2371
|
continue;
|
|
2794
2372
|
}
|
|
@@ -2803,7 +2381,7 @@ var _Model = class {
|
|
|
2803
2381
|
}
|
|
2804
2382
|
}
|
|
2805
2383
|
if (!set && !disableWarnings) {
|
|
2806
|
-
|
|
2384
|
+
import_core10.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
|
|
2807
2385
|
}
|
|
2808
2386
|
}
|
|
2809
2387
|
this.setNeedsRedraw("attributes");
|
|
@@ -2822,7 +2400,7 @@ var _Model = class {
|
|
|
2822
2400
|
if (attributeInfo) {
|
|
2823
2401
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
2824
2402
|
} else if (!((options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings)) {
|
|
2825
|
-
|
|
2403
|
+
import_core10.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
|
|
2826
2404
|
}
|
|
2827
2405
|
}
|
|
2828
2406
|
this.setNeedsRedraw("constants");
|
|
@@ -2855,16 +2433,16 @@ var _Model = class {
|
|
|
2855
2433
|
_getBindingsUpdateTimestamp() {
|
|
2856
2434
|
let timestamp = 0;
|
|
2857
2435
|
for (const binding of Object.values(this.bindings)) {
|
|
2858
|
-
if (binding instanceof
|
|
2436
|
+
if (binding instanceof import_core10.TextureView) {
|
|
2859
2437
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
2860
|
-
} else if (binding instanceof
|
|
2438
|
+
} else if (binding instanceof import_core10.Buffer || binding instanceof import_core10.Texture) {
|
|
2861
2439
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
2862
2440
|
} else if (binding instanceof DynamicTexture) {
|
|
2863
2441
|
timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
|
|
2864
2442
|
// The texture will become available in the future
|
|
2865
2443
|
Infinity
|
|
2866
2444
|
);
|
|
2867
|
-
} else if (!(binding instanceof
|
|
2445
|
+
} else if (!(binding instanceof import_core10.Sampler)) {
|
|
2868
2446
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
2869
2447
|
}
|
|
2870
2448
|
}
|
|
@@ -2899,7 +2477,7 @@ var _Model = class {
|
|
|
2899
2477
|
let prevShaderVs = null;
|
|
2900
2478
|
let prevShaderFs = null;
|
|
2901
2479
|
if (this.pipeline) {
|
|
2902
|
-
|
|
2480
|
+
import_core10.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
2903
2481
|
prevShaderVs = this.pipeline.vs;
|
|
2904
2482
|
prevShaderFs = this.pipeline.fs;
|
|
2905
2483
|
}
|
|
@@ -2932,11 +2510,12 @@ var _Model = class {
|
|
|
2932
2510
|
vs: vs3,
|
|
2933
2511
|
fs: fs3
|
|
2934
2512
|
});
|
|
2935
|
-
this._attributeInfos = (0,
|
|
2513
|
+
this._attributeInfos = (0, import_core10.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
|
|
2936
2514
|
if (prevShaderVs)
|
|
2937
2515
|
this.shaderFactory.release(prevShaderVs);
|
|
2938
|
-
if (prevShaderFs)
|
|
2516
|
+
if (prevShaderFs && prevShaderFs !== prevShaderVs) {
|
|
2939
2517
|
this.shaderFactory.release(prevShaderFs);
|
|
2518
|
+
}
|
|
2940
2519
|
}
|
|
2941
2520
|
return this.pipeline;
|
|
2942
2521
|
}
|
|
@@ -2944,24 +2523,24 @@ var _Model = class {
|
|
|
2944
2523
|
_lastLogTime = 0;
|
|
2945
2524
|
_logOpen = false;
|
|
2946
2525
|
_logDrawCallStart() {
|
|
2947
|
-
const logDrawTimeout =
|
|
2948
|
-
if (
|
|
2526
|
+
const logDrawTimeout = import_core10.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
2527
|
+
if (import_core10.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
2949
2528
|
return;
|
|
2950
2529
|
}
|
|
2951
2530
|
this._lastLogTime = Date.now();
|
|
2952
2531
|
this._logOpen = true;
|
|
2953
|
-
|
|
2532
|
+
import_core10.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core10.log.level <= 2 })();
|
|
2954
2533
|
}
|
|
2955
2534
|
_logDrawCallEnd() {
|
|
2956
2535
|
if (this._logOpen) {
|
|
2957
2536
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
2958
|
-
|
|
2537
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
|
|
2959
2538
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
2960
|
-
|
|
2539
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
2961
2540
|
const attributeTable = this._getAttributeDebugTable();
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2541
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
|
|
2542
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, attributeTable)();
|
|
2543
|
+
import_core10.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
2965
2544
|
this._logOpen = false;
|
|
2966
2545
|
}
|
|
2967
2546
|
}
|
|
@@ -3000,14 +2579,14 @@ var _Model = class {
|
|
|
3000
2579
|
}
|
|
3001
2580
|
// TODO - fix typing of luma data types
|
|
3002
2581
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
3003
|
-
const TypedArrayConstructor = (0,
|
|
3004
|
-
const typedArray = attribute instanceof
|
|
2582
|
+
const TypedArrayConstructor = (0, import_core10.getTypedArrayConstructor)(dataType);
|
|
2583
|
+
const typedArray = attribute instanceof import_core10.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
3005
2584
|
return typedArray.toString();
|
|
3006
2585
|
}
|
|
3007
2586
|
};
|
|
3008
2587
|
var Model = _Model;
|
|
3009
2588
|
__publicField(Model, "defaultProps", {
|
|
3010
|
-
...
|
|
2589
|
+
...import_core10.RenderPipeline.defaultProps,
|
|
3011
2590
|
source: void 0,
|
|
3012
2591
|
vs: null,
|
|
3013
2592
|
fs: null,
|
|
@@ -3020,6 +2599,8 @@ __publicField(Model, "defaultProps", {
|
|
|
3020
2599
|
indexBuffer: null,
|
|
3021
2600
|
attributes: {},
|
|
3022
2601
|
constantAttributes: {},
|
|
2602
|
+
bindings: {},
|
|
2603
|
+
uniforms: {},
|
|
3023
2604
|
varyings: [],
|
|
3024
2605
|
isInstanced: void 0,
|
|
3025
2606
|
instanceCount: 0,
|
|
@@ -3028,14 +2609,14 @@ __publicField(Model, "defaultProps", {
|
|
|
3028
2609
|
pipelineFactory: void 0,
|
|
3029
2610
|
shaderFactory: void 0,
|
|
3030
2611
|
transformFeedback: void 0,
|
|
3031
|
-
shaderAssembler:
|
|
2612
|
+
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
3032
2613
|
debugShaders: void 0,
|
|
3033
2614
|
disableWarnings: void 0
|
|
3034
2615
|
});
|
|
3035
2616
|
function shaderModuleHasUniforms(module2) {
|
|
3036
2617
|
return Boolean(module2.uniformTypes && !isObjectEmpty(module2.uniformTypes));
|
|
3037
2618
|
}
|
|
3038
|
-
function
|
|
2619
|
+
function getPlatformInfo(device) {
|
|
3039
2620
|
return {
|
|
3040
2621
|
type: device.type,
|
|
3041
2622
|
shaderLanguage: device.info.shadingLanguage,
|
|
@@ -3053,8 +2634,8 @@ function isObjectEmpty(obj) {
|
|
|
3053
2634
|
}
|
|
3054
2635
|
|
|
3055
2636
|
// dist/compute/buffer-transform.js
|
|
3056
|
-
var
|
|
3057
|
-
var
|
|
2637
|
+
var import_core11 = require("@luma.gl/core");
|
|
2638
|
+
var import_shadertools3 = require("@luma.gl/shadertools");
|
|
3058
2639
|
var _BufferTransform = class {
|
|
3059
2640
|
device;
|
|
3060
2641
|
model;
|
|
@@ -3070,7 +2651,7 @@ var _BufferTransform = class {
|
|
|
3070
2651
|
this.device = device;
|
|
3071
2652
|
this.model = new Model(this.device, {
|
|
3072
2653
|
id: props.id || "buffer-transform-model",
|
|
3073
|
-
fs: props.fs || (0,
|
|
2654
|
+
fs: props.fs || (0, import_shadertools3.getPassthroughFS)(),
|
|
3074
2655
|
topology: props.topology || "point-list",
|
|
3075
2656
|
varyings: props.outputs || props.varyings,
|
|
3076
2657
|
...props
|
|
@@ -3116,7 +2697,7 @@ var _BufferTransform = class {
|
|
|
3116
2697
|
if (!result) {
|
|
3117
2698
|
throw new Error("BufferTransform#getBuffer");
|
|
3118
2699
|
}
|
|
3119
|
-
if (result instanceof
|
|
2700
|
+
if (result instanceof import_core11.Buffer) {
|
|
3120
2701
|
return result.readAsync();
|
|
3121
2702
|
}
|
|
3122
2703
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -3131,7 +2712,7 @@ __publicField(BufferTransform, "defaultProps", {
|
|
|
3131
2712
|
});
|
|
3132
2713
|
|
|
3133
2714
|
// dist/compute/texture-transform.js
|
|
3134
|
-
var
|
|
2715
|
+
var import_shadertools4 = require("@luma.gl/shadertools");
|
|
3135
2716
|
var FS_OUTPUT_VARIABLE = "transform_output";
|
|
3136
2717
|
var TextureTransform = class {
|
|
3137
2718
|
device;
|
|
@@ -3154,7 +2735,7 @@ var TextureTransform = class {
|
|
|
3154
2735
|
});
|
|
3155
2736
|
this.model = new Model(this.device, {
|
|
3156
2737
|
id: props.id || uid("texture-transform-model"),
|
|
3157
|
-
fs: props.fs || (0,
|
|
2738
|
+
fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
|
|
3158
2739
|
input: props.targetTextureVarying,
|
|
3159
2740
|
inputChannels: props.targetTextureChannels,
|
|
3160
2741
|
output: FS_OUTPUT_VARIABLE
|
|
@@ -3324,9 +2905,9 @@ var Geometry = class {
|
|
|
3324
2905
|
var CLIPSPACE_VERTEX_SHADER_WGSL = (
|
|
3325
2906
|
/* wgsl */
|
|
3326
2907
|
`struct VertexInputs {
|
|
3327
|
-
@location(0)
|
|
3328
|
-
@location(1)
|
|
3329
|
-
@location(2)
|
|
2908
|
+
@location(0) clipSpacePositions: vec2<f32>,
|
|
2909
|
+
@location(1) texCoords: vec2<f32>,
|
|
2910
|
+
@location(2) coordinates: vec2<f32>
|
|
3330
2911
|
}
|
|
3331
2912
|
|
|
3332
2913
|
struct FragmentInputs {
|
|
@@ -3339,10 +2920,10 @@ struct FragmentInputs {
|
|
|
3339
2920
|
@vertex
|
|
3340
2921
|
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
3341
2922
|
var outputs: FragmentInputs;
|
|
3342
|
-
outputs.Position = vec4(inputs.
|
|
3343
|
-
outputs.position = inputs.
|
|
3344
|
-
outputs.coordinate = inputs.
|
|
3345
|
-
outputs.uv = inputs.
|
|
2923
|
+
outputs.Position = vec4(inputs.clipSpacePositions, 0., 1.);
|
|
2924
|
+
outputs.position = inputs.clipSpacePositions;
|
|
2925
|
+
outputs.coordinate = inputs.coordinates;
|
|
2926
|
+
outputs.uv = inputs.texCoords;
|
|
3346
2927
|
return outputs;
|
|
3347
2928
|
}
|
|
3348
2929
|
`
|
|
@@ -3408,15 +2989,15 @@ struct backgroundUniforms {
|
|
|
3408
2989
|
};
|
|
3409
2990
|
@group(0) @binding(2) var<uniform> background: backgroundUniforms;
|
|
3410
2991
|
|
|
3411
|
-
fn billboardTexture_getTextureUV(
|
|
2992
|
+
fn billboardTexture_getTextureUV(uv: vec2<f32>) -> vec2<f32> {
|
|
3412
2993
|
let scale: vec2<f32> = background.scale;
|
|
3413
|
-
var position: vec2<f32> = (
|
|
2994
|
+
var position: vec2<f32> = (uv - vec2<f32>(0.5, 0.5)) / scale + vec2<f32>(0.5, 0.5);
|
|
3414
2995
|
return position;
|
|
3415
2996
|
}
|
|
3416
2997
|
|
|
3417
2998
|
@fragment
|
|
3418
2999
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
3419
|
-
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.
|
|
3000
|
+
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.uv);
|
|
3420
3001
|
return textureSample(backgroundTexture, backgroundTextureSampler, position);
|
|
3421
3002
|
}
|
|
3422
3003
|
`
|
|
@@ -3450,20 +3031,22 @@ var BackgroundTextureModel = class extends ClipSpace {
|
|
|
3450
3031
|
backgroundTexture = null;
|
|
3451
3032
|
constructor(device, props) {
|
|
3452
3033
|
super(device, {
|
|
3034
|
+
...props,
|
|
3453
3035
|
id: props.id || "background-texture-model",
|
|
3454
3036
|
source: BACKGROUND_FS_WGSL,
|
|
3455
3037
|
fs: BACKGROUND_FS,
|
|
3456
|
-
modules: [backgroundModule],
|
|
3038
|
+
modules: [...props.modules || [], backgroundModule],
|
|
3457
3039
|
parameters: {
|
|
3458
3040
|
depthWriteEnabled: false,
|
|
3041
|
+
...props.parameters || {},
|
|
3459
3042
|
...props.blend ? {
|
|
3460
3043
|
blend: true,
|
|
3461
3044
|
blendColorOperation: "add",
|
|
3462
3045
|
blendAlphaOperation: "add",
|
|
3463
|
-
blendColorSrcFactor: "one",
|
|
3464
|
-
blendColorDstFactor: "one
|
|
3465
|
-
blendAlphaSrcFactor: "one",
|
|
3466
|
-
blendAlphaDstFactor: "one
|
|
3046
|
+
blendColorSrcFactor: "one-minus-dst-alpha",
|
|
3047
|
+
blendColorDstFactor: "one",
|
|
3048
|
+
blendAlphaSrcFactor: "one-minus-dst-alpha",
|
|
3049
|
+
blendAlphaDstFactor: "one"
|
|
3467
3050
|
} : {}
|
|
3468
3051
|
}
|
|
3469
3052
|
});
|
|
@@ -3514,14 +3097,19 @@ var BackgroundTextureModel = class extends ClipSpace {
|
|
|
3514
3097
|
};
|
|
3515
3098
|
|
|
3516
3099
|
// dist/scenegraph/scenegraph-node.js
|
|
3517
|
-
var
|
|
3100
|
+
var import_core12 = require("@math.gl/core");
|
|
3101
|
+
function assert(condition, message) {
|
|
3102
|
+
if (!condition) {
|
|
3103
|
+
throw new Error(message);
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3518
3106
|
var ScenegraphNode = class {
|
|
3519
3107
|
id;
|
|
3520
|
-
matrix = new
|
|
3108
|
+
matrix = new import_core12.Matrix4();
|
|
3521
3109
|
display = true;
|
|
3522
|
-
position = new
|
|
3523
|
-
rotation = new
|
|
3524
|
-
scale = new
|
|
3110
|
+
position = new import_core12.Vector3();
|
|
3111
|
+
rotation = new import_core12.Vector3();
|
|
3112
|
+
scale = new import_core12.Vector3(1, 1, 1);
|
|
3525
3113
|
userData = {};
|
|
3526
3114
|
props = {};
|
|
3527
3115
|
constructor(props = {}) {
|
|
@@ -3546,14 +3134,17 @@ var ScenegraphNode = class {
|
|
|
3546
3134
|
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
3547
3135
|
}
|
|
3548
3136
|
setPosition(position) {
|
|
3137
|
+
assert(position.length === 3, "setPosition requires vector argument");
|
|
3549
3138
|
this.position = position;
|
|
3550
3139
|
return this;
|
|
3551
3140
|
}
|
|
3552
3141
|
setRotation(rotation) {
|
|
3142
|
+
assert(rotation.length === 3 || rotation.length === 4, "setRotation requires vector argument");
|
|
3553
3143
|
this.rotation = rotation;
|
|
3554
3144
|
return this;
|
|
3555
3145
|
}
|
|
3556
3146
|
setScale(scale) {
|
|
3147
|
+
assert(scale.length === 3, "setScale requires vector argument");
|
|
3557
3148
|
this.scale = scale;
|
|
3558
3149
|
return this;
|
|
3559
3150
|
}
|
|
@@ -3581,17 +3172,18 @@ var ScenegraphNode = class {
|
|
|
3581
3172
|
return this;
|
|
3582
3173
|
}
|
|
3583
3174
|
updateMatrix() {
|
|
3584
|
-
const pos = this.position;
|
|
3585
|
-
const rot = this.rotation;
|
|
3586
|
-
const scale = this.scale;
|
|
3587
3175
|
this.matrix.identity();
|
|
3588
|
-
this.matrix.translate(
|
|
3589
|
-
this.
|
|
3590
|
-
|
|
3176
|
+
this.matrix.translate(this.position);
|
|
3177
|
+
if (this.rotation.length === 4) {
|
|
3178
|
+
const rotationMatrix = new import_core12.Matrix4().fromQuaternion(this.rotation);
|
|
3179
|
+
this.matrix.multiplyRight(rotationMatrix);
|
|
3180
|
+
} else {
|
|
3181
|
+
this.matrix.rotateXYZ(this.rotation);
|
|
3182
|
+
}
|
|
3183
|
+
this.matrix.scale(this.scale);
|
|
3591
3184
|
return this;
|
|
3592
3185
|
}
|
|
3593
|
-
update(
|
|
3594
|
-
const { position, rotation, scale } = options;
|
|
3186
|
+
update({ position, rotation, scale } = {}) {
|
|
3595
3187
|
if (position) {
|
|
3596
3188
|
this.setPosition(position);
|
|
3597
3189
|
}
|
|
@@ -3606,7 +3198,7 @@ var ScenegraphNode = class {
|
|
|
3606
3198
|
}
|
|
3607
3199
|
getCoordinateUniforms(viewMatrix, modelMatrix) {
|
|
3608
3200
|
modelMatrix = modelMatrix || this.matrix;
|
|
3609
|
-
const worldMatrix = new
|
|
3201
|
+
const worldMatrix = new import_core12.Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
3610
3202
|
const worldInverse = worldMatrix.invert();
|
|
3611
3203
|
const worldInverseTranspose = worldInverse.transpose();
|
|
3612
3204
|
return {
|
|
@@ -3641,16 +3233,17 @@ var ScenegraphNode = class {
|
|
|
3641
3233
|
}
|
|
3642
3234
|
*/
|
|
3643
3235
|
_setScenegraphNodeProps(props) {
|
|
3644
|
-
if (
|
|
3236
|
+
if (props == null ? void 0 : props.position) {
|
|
3645
3237
|
this.setPosition(props.position);
|
|
3646
3238
|
}
|
|
3647
|
-
if (
|
|
3239
|
+
if (props == null ? void 0 : props.rotation) {
|
|
3648
3240
|
this.setRotation(props.rotation);
|
|
3649
3241
|
}
|
|
3650
|
-
if (
|
|
3242
|
+
if (props == null ? void 0 : props.scale) {
|
|
3651
3243
|
this.setScale(props.scale);
|
|
3652
3244
|
}
|
|
3653
|
-
|
|
3245
|
+
this.updateMatrix();
|
|
3246
|
+
if (props == null ? void 0 : props.matrix) {
|
|
3654
3247
|
this.setMatrix(props.matrix);
|
|
3655
3248
|
}
|
|
3656
3249
|
Object.assign(this.props, props);
|
|
@@ -3658,14 +3251,14 @@ var ScenegraphNode = class {
|
|
|
3658
3251
|
};
|
|
3659
3252
|
|
|
3660
3253
|
// dist/scenegraph/group-node.js
|
|
3661
|
-
var
|
|
3662
|
-
var
|
|
3254
|
+
var import_core13 = require("@math.gl/core");
|
|
3255
|
+
var import_core14 = require("@luma.gl/core");
|
|
3663
3256
|
var GroupNode = class extends ScenegraphNode {
|
|
3664
3257
|
children;
|
|
3665
3258
|
constructor(props = {}) {
|
|
3666
3259
|
props = Array.isArray(props) ? { children: props } : props;
|
|
3667
3260
|
const { children = [] } = props;
|
|
3668
|
-
|
|
3261
|
+
import_core14.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
|
|
3669
3262
|
super(props);
|
|
3670
3263
|
this.children = children;
|
|
3671
3264
|
}
|
|
@@ -3680,12 +3273,12 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3680
3273
|
return;
|
|
3681
3274
|
}
|
|
3682
3275
|
const [min, max] = bounds;
|
|
3683
|
-
const center = new
|
|
3276
|
+
const center = new import_core13.Vector3(min).add(max).divide([2, 2, 2]);
|
|
3684
3277
|
worldMatrix.transformAsPoint(center, center);
|
|
3685
|
-
const halfSize = new
|
|
3278
|
+
const halfSize = new import_core13.Vector3(max).subtract(min).divide([2, 2, 2]);
|
|
3686
3279
|
worldMatrix.transformAsVector(halfSize, halfSize);
|
|
3687
3280
|
for (let v = 0; v < 8; v++) {
|
|
3688
|
-
const position = new
|
|
3281
|
+
const position = new import_core13.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
|
|
3689
3282
|
for (let i = 0; i < 3; i++) {
|
|
3690
3283
|
result[0][i] = Math.min(result[0][i], position[i]);
|
|
3691
3284
|
result[1][i] = Math.max(result[1][i], position[i]);
|
|
@@ -3725,8 +3318,8 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3725
3318
|
this.children = [];
|
|
3726
3319
|
return this;
|
|
3727
3320
|
}
|
|
3728
|
-
traverse(visitor, { worldMatrix = new
|
|
3729
|
-
const modelMatrix = new
|
|
3321
|
+
traverse(visitor, { worldMatrix = new import_core13.Matrix4() } = {}) {
|
|
3322
|
+
const modelMatrix = new import_core13.Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
3730
3323
|
for (const child of this.children) {
|
|
3731
3324
|
if (child instanceof GroupNode) {
|
|
3732
3325
|
child.traverse(visitor, { worldMatrix: modelMatrix });
|
|
@@ -3735,6 +3328,17 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3735
3328
|
}
|
|
3736
3329
|
}
|
|
3737
3330
|
}
|
|
3331
|
+
preorderTraversal(visitor, { worldMatrix = new import_core13.Matrix4() } = {}) {
|
|
3332
|
+
const modelMatrix = new import_core13.Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
3333
|
+
visitor(this, { worldMatrix: modelMatrix });
|
|
3334
|
+
for (const child of this.children) {
|
|
3335
|
+
if (child instanceof GroupNode) {
|
|
3336
|
+
child.preorderTraversal(visitor, { worldMatrix: modelMatrix });
|
|
3337
|
+
} else {
|
|
3338
|
+
visitor(child, { worldMatrix: modelMatrix });
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3738
3342
|
};
|
|
3739
3343
|
|
|
3740
3344
|
// dist/scenegraph/model-node.js
|
|
@@ -4508,7 +4112,7 @@ var CylinderGeometry = class extends TruncatedConeGeometry {
|
|
|
4508
4112
|
};
|
|
4509
4113
|
|
|
4510
4114
|
// dist/geometries/ico-sphere-geometry.js
|
|
4511
|
-
var
|
|
4115
|
+
var import_core15 = require("@math.gl/core");
|
|
4512
4116
|
var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
|
|
4513
4117
|
var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
|
|
4514
4118
|
var IcoSphereGeometry = class extends Geometry {
|
|
@@ -4606,7 +4210,7 @@ function tesselateIcosaHedron(props) {
|
|
|
4606
4210
|
const u3 = 1 - phi3 / PI2;
|
|
4607
4211
|
const vec1 = [x3 - x2, y3 - y2, z3 - z2];
|
|
4608
4212
|
const vec2 = [x1 - x2, y1 - y2, z1 - z2];
|
|
4609
|
-
const normal = new
|
|
4213
|
+
const normal = new import_core15.Vector3(vec1).cross(vec2).normalize();
|
|
4610
4214
|
let newIndex;
|
|
4611
4215
|
if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
|
|
4612
4216
|
positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
|
|
@@ -4893,10 +4497,10 @@ async function loadImage(url, opts) {
|
|
|
4893
4497
|
}
|
|
4894
4498
|
|
|
4895
4499
|
// dist/passes/shader-pass-renderer.js
|
|
4896
|
-
var
|
|
4500
|
+
var import_shadertools5 = require("@luma.gl/shadertools");
|
|
4897
4501
|
|
|
4898
4502
|
// dist/compute/swap.js
|
|
4899
|
-
var
|
|
4503
|
+
var import_core16 = require("@luma.gl/core");
|
|
4900
4504
|
var Swap = class {
|
|
4901
4505
|
id;
|
|
4902
4506
|
/** The current resource - usually the source for renders or computations */
|
|
@@ -4929,7 +4533,7 @@ var SwapFramebuffers = class extends Swap {
|
|
|
4929
4533
|
let colorAttachments = (_a = props.colorAttachments) == null ? void 0 : _a.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
4930
4534
|
id: `${props.id}-texture-0`,
|
|
4931
4535
|
format: colorAttachment,
|
|
4932
|
-
usage:
|
|
4536
|
+
usage: import_core16.Texture.SAMPLE | import_core16.Texture.RENDER | import_core16.Texture.COPY_SRC | import_core16.Texture.COPY_DST,
|
|
4933
4537
|
width,
|
|
4934
4538
|
height
|
|
4935
4539
|
}));
|
|
@@ -4937,7 +4541,7 @@ var SwapFramebuffers = class extends Swap {
|
|
|
4937
4541
|
colorAttachments = (_b = props.colorAttachments) == null ? void 0 : _b.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
4938
4542
|
id: `${props.id}-texture-1`,
|
|
4939
4543
|
format: colorAttachment,
|
|
4940
|
-
usage:
|
|
4544
|
+
usage: import_core16.Texture.SAMPLE | import_core16.Texture.RENDER | import_core16.Texture.COPY_SRC | import_core16.Texture.COPY_DST,
|
|
4941
4545
|
width,
|
|
4942
4546
|
height
|
|
4943
4547
|
}));
|
|
@@ -5000,26 +4604,16 @@ function getFragmentShaderForRenderPass(options) {
|
|
|
5000
4604
|
function getFilterShaderWGSL(func) {
|
|
5001
4605
|
return (
|
|
5002
4606
|
/* wgsl */
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
5006
|
-
@group(0) @binding(2) var textureSampler: sampler;
|
|
5007
|
-
|
|
5008
|
-
// This needs to be aligned with
|
|
5009
|
-
// struct FragmentInputs {
|
|
5010
|
-
// @location(0) fragUV: vec2f,
|
|
5011
|
-
// @location(1) fragPosition: vec4f,
|
|
5012
|
-
// @location(2) fragCoordinate: vec4f
|
|
5013
|
-
// };
|
|
4607
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4608
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
5014
4609
|
|
|
5015
4610
|
@fragment
|
|
5016
4611
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
5017
|
-
let
|
|
5018
|
-
let
|
|
5019
|
-
let texSize = vec2f(textureDimensions(texture, 0));
|
|
4612
|
+
let texCoord = inputs.coordinate;
|
|
4613
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
5020
4614
|
|
|
5021
|
-
var fragColor = textureSample(
|
|
5022
|
-
fragColor = ${func}(fragColor, texSize,
|
|
4615
|
+
var fragColor = textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
4616
|
+
fragColor = ${func}(fragColor, texSize, texCoord);
|
|
5023
4617
|
return fragColor;
|
|
5024
4618
|
}
|
|
5025
4619
|
`
|
|
@@ -5028,23 +4622,14 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
5028
4622
|
function getSamplerShaderWGSL(func) {
|
|
5029
4623
|
return (
|
|
5030
4624
|
/* wgsl */
|
|
5031
|
-
|
|
5032
|
-
@group(0) @binding(
|
|
5033
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
5034
|
-
@group(0) @binding(2) var sampler: sampler;
|
|
5035
|
-
|
|
5036
|
-
struct FragmentInputs = {
|
|
5037
|
-
@location(0) fragUV: vec2f,
|
|
5038
|
-
@location(1) fragPosition: vec4f,
|
|
5039
|
-
@location(2) fragCoordinate: vec4f
|
|
5040
|
-
};
|
|
4625
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4626
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
5041
4627
|
|
|
5042
4628
|
@fragment
|
|
5043
4629
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
5044
|
-
let
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
return fragColor;
|
|
4630
|
+
let texCoord = inputs.coordinate;
|
|
4631
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
4632
|
+
return ${func}(sourceTexture, sourceTextureSampler, texSize, texCoord);
|
|
5048
4633
|
}
|
|
5049
4634
|
`
|
|
5050
4635
|
);
|
|
@@ -5103,12 +4688,10 @@ var ShaderPassRenderer = class {
|
|
|
5103
4688
|
shaderInputs;
|
|
5104
4689
|
passRenderers;
|
|
5105
4690
|
swapFramebuffers;
|
|
5106
|
-
/** For rendering to the screen */
|
|
5107
|
-
clipSpace;
|
|
5108
4691
|
textureModel;
|
|
5109
4692
|
constructor(device, props) {
|
|
5110
4693
|
this.device = device;
|
|
5111
|
-
props.shaderPasses.map((shaderPass) => (0,
|
|
4694
|
+
props.shaderPasses.map((shaderPass) => (0, import_shadertools5.initializeShaderModule)(shaderPass));
|
|
5112
4695
|
const modules = props.shaderPasses.reduce((object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }), {});
|
|
5113
4696
|
this.shaderInputs = props.shaderInputs || new ShaderInputs(modules);
|
|
5114
4697
|
const size = device.getCanvasContext().getDrawingBufferSize();
|
|
@@ -5120,33 +4703,6 @@ var ShaderPassRenderer = class {
|
|
|
5120
4703
|
this.textureModel = new BackgroundTextureModel(device, {
|
|
5121
4704
|
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
5122
4705
|
});
|
|
5123
|
-
this.clipSpace = new ClipSpace(device, {
|
|
5124
|
-
source: (
|
|
5125
|
-
/* wgsl */
|
|
5126
|
-
` @group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
5127
|
-
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
5128
|
-
|
|
5129
|
-
@fragment
|
|
5130
|
-
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
5131
|
-
let texCoord: vec2<f32> = inputs.coordinate;
|
|
5132
|
-
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
5133
|
-
}
|
|
5134
|
-
`
|
|
5135
|
-
),
|
|
5136
|
-
fs: (
|
|
5137
|
-
/* glsl */
|
|
5138
|
-
`#version 300 es
|
|
5139
|
-
|
|
5140
|
-
uniform sampler2D sourceTexture;
|
|
5141
|
-
in vec2 uv;
|
|
5142
|
-
out vec4 fragColor;
|
|
5143
|
-
|
|
5144
|
-
void main() {
|
|
5145
|
-
fragColor = texture(sourceTexture, uv);
|
|
5146
|
-
}
|
|
5147
|
-
`
|
|
5148
|
-
)
|
|
5149
|
-
});
|
|
5150
4706
|
this.passRenderers = props.shaderPasses.map((shaderPass) => new PassRenderer(device, shaderPass));
|
|
5151
4707
|
}
|
|
5152
4708
|
/** Destroys resources created by this ShaderPassRenderer */
|
|
@@ -5155,7 +4711,6 @@ void main() {
|
|
|
5155
4711
|
subPassRenderer.destroy();
|
|
5156
4712
|
}
|
|
5157
4713
|
this.swapFramebuffers.destroy();
|
|
5158
|
-
this.clipSpace.destroy();
|
|
5159
4714
|
this.textureModel.destroy();
|
|
5160
4715
|
}
|
|
5161
4716
|
resize(size) {
|
|
@@ -5167,15 +4722,15 @@ void main() {
|
|
|
5167
4722
|
if (!outputTexture) {
|
|
5168
4723
|
return false;
|
|
5169
4724
|
}
|
|
5170
|
-
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({
|
|
4725
|
+
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilFormat: false });
|
|
5171
4726
|
const renderPass = this.device.beginRenderPass({
|
|
5172
4727
|
id: "shader-pass-renderer-to-screen",
|
|
5173
4728
|
framebuffer,
|
|
5174
4729
|
// clearColor: [1, 1, 0, 1],
|
|
5175
|
-
clearDepth:
|
|
4730
|
+
clearDepth: false
|
|
5176
4731
|
});
|
|
5177
|
-
this.
|
|
5178
|
-
this.
|
|
4732
|
+
this.textureModel.setProps({ backgroundTexture: outputTexture });
|
|
4733
|
+
this.textureModel.draw(renderPass);
|
|
5179
4734
|
renderPass.end();
|
|
5180
4735
|
return true;
|
|
5181
4736
|
}
|
|
@@ -5280,6 +4835,218 @@ var SubPassRenderer = class {
|
|
|
5280
4835
|
}
|
|
5281
4836
|
};
|
|
5282
4837
|
|
|
4838
|
+
// dist/compute/computation.js
|
|
4839
|
+
var import_core17 = require("@luma.gl/core");
|
|
4840
|
+
var import_shadertools6 = require("@luma.gl/shadertools");
|
|
4841
|
+
var import_types2 = require("@math.gl/types");
|
|
4842
|
+
var LOG_DRAW_PRIORITY2 = 2;
|
|
4843
|
+
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
4844
|
+
var _Computation = class {
|
|
4845
|
+
device;
|
|
4846
|
+
id;
|
|
4847
|
+
pipelineFactory;
|
|
4848
|
+
shaderFactory;
|
|
4849
|
+
userData = {};
|
|
4850
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
4851
|
+
bindings = {};
|
|
4852
|
+
/** The underlying GPU pipeline. */
|
|
4853
|
+
pipeline;
|
|
4854
|
+
/** Assembled compute shader source */
|
|
4855
|
+
source;
|
|
4856
|
+
/** the underlying compiled compute shader */
|
|
4857
|
+
// @ts-ignore Set in function called from constructor
|
|
4858
|
+
shader;
|
|
4859
|
+
/** ShaderInputs instance */
|
|
4860
|
+
shaderInputs;
|
|
4861
|
+
// @ts-ignore Set in function called from constructor
|
|
4862
|
+
_uniformStore;
|
|
4863
|
+
_pipelineNeedsUpdate = "newly created";
|
|
4864
|
+
_getModuleUniforms;
|
|
4865
|
+
props;
|
|
4866
|
+
_destroyed = false;
|
|
4867
|
+
constructor(device, props) {
|
|
4868
|
+
var _a, _b, _c;
|
|
4869
|
+
if (device.type !== "webgpu") {
|
|
4870
|
+
throw new Error("Computation is only supported in WebGPU");
|
|
4871
|
+
}
|
|
4872
|
+
this.props = { ..._Computation.defaultProps, ...props };
|
|
4873
|
+
props = this.props;
|
|
4874
|
+
this.id = props.id || uid("model");
|
|
4875
|
+
this.device = device;
|
|
4876
|
+
Object.assign(this.userData, props.userData);
|
|
4877
|
+
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
4878
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
4879
|
+
this.setShaderInputs(this.shaderInputs);
|
|
4880
|
+
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
4881
|
+
const platformInfo = getPlatformInfo2(device);
|
|
4882
|
+
const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
|
|
4883
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
4884
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
4885
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
4886
|
+
platformInfo,
|
|
4887
|
+
...this.props,
|
|
4888
|
+
modules
|
|
4889
|
+
});
|
|
4890
|
+
this.source = source3;
|
|
4891
|
+
this._getModuleUniforms = getUniforms2;
|
|
4892
|
+
this.pipeline = this._updatePipeline();
|
|
4893
|
+
if (props.bindings) {
|
|
4894
|
+
this.setBindings(props.bindings);
|
|
4895
|
+
}
|
|
4896
|
+
Object.seal(this);
|
|
4897
|
+
}
|
|
4898
|
+
destroy() {
|
|
4899
|
+
if (this._destroyed)
|
|
4900
|
+
return;
|
|
4901
|
+
this.pipelineFactory.release(this.pipeline);
|
|
4902
|
+
this.shaderFactory.release(this.shader);
|
|
4903
|
+
this._uniformStore.destroy();
|
|
4904
|
+
this._destroyed = true;
|
|
4905
|
+
}
|
|
4906
|
+
// Draw call
|
|
4907
|
+
predraw() {
|
|
4908
|
+
this.updateShaderInputs();
|
|
4909
|
+
}
|
|
4910
|
+
dispatch(computePass, x, y, z) {
|
|
4911
|
+
try {
|
|
4912
|
+
this._logDrawCallStart();
|
|
4913
|
+
this.pipeline = this._updatePipeline();
|
|
4914
|
+
this.pipeline.setBindings(this.bindings);
|
|
4915
|
+
computePass.setPipeline(this.pipeline);
|
|
4916
|
+
computePass.setBindings([]);
|
|
4917
|
+
computePass.dispatch(x, y, z);
|
|
4918
|
+
} finally {
|
|
4919
|
+
this._logDrawCallEnd();
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
4923
|
+
// Update dynamic fields
|
|
4924
|
+
/**
|
|
4925
|
+
* Updates the vertex count (used in draw calls)
|
|
4926
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
4927
|
+
*/
|
|
4928
|
+
setVertexCount(vertexCount) {
|
|
4929
|
+
}
|
|
4930
|
+
/**
|
|
4931
|
+
* Updates the instance count (used in draw calls)
|
|
4932
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
4933
|
+
*/
|
|
4934
|
+
setInstanceCount(instanceCount) {
|
|
4935
|
+
}
|
|
4936
|
+
setShaderInputs(shaderInputs) {
|
|
4937
|
+
this.shaderInputs = shaderInputs;
|
|
4938
|
+
this._uniformStore = new import_core17.UniformStore(this.shaderInputs.modules);
|
|
4939
|
+
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
4940
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
4941
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
/**
|
|
4945
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
4946
|
+
*/
|
|
4947
|
+
setShaderModuleProps(props) {
|
|
4948
|
+
const uniforms = this._getModuleUniforms(props);
|
|
4949
|
+
const keys = Object.keys(uniforms).filter((k) => {
|
|
4950
|
+
const uniform = uniforms[k];
|
|
4951
|
+
return !(0, import_types2.isNumericArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
4952
|
+
});
|
|
4953
|
+
const bindings = {};
|
|
4954
|
+
for (const k of keys) {
|
|
4955
|
+
bindings[k] = uniforms[k];
|
|
4956
|
+
delete uniforms[k];
|
|
4957
|
+
}
|
|
4958
|
+
}
|
|
4959
|
+
updateShaderInputs() {
|
|
4960
|
+
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
4961
|
+
}
|
|
4962
|
+
/**
|
|
4963
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
4964
|
+
*/
|
|
4965
|
+
setBindings(bindings) {
|
|
4966
|
+
Object.assign(this.bindings, bindings);
|
|
4967
|
+
}
|
|
4968
|
+
_setPipelineNeedsUpdate(reason) {
|
|
4969
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
4970
|
+
}
|
|
4971
|
+
_updatePipeline() {
|
|
4972
|
+
if (this._pipelineNeedsUpdate) {
|
|
4973
|
+
let prevShader = null;
|
|
4974
|
+
if (this.pipeline) {
|
|
4975
|
+
import_core17.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
4976
|
+
prevShader = this.shader;
|
|
4977
|
+
}
|
|
4978
|
+
this._pipelineNeedsUpdate = false;
|
|
4979
|
+
this.shader = this.shaderFactory.createShader({
|
|
4980
|
+
id: `${this.id}-fragment`,
|
|
4981
|
+
stage: "compute",
|
|
4982
|
+
source: this.source,
|
|
4983
|
+
debugShaders: this.props.debugShaders
|
|
4984
|
+
});
|
|
4985
|
+
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
4986
|
+
...this.props,
|
|
4987
|
+
shader: this.shader
|
|
4988
|
+
});
|
|
4989
|
+
if (prevShader) {
|
|
4990
|
+
this.shaderFactory.release(prevShader);
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
return this.pipeline;
|
|
4994
|
+
}
|
|
4995
|
+
/** Throttle draw call logging */
|
|
4996
|
+
_lastLogTime = 0;
|
|
4997
|
+
_logOpen = false;
|
|
4998
|
+
_logDrawCallStart() {
|
|
4999
|
+
const logDrawTimeout = import_core17.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
5000
|
+
if (import_core17.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
5001
|
+
return;
|
|
5002
|
+
}
|
|
5003
|
+
this._lastLogTime = Date.now();
|
|
5004
|
+
this._logOpen = true;
|
|
5005
|
+
import_core17.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core17.log.level <= 2 })();
|
|
5006
|
+
}
|
|
5007
|
+
_logDrawCallEnd() {
|
|
5008
|
+
if (this._logOpen) {
|
|
5009
|
+
const uniformTable = this.shaderInputs.getDebugTable();
|
|
5010
|
+
import_core17.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
5011
|
+
import_core17.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
5012
|
+
this._logOpen = false;
|
|
5013
|
+
}
|
|
5014
|
+
}
|
|
5015
|
+
_drawCount = 0;
|
|
5016
|
+
// TODO - fix typing of luma data types
|
|
5017
|
+
_getBufferOrConstantValues(attribute, dataType) {
|
|
5018
|
+
const TypedArrayConstructor = (0, import_core17.getTypedArrayConstructor)(dataType);
|
|
5019
|
+
const typedArray = attribute instanceof import_core17.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
5020
|
+
return typedArray.toString();
|
|
5021
|
+
}
|
|
5022
|
+
};
|
|
5023
|
+
var Computation = _Computation;
|
|
5024
|
+
__publicField(Computation, "defaultProps", {
|
|
5025
|
+
...import_core17.ComputePipeline.defaultProps,
|
|
5026
|
+
id: "unnamed",
|
|
5027
|
+
handle: void 0,
|
|
5028
|
+
userData: {},
|
|
5029
|
+
source: "",
|
|
5030
|
+
modules: [],
|
|
5031
|
+
defines: {},
|
|
5032
|
+
bindings: void 0,
|
|
5033
|
+
shaderInputs: void 0,
|
|
5034
|
+
pipelineFactory: void 0,
|
|
5035
|
+
shaderFactory: void 0,
|
|
5036
|
+
shaderAssembler: import_shadertools6.ShaderAssembler.getDefaultShaderAssembler(),
|
|
5037
|
+
debugShaders: void 0
|
|
5038
|
+
});
|
|
5039
|
+
function getPlatformInfo2(device) {
|
|
5040
|
+
return {
|
|
5041
|
+
type: device.type,
|
|
5042
|
+
shaderLanguage: device.info.shadingLanguage,
|
|
5043
|
+
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
5044
|
+
gpu: device.info.gpu,
|
|
5045
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
5046
|
+
features: device.features
|
|
5047
|
+
};
|
|
5048
|
+
}
|
|
5049
|
+
|
|
5283
5050
|
// dist/modules/picking/picking-uniforms.js
|
|
5284
5051
|
var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
|
|
5285
5052
|
var INVALID_INDEX = -1;
|
|
@@ -5475,12 +5242,6 @@ const INDEX_PICKING_MODE_INSTANCE = 0;
|
|
|
5475
5242
|
const INDEX_PICKING_MODE_CUSTOM = 1;
|
|
5476
5243
|
const INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
5477
5244
|
|
|
5478
|
-
struct indexPickingFragmentInputs = {
|
|
5479
|
-
objectIndex: int32;
|
|
5480
|
-
};
|
|
5481
|
-
|
|
5482
|
-
let indexPickingFragmentInputs: indexPickingFragmentInputs;
|
|
5483
|
-
|
|
5484
5245
|
/**
|
|
5485
5246
|
* Vertex shaders should call this function to set the object index.
|
|
5486
5247
|
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|