@luma.gl/engine 9.3.0-alpha.2 → 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 +442 -209
- package/dist/dist.min.js +37 -79
- 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 +187 -36
- 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 +9 -1
- 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 +433 -208
- package/dist/index.cjs.map +2 -2
- 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/dist/utils/buffer-layout-order.d.ts.map +1 -1
- package/dist/utils/buffer-layout-order.js +12 -2
- package/dist/utils/buffer-layout-order.js.map +1 -1
- package/package.json +4 -4
- 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 +248 -39
- package/src/dynamic-texture/texture-data.ts +15 -1
- 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/src/utils/buffer-layout-order.ts +18 -2
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();
|
|
@@ -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
|
-
return false;
|
|
903
|
-
case "unused":
|
|
904
|
-
delete cache[pipeline.hash];
|
|
905
|
-
pipeline.destroy();
|
|
906
|
-
return true;
|
|
990
|
+
if (!this.device.props._destroyPipelines) {
|
|
991
|
+
return false;
|
|
907
992
|
}
|
|
993
|
+
delete cache[pipeline.hash];
|
|
994
|
+
pipeline.destroy();
|
|
995
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
996
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
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
|
}
|
|
@@ -1175,14 +1271,24 @@ var BufferLayoutHelper = class {
|
|
|
1175
1271
|
};
|
|
1176
1272
|
|
|
1177
1273
|
// dist/utils/buffer-layout-order.js
|
|
1274
|
+
function getMinLocation(attributeNames, shaderLayoutMap) {
|
|
1275
|
+
let minLocation = Infinity;
|
|
1276
|
+
for (const name of attributeNames) {
|
|
1277
|
+
const location = shaderLayoutMap[name];
|
|
1278
|
+
if (location !== void 0) {
|
|
1279
|
+
minLocation = Math.min(minLocation, location);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
return minLocation;
|
|
1283
|
+
}
|
|
1178
1284
|
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
1179
1285
|
const shaderLayoutMap = Object.fromEntries(shaderLayout.attributes.map((attr) => [attr.name, attr.location]));
|
|
1180
1286
|
const sortedLayout = bufferLayout.slice();
|
|
1181
1287
|
sortedLayout.sort((a, b) => {
|
|
1182
1288
|
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
1183
1289
|
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
1184
|
-
const minLocationA =
|
|
1185
|
-
const minLocationB =
|
|
1290
|
+
const minLocationA = getMinLocation(attributeNamesA, shaderLayoutMap);
|
|
1291
|
+
const minLocationB = getMinLocation(attributeNamesB, shaderLayoutMap);
|
|
1186
1292
|
return minLocationA - minLocationB;
|
|
1187
1293
|
});
|
|
1188
1294
|
return sortedLayout;
|
|
@@ -1384,6 +1490,13 @@ function getTextureMipLevelSize(data) {
|
|
|
1384
1490
|
function isTextureImageData(data) {
|
|
1385
1491
|
return typeof data === "object" && data !== null && "data" in data && "width" in data && "height" in data;
|
|
1386
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
|
+
}
|
|
1387
1500
|
function getCubeFaceIndex(face) {
|
|
1388
1501
|
const idx = TEXTURE_CUBE_FACE_MAP[face];
|
|
1389
1502
|
if (idx === void 0)
|
|
@@ -1416,6 +1529,7 @@ function getTexture2DSubresources(slice, lodData) {
|
|
|
1416
1529
|
subresources.push({
|
|
1417
1530
|
type: "texture-data",
|
|
1418
1531
|
data: imageData,
|
|
1532
|
+
textureFormat: resolveTextureImageFormat(imageData),
|
|
1419
1533
|
z,
|
|
1420
1534
|
mipLevel
|
|
1421
1535
|
});
|
|
@@ -1452,7 +1566,7 @@ function getTextureCubeArraySubresources(data) {
|
|
|
1452
1566
|
data.forEach((cubeData, cubeIndex) => {
|
|
1453
1567
|
for (const [face, faceData] of Object.entries(cubeData)) {
|
|
1454
1568
|
const faceDepth = getCubeArrayFaceIndex(cubeIndex, face);
|
|
1455
|
-
getTexture2DSubresources(faceDepth, faceData);
|
|
1569
|
+
subresources.push(...getTexture2DSubresources(faceDepth, faceData));
|
|
1456
1570
|
}
|
|
1457
1571
|
});
|
|
1458
1572
|
return subresources;
|
|
@@ -1514,6 +1628,9 @@ var _DynamicTexture = class {
|
|
|
1514
1628
|
try {
|
|
1515
1629
|
const propsWithSyncData = await this._loadAllData(originalPropsWithAsyncData);
|
|
1516
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;
|
|
1517
1634
|
const deduceSize = () => {
|
|
1518
1635
|
if (this.props.width && this.props.height) {
|
|
1519
1636
|
return { width: this.props.width, height: this.props.height };
|
|
@@ -1528,45 +1645,39 @@ var _DynamicTexture = class {
|
|
|
1528
1645
|
if (!size || size.width <= 0 || size.height <= 0) {
|
|
1529
1646
|
throw new Error(`${this} size could not be determined or was zero`);
|
|
1530
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;
|
|
1531
1652
|
const baseTextureProps = {
|
|
1532
1653
|
...this.props,
|
|
1533
1654
|
...size,
|
|
1655
|
+
format: resolvedFormat,
|
|
1534
1656
|
mipLevels: 1,
|
|
1535
1657
|
// temporary; updated below
|
|
1536
1658
|
data: void 0
|
|
1537
1659
|
};
|
|
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;
|
|
1666
|
+
baseTextureProps.usage |= requiredUsage;
|
|
1667
|
+
}
|
|
1538
1668
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
1539
|
-
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));
|
|
1540
1670
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
1541
1671
|
this._texture = this.device.createTexture(finalTextureProps);
|
|
1542
1672
|
this._sampler = this.texture.sampler;
|
|
1543
1673
|
this._view = this.texture.view;
|
|
1544
|
-
if (
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
case "2d":
|
|
1550
|
-
this.setTexture2DData(propsWithSyncData.data);
|
|
1551
|
-
break;
|
|
1552
|
-
case "3d":
|
|
1553
|
-
this.setTexture3DData(propsWithSyncData.data);
|
|
1554
|
-
break;
|
|
1555
|
-
case "2d-array":
|
|
1556
|
-
this.setTextureArrayData(propsWithSyncData.data);
|
|
1557
|
-
break;
|
|
1558
|
-
case "cube":
|
|
1559
|
-
this.setTextureCubeData(propsWithSyncData.data);
|
|
1560
|
-
break;
|
|
1561
|
-
case "cube-array":
|
|
1562
|
-
this.setTextureCubeArrayData(propsWithSyncData.data);
|
|
1563
|
-
break;
|
|
1564
|
-
default: {
|
|
1565
|
-
throw new Error(`Unhandled dimension ${propsWithSyncData.dimension}`);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
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`)();
|
|
1568
1679
|
}
|
|
1569
|
-
if (
|
|
1680
|
+
if (shouldGenerateMipmaps) {
|
|
1570
1681
|
this.generateMipmaps();
|
|
1571
1682
|
}
|
|
1572
1683
|
this.isReady = true;
|
|
@@ -1590,8 +1701,10 @@ var _DynamicTexture = class {
|
|
|
1590
1701
|
generateMipmaps() {
|
|
1591
1702
|
if (this.device.type === "webgl") {
|
|
1592
1703
|
this.texture.generateMipmapsWebGL();
|
|
1704
|
+
} else if (this.device.type === "webgpu") {
|
|
1705
|
+
this.device.generateMipmapsWebGPU(this.texture);
|
|
1593
1706
|
} else {
|
|
1594
|
-
import_core9.log.warn(
|
|
1707
|
+
import_core9.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
1595
1708
|
}
|
|
1596
1709
|
}
|
|
1597
1710
|
/** Set sampler or create one from props */
|
|
@@ -1689,8 +1802,19 @@ var _DynamicTexture = class {
|
|
|
1689
1802
|
this.texture.copyExternalImage({ image, z, mipLevel, flipY });
|
|
1690
1803
|
break;
|
|
1691
1804
|
case "texture-data":
|
|
1692
|
-
const { data } = subresource;
|
|
1693
|
-
|
|
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, {
|
|
1810
|
+
x: 0,
|
|
1811
|
+
y: 0,
|
|
1812
|
+
z,
|
|
1813
|
+
width: data.width,
|
|
1814
|
+
height: data.height,
|
|
1815
|
+
depthOrArrayLayers: 1,
|
|
1816
|
+
mipLevel
|
|
1817
|
+
});
|
|
1694
1818
|
break;
|
|
1695
1819
|
default:
|
|
1696
1820
|
throw new Error("Unsupported 2D mip-level payload");
|
|
@@ -1722,6 +1846,134 @@ __publicField(DynamicTexture, "defaultProps", {
|
|
|
1722
1846
|
data: null,
|
|
1723
1847
|
mipmaps: false
|
|
1724
1848
|
});
|
|
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;
|
|
1976
|
+
}
|
|
1725
1977
|
async function awaitAllPromises(x) {
|
|
1726
1978
|
x = await x;
|
|
1727
1979
|
if (Array.isArray(x)) {
|
|
@@ -1897,7 +2149,7 @@ var _Model = class {
|
|
|
1897
2149
|
if (!this._destroyed) {
|
|
1898
2150
|
this.pipelineFactory.release(this.pipeline);
|
|
1899
2151
|
this.shaderFactory.release(this.pipeline.vs);
|
|
1900
|
-
if (this.pipeline.fs) {
|
|
2152
|
+
if (this.pipeline.fs && this.pipeline.fs !== this.pipeline.vs) {
|
|
1901
2153
|
this.shaderFactory.release(this.pipeline.fs);
|
|
1902
2154
|
}
|
|
1903
2155
|
this._uniformStore.destroy();
|
|
@@ -1947,9 +2199,6 @@ var _Model = class {
|
|
|
1947
2199
|
this._logDrawCallStart();
|
|
1948
2200
|
this.pipeline = this._updatePipeline();
|
|
1949
2201
|
const syncBindings = this._getBindings();
|
|
1950
|
-
this.pipeline.setBindings(syncBindings, {
|
|
1951
|
-
disableWarnings: this.props.disableWarnings
|
|
1952
|
-
});
|
|
1953
2202
|
const { indexBuffer } = this.vertexArray;
|
|
1954
2203
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
1955
2204
|
drawSuccess = this.pipeline.draw({
|
|
@@ -1960,6 +2209,11 @@ var _Model = class {
|
|
|
1960
2209
|
instanceCount: this.instanceCount,
|
|
1961
2210
|
indexCount,
|
|
1962
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,
|
|
1963
2217
|
// WebGL shares underlying cached pipelines even for models that have different parameters and topology,
|
|
1964
2218
|
// so we must provide our unique parameters to each draw
|
|
1965
2219
|
// (In WebGPU most parameters are encoded in the pipeline and cannot be changed per draw call)
|
|
@@ -2259,8 +2513,9 @@ var _Model = class {
|
|
|
2259
2513
|
this._attributeInfos = (0, import_core10.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
|
|
2260
2514
|
if (prevShaderVs)
|
|
2261
2515
|
this.shaderFactory.release(prevShaderVs);
|
|
2262
|
-
if (prevShaderFs)
|
|
2516
|
+
if (prevShaderFs && prevShaderFs !== prevShaderVs) {
|
|
2263
2517
|
this.shaderFactory.release(prevShaderFs);
|
|
2518
|
+
}
|
|
2264
2519
|
}
|
|
2265
2520
|
return this.pipeline;
|
|
2266
2521
|
}
|
|
@@ -2344,6 +2599,8 @@ __publicField(Model, "defaultProps", {
|
|
|
2344
2599
|
indexBuffer: null,
|
|
2345
2600
|
attributes: {},
|
|
2346
2601
|
constantAttributes: {},
|
|
2602
|
+
bindings: {},
|
|
2603
|
+
uniforms: {},
|
|
2347
2604
|
varyings: [],
|
|
2348
2605
|
isInstanced: void 0,
|
|
2349
2606
|
instanceCount: 0,
|
|
@@ -2648,9 +2905,9 @@ var Geometry = class {
|
|
|
2648
2905
|
var CLIPSPACE_VERTEX_SHADER_WGSL = (
|
|
2649
2906
|
/* wgsl */
|
|
2650
2907
|
`struct VertexInputs {
|
|
2651
|
-
@location(0)
|
|
2652
|
-
@location(1)
|
|
2653
|
-
@location(2)
|
|
2908
|
+
@location(0) clipSpacePositions: vec2<f32>,
|
|
2909
|
+
@location(1) texCoords: vec2<f32>,
|
|
2910
|
+
@location(2) coordinates: vec2<f32>
|
|
2654
2911
|
}
|
|
2655
2912
|
|
|
2656
2913
|
struct FragmentInputs {
|
|
@@ -2663,10 +2920,10 @@ struct FragmentInputs {
|
|
|
2663
2920
|
@vertex
|
|
2664
2921
|
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
2665
2922
|
var outputs: FragmentInputs;
|
|
2666
|
-
outputs.Position = vec4(inputs.
|
|
2667
|
-
outputs.position = inputs.
|
|
2668
|
-
outputs.coordinate = inputs.
|
|
2669
|
-
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;
|
|
2670
2927
|
return outputs;
|
|
2671
2928
|
}
|
|
2672
2929
|
`
|
|
@@ -2732,15 +2989,15 @@ struct backgroundUniforms {
|
|
|
2732
2989
|
};
|
|
2733
2990
|
@group(0) @binding(2) var<uniform> background: backgroundUniforms;
|
|
2734
2991
|
|
|
2735
|
-
fn billboardTexture_getTextureUV(
|
|
2992
|
+
fn billboardTexture_getTextureUV(uv: vec2<f32>) -> vec2<f32> {
|
|
2736
2993
|
let scale: vec2<f32> = background.scale;
|
|
2737
|
-
var position: vec2<f32> = (
|
|
2994
|
+
var position: vec2<f32> = (uv - vec2<f32>(0.5, 0.5)) / scale + vec2<f32>(0.5, 0.5);
|
|
2738
2995
|
return position;
|
|
2739
2996
|
}
|
|
2740
2997
|
|
|
2741
2998
|
@fragment
|
|
2742
2999
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
2743
|
-
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.
|
|
3000
|
+
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.uv);
|
|
2744
3001
|
return textureSample(backgroundTexture, backgroundTextureSampler, position);
|
|
2745
3002
|
}
|
|
2746
3003
|
`
|
|
@@ -2774,20 +3031,22 @@ var BackgroundTextureModel = class extends ClipSpace {
|
|
|
2774
3031
|
backgroundTexture = null;
|
|
2775
3032
|
constructor(device, props) {
|
|
2776
3033
|
super(device, {
|
|
3034
|
+
...props,
|
|
2777
3035
|
id: props.id || "background-texture-model",
|
|
2778
3036
|
source: BACKGROUND_FS_WGSL,
|
|
2779
3037
|
fs: BACKGROUND_FS,
|
|
2780
|
-
modules: [backgroundModule],
|
|
3038
|
+
modules: [...props.modules || [], backgroundModule],
|
|
2781
3039
|
parameters: {
|
|
2782
3040
|
depthWriteEnabled: false,
|
|
3041
|
+
...props.parameters || {},
|
|
2783
3042
|
...props.blend ? {
|
|
2784
3043
|
blend: true,
|
|
2785
3044
|
blendColorOperation: "add",
|
|
2786
3045
|
blendAlphaOperation: "add",
|
|
2787
|
-
blendColorSrcFactor: "one",
|
|
2788
|
-
blendColorDstFactor: "one
|
|
2789
|
-
blendAlphaSrcFactor: "one",
|
|
2790
|
-
blendAlphaDstFactor: "one
|
|
3046
|
+
blendColorSrcFactor: "one-minus-dst-alpha",
|
|
3047
|
+
blendColorDstFactor: "one",
|
|
3048
|
+
blendAlphaSrcFactor: "one-minus-dst-alpha",
|
|
3049
|
+
blendAlphaDstFactor: "one"
|
|
2791
3050
|
} : {}
|
|
2792
3051
|
}
|
|
2793
3052
|
});
|
|
@@ -2839,6 +3098,11 @@ var BackgroundTextureModel = class extends ClipSpace {
|
|
|
2839
3098
|
|
|
2840
3099
|
// dist/scenegraph/scenegraph-node.js
|
|
2841
3100
|
var import_core12 = require("@math.gl/core");
|
|
3101
|
+
function assert(condition, message) {
|
|
3102
|
+
if (!condition) {
|
|
3103
|
+
throw new Error(message);
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
2842
3106
|
var ScenegraphNode = class {
|
|
2843
3107
|
id;
|
|
2844
3108
|
matrix = new import_core12.Matrix4();
|
|
@@ -2870,14 +3134,17 @@ var ScenegraphNode = class {
|
|
|
2870
3134
|
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
2871
3135
|
}
|
|
2872
3136
|
setPosition(position) {
|
|
3137
|
+
assert(position.length === 3, "setPosition requires vector argument");
|
|
2873
3138
|
this.position = position;
|
|
2874
3139
|
return this;
|
|
2875
3140
|
}
|
|
2876
3141
|
setRotation(rotation) {
|
|
3142
|
+
assert(rotation.length === 3 || rotation.length === 4, "setRotation requires vector argument");
|
|
2877
3143
|
this.rotation = rotation;
|
|
2878
3144
|
return this;
|
|
2879
3145
|
}
|
|
2880
3146
|
setScale(scale) {
|
|
3147
|
+
assert(scale.length === 3, "setScale requires vector argument");
|
|
2881
3148
|
this.scale = scale;
|
|
2882
3149
|
return this;
|
|
2883
3150
|
}
|
|
@@ -2905,17 +3172,18 @@ var ScenegraphNode = class {
|
|
|
2905
3172
|
return this;
|
|
2906
3173
|
}
|
|
2907
3174
|
updateMatrix() {
|
|
2908
|
-
const pos = this.position;
|
|
2909
|
-
const rot = this.rotation;
|
|
2910
|
-
const scale = this.scale;
|
|
2911
3175
|
this.matrix.identity();
|
|
2912
|
-
this.matrix.translate(
|
|
2913
|
-
this.
|
|
2914
|
-
|
|
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);
|
|
2915
3184
|
return this;
|
|
2916
3185
|
}
|
|
2917
|
-
update(
|
|
2918
|
-
const { position, rotation, scale } = options;
|
|
3186
|
+
update({ position, rotation, scale } = {}) {
|
|
2919
3187
|
if (position) {
|
|
2920
3188
|
this.setPosition(position);
|
|
2921
3189
|
}
|
|
@@ -2965,16 +3233,17 @@ var ScenegraphNode = class {
|
|
|
2965
3233
|
}
|
|
2966
3234
|
*/
|
|
2967
3235
|
_setScenegraphNodeProps(props) {
|
|
2968
|
-
if (
|
|
3236
|
+
if (props == null ? void 0 : props.position) {
|
|
2969
3237
|
this.setPosition(props.position);
|
|
2970
3238
|
}
|
|
2971
|
-
if (
|
|
3239
|
+
if (props == null ? void 0 : props.rotation) {
|
|
2972
3240
|
this.setRotation(props.rotation);
|
|
2973
3241
|
}
|
|
2974
|
-
if (
|
|
3242
|
+
if (props == null ? void 0 : props.scale) {
|
|
2975
3243
|
this.setScale(props.scale);
|
|
2976
3244
|
}
|
|
2977
|
-
|
|
3245
|
+
this.updateMatrix();
|
|
3246
|
+
if (props == null ? void 0 : props.matrix) {
|
|
2978
3247
|
this.setMatrix(props.matrix);
|
|
2979
3248
|
}
|
|
2980
3249
|
Object.assign(this.props, props);
|
|
@@ -3059,6 +3328,17 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3059
3328
|
}
|
|
3060
3329
|
}
|
|
3061
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
|
+
}
|
|
3062
3342
|
};
|
|
3063
3343
|
|
|
3064
3344
|
// dist/scenegraph/model-node.js
|
|
@@ -4324,26 +4604,16 @@ function getFragmentShaderForRenderPass(options) {
|
|
|
4324
4604
|
function getFilterShaderWGSL(func) {
|
|
4325
4605
|
return (
|
|
4326
4606
|
/* wgsl */
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
4330
|
-
@group(0) @binding(2) var textureSampler: sampler;
|
|
4331
|
-
|
|
4332
|
-
// This needs to be aligned with
|
|
4333
|
-
// struct FragmentInputs {
|
|
4334
|
-
// @location(0) fragUV: vec2f,
|
|
4335
|
-
// @location(1) fragPosition: vec4f,
|
|
4336
|
-
// @location(2) fragCoordinate: vec4f
|
|
4337
|
-
// };
|
|
4607
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4608
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
4338
4609
|
|
|
4339
4610
|
@fragment
|
|
4340
4611
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
4341
|
-
let
|
|
4342
|
-
let
|
|
4343
|
-
let texSize = vec2f(textureDimensions(texture, 0));
|
|
4612
|
+
let texCoord = inputs.coordinate;
|
|
4613
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
4344
4614
|
|
|
4345
|
-
var fragColor = textureSample(
|
|
4346
|
-
fragColor = ${func}(fragColor, texSize,
|
|
4615
|
+
var fragColor = textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
4616
|
+
fragColor = ${func}(fragColor, texSize, texCoord);
|
|
4347
4617
|
return fragColor;
|
|
4348
4618
|
}
|
|
4349
4619
|
`
|
|
@@ -4352,23 +4622,14 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
4352
4622
|
function getSamplerShaderWGSL(func) {
|
|
4353
4623
|
return (
|
|
4354
4624
|
/* wgsl */
|
|
4355
|
-
|
|
4356
|
-
@group(0) @binding(
|
|
4357
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
4358
|
-
@group(0) @binding(2) var sampler: sampler;
|
|
4359
|
-
|
|
4360
|
-
struct FragmentInputs = {
|
|
4361
|
-
@location(0) fragUV: vec2f,
|
|
4362
|
-
@location(1) fragPosition: vec4f,
|
|
4363
|
-
@location(2) fragCoordinate: vec4f
|
|
4364
|
-
};
|
|
4625
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4626
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
4365
4627
|
|
|
4366
4628
|
@fragment
|
|
4367
4629
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
4368
|
-
let
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
return fragColor;
|
|
4630
|
+
let texCoord = inputs.coordinate;
|
|
4631
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
4632
|
+
return ${func}(sourceTexture, sourceTextureSampler, texSize, texCoord);
|
|
4372
4633
|
}
|
|
4373
4634
|
`
|
|
4374
4635
|
);
|
|
@@ -4427,8 +4688,6 @@ var ShaderPassRenderer = class {
|
|
|
4427
4688
|
shaderInputs;
|
|
4428
4689
|
passRenderers;
|
|
4429
4690
|
swapFramebuffers;
|
|
4430
|
-
/** For rendering to the screen */
|
|
4431
|
-
clipSpace;
|
|
4432
4691
|
textureModel;
|
|
4433
4692
|
constructor(device, props) {
|
|
4434
4693
|
this.device = device;
|
|
@@ -4444,33 +4703,6 @@ var ShaderPassRenderer = class {
|
|
|
4444
4703
|
this.textureModel = new BackgroundTextureModel(device, {
|
|
4445
4704
|
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
4446
4705
|
});
|
|
4447
|
-
this.clipSpace = new ClipSpace(device, {
|
|
4448
|
-
source: (
|
|
4449
|
-
/* wgsl */
|
|
4450
|
-
` @group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4451
|
-
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
4452
|
-
|
|
4453
|
-
@fragment
|
|
4454
|
-
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
4455
|
-
let texCoord: vec2<f32> = inputs.coordinate;
|
|
4456
|
-
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
4457
|
-
}
|
|
4458
|
-
`
|
|
4459
|
-
),
|
|
4460
|
-
fs: (
|
|
4461
|
-
/* glsl */
|
|
4462
|
-
`#version 300 es
|
|
4463
|
-
|
|
4464
|
-
uniform sampler2D sourceTexture;
|
|
4465
|
-
in vec2 uv;
|
|
4466
|
-
out vec4 fragColor;
|
|
4467
|
-
|
|
4468
|
-
void main() {
|
|
4469
|
-
fragColor = texture(sourceTexture, uv);
|
|
4470
|
-
}
|
|
4471
|
-
`
|
|
4472
|
-
)
|
|
4473
|
-
});
|
|
4474
4706
|
this.passRenderers = props.shaderPasses.map((shaderPass) => new PassRenderer(device, shaderPass));
|
|
4475
4707
|
}
|
|
4476
4708
|
/** Destroys resources created by this ShaderPassRenderer */
|
|
@@ -4479,7 +4711,6 @@ void main() {
|
|
|
4479
4711
|
subPassRenderer.destroy();
|
|
4480
4712
|
}
|
|
4481
4713
|
this.swapFramebuffers.destroy();
|
|
4482
|
-
this.clipSpace.destroy();
|
|
4483
4714
|
this.textureModel.destroy();
|
|
4484
4715
|
}
|
|
4485
4716
|
resize(size) {
|
|
@@ -4491,15 +4722,15 @@ void main() {
|
|
|
4491
4722
|
if (!outputTexture) {
|
|
4492
4723
|
return false;
|
|
4493
4724
|
}
|
|
4494
|
-
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({
|
|
4725
|
+
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilFormat: false });
|
|
4495
4726
|
const renderPass = this.device.beginRenderPass({
|
|
4496
4727
|
id: "shader-pass-renderer-to-screen",
|
|
4497
4728
|
framebuffer,
|
|
4498
4729
|
// clearColor: [1, 1, 0, 1],
|
|
4499
|
-
clearDepth:
|
|
4730
|
+
clearDepth: false
|
|
4500
4731
|
});
|
|
4501
|
-
this.
|
|
4502
|
-
this.
|
|
4732
|
+
this.textureModel.setProps({ backgroundTexture: outputTexture });
|
|
4733
|
+
this.textureModel.draw(renderPass);
|
|
4503
4734
|
renderPass.end();
|
|
4504
4735
|
return true;
|
|
4505
4736
|
}
|
|
@@ -5011,12 +5242,6 @@ const INDEX_PICKING_MODE_INSTANCE = 0;
|
|
|
5011
5242
|
const INDEX_PICKING_MODE_CUSTOM = 1;
|
|
5012
5243
|
const INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
5013
5244
|
|
|
5014
|
-
struct indexPickingFragmentInputs = {
|
|
5015
|
-
objectIndex: int32;
|
|
5016
|
-
};
|
|
5017
|
-
|
|
5018
|
-
let indexPickingFragmentInputs: indexPickingFragmentInputs;
|
|
5019
|
-
|
|
5020
5245
|
/**
|
|
5021
5246
|
* Vertex shaders should call this function to set the object index.
|
|
5022
5247
|
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|