@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/dist.dev.js
CHANGED
|
@@ -281,10 +281,22 @@ var __exports__ = (() => {
|
|
|
281
281
|
|
|
282
282
|
// src/animation-loop/request-animation-frame.ts
|
|
283
283
|
function requestAnimationFramePolyfill(callback) {
|
|
284
|
-
|
|
284
|
+
const browserRequestAnimationFrame = typeof window !== "undefined" ? window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame : null;
|
|
285
|
+
if (browserRequestAnimationFrame) {
|
|
286
|
+
return browserRequestAnimationFrame.call(window, callback);
|
|
287
|
+
}
|
|
288
|
+
return setTimeout(
|
|
289
|
+
() => callback(typeof performance !== "undefined" ? performance.now() : Date.now()),
|
|
290
|
+
1e3 / 60
|
|
291
|
+
);
|
|
285
292
|
}
|
|
286
293
|
function cancelAnimationFramePolyfill(timerId) {
|
|
287
|
-
|
|
294
|
+
const browserCancelAnimationFrame = typeof window !== "undefined" ? window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame : null;
|
|
295
|
+
if (browserCancelAnimationFrame) {
|
|
296
|
+
browserCancelAnimationFrame.call(window, timerId);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
clearTimeout(timerId);
|
|
288
300
|
}
|
|
289
301
|
|
|
290
302
|
// ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
|
|
@@ -482,6 +494,7 @@ var __exports__ = (() => {
|
|
|
482
494
|
|
|
483
495
|
// src/animation-loop/animation-loop.ts
|
|
484
496
|
var statIdCounter = 0;
|
|
497
|
+
var ANIMATION_LOOP_STATS = "Animation Loop";
|
|
485
498
|
var _AnimationLoop = class {
|
|
486
499
|
device = null;
|
|
487
500
|
canvas = null;
|
|
@@ -489,6 +502,7 @@ var __exports__ = (() => {
|
|
|
489
502
|
animationProps = null;
|
|
490
503
|
timeline = null;
|
|
491
504
|
stats;
|
|
505
|
+
sharedStats;
|
|
492
506
|
cpuTime;
|
|
493
507
|
gpuTime;
|
|
494
508
|
frameRate;
|
|
@@ -501,7 +515,7 @@ var __exports__ = (() => {
|
|
|
501
515
|
_resolveNextFrame = null;
|
|
502
516
|
_cpuStartTime = 0;
|
|
503
517
|
_error = null;
|
|
504
|
-
|
|
518
|
+
_lastFrameTime = 0;
|
|
505
519
|
/*
|
|
506
520
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
507
521
|
*/
|
|
@@ -511,10 +525,12 @@ var __exports__ = (() => {
|
|
|
511
525
|
if (!props.device) {
|
|
512
526
|
throw new Error("No device provided");
|
|
513
527
|
}
|
|
514
|
-
this.stats = props.stats || new Stats({ id:
|
|
528
|
+
this.stats = props.stats || new Stats({ id: `animation-loop-${statIdCounter++}` });
|
|
529
|
+
this.sharedStats = import_core.luma.stats.get(ANIMATION_LOOP_STATS);
|
|
530
|
+
this.frameRate = this.stats.get("Frame Rate");
|
|
531
|
+
this.frameRate.setSampleSize(1);
|
|
515
532
|
this.cpuTime = this.stats.get("CPU Time");
|
|
516
533
|
this.gpuTime = this.stats.get("GPU Time");
|
|
517
|
-
this.frameRate = this.stats.get("Frame Rate");
|
|
518
534
|
this.setProps({ autoResizeViewport: props.autoResizeViewport });
|
|
519
535
|
this.start = this.start.bind(this);
|
|
520
536
|
this.stop = this.stop.bind(this);
|
|
@@ -524,6 +540,7 @@ var __exports__ = (() => {
|
|
|
524
540
|
destroy() {
|
|
525
541
|
this.stop();
|
|
526
542
|
this._setDisplay(null);
|
|
543
|
+
this.device?._disableDebugGPUTime();
|
|
527
544
|
}
|
|
528
545
|
/** @deprecated Use .destroy() */
|
|
529
546
|
delete() {
|
|
@@ -588,15 +605,16 @@ var __exports__ = (() => {
|
|
|
588
605
|
this._nextFramePromise = null;
|
|
589
606
|
this._resolveNextFrame = null;
|
|
590
607
|
this._running = false;
|
|
608
|
+
this._lastFrameTime = 0;
|
|
591
609
|
}
|
|
592
610
|
return this;
|
|
593
611
|
}
|
|
594
612
|
/** Explicitly draw a frame */
|
|
595
|
-
redraw() {
|
|
613
|
+
redraw(time) {
|
|
596
614
|
if (this.device?.isLost || this._error) {
|
|
597
615
|
return this;
|
|
598
616
|
}
|
|
599
|
-
this._beginFrameTimers();
|
|
617
|
+
this._beginFrameTimers(time);
|
|
600
618
|
this._setupFrame();
|
|
601
619
|
this._updateAnimationProps();
|
|
602
620
|
this._renderFrame(this._getAnimationProps());
|
|
@@ -643,6 +661,7 @@ var __exports__ = (() => {
|
|
|
643
661
|
this._initializeAnimationProps();
|
|
644
662
|
this._updateAnimationProps();
|
|
645
663
|
this._resizeViewport();
|
|
664
|
+
this.device?._enableDebugGPUTime();
|
|
646
665
|
}
|
|
647
666
|
_setDisplay(display) {
|
|
648
667
|
if (this.display) {
|
|
@@ -667,11 +686,11 @@ var __exports__ = (() => {
|
|
|
667
686
|
cancelAnimationFramePolyfill(this._animationFrameId);
|
|
668
687
|
this._animationFrameId = null;
|
|
669
688
|
}
|
|
670
|
-
_animationFrame() {
|
|
689
|
+
_animationFrame(time) {
|
|
671
690
|
if (!this._running) {
|
|
672
691
|
return;
|
|
673
692
|
}
|
|
674
|
-
this.redraw();
|
|
693
|
+
this.redraw(time);
|
|
675
694
|
this._requestAnimationFrame();
|
|
676
695
|
}
|
|
677
696
|
// Called on each frame, can be overridden to call onRender multiple times
|
|
@@ -785,14 +804,8 @@ var __exports__ = (() => {
|
|
|
785
804
|
if (!this.device) {
|
|
786
805
|
return { width: 1, height: 1, aspect: 1 };
|
|
787
806
|
}
|
|
788
|
-
const [width, height] = this.device
|
|
789
|
-
|
|
790
|
-
const canvas2 = this.device?.getDefaultCanvasContext().canvas;
|
|
791
|
-
if (canvas2 && canvas2.clientHeight) {
|
|
792
|
-
aspect = canvas2.clientWidth / canvas2.clientHeight;
|
|
793
|
-
} else if (width > 0 && height > 0) {
|
|
794
|
-
aspect = width / height;
|
|
795
|
-
}
|
|
807
|
+
const [width, height] = this.device.getDefaultCanvasContext().getDrawingBufferSize();
|
|
808
|
+
const aspect = width > 0 && height > 0 ? width / height : 1;
|
|
796
809
|
return { width, height, aspect };
|
|
797
810
|
}
|
|
798
811
|
/** @deprecated Default viewport setup */
|
|
@@ -808,13 +821,61 @@ var __exports__ = (() => {
|
|
|
808
821
|
);
|
|
809
822
|
}
|
|
810
823
|
}
|
|
811
|
-
_beginFrameTimers() {
|
|
812
|
-
|
|
813
|
-
this.
|
|
824
|
+
_beginFrameTimers(time) {
|
|
825
|
+
const now = time ?? (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
826
|
+
if (this._lastFrameTime) {
|
|
827
|
+
const frameTime = now - this._lastFrameTime;
|
|
828
|
+
if (frameTime > 0) {
|
|
829
|
+
this.frameRate.addTime(frameTime);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
this._lastFrameTime = now;
|
|
833
|
+
if (this.device?._isDebugGPUTimeEnabled()) {
|
|
834
|
+
this._consumeEncodedGpuTime();
|
|
835
|
+
}
|
|
814
836
|
this.cpuTime.timeStart();
|
|
815
837
|
}
|
|
816
838
|
_endFrameTimers() {
|
|
839
|
+
if (this.device?._isDebugGPUTimeEnabled()) {
|
|
840
|
+
this._consumeEncodedGpuTime();
|
|
841
|
+
}
|
|
817
842
|
this.cpuTime.timeEnd();
|
|
843
|
+
this._updateSharedStats();
|
|
844
|
+
}
|
|
845
|
+
_consumeEncodedGpuTime() {
|
|
846
|
+
if (!this.device) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const gpuTimeMs = this.device.commandEncoder._gpuTimeMs;
|
|
850
|
+
if (gpuTimeMs !== void 0) {
|
|
851
|
+
this.gpuTime.addTime(gpuTimeMs);
|
|
852
|
+
this.device.commandEncoder._gpuTimeMs = void 0;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
_updateSharedStats() {
|
|
856
|
+
if (this.stats === this.sharedStats) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
for (const name of Object.keys(this.sharedStats.stats)) {
|
|
860
|
+
if (!this.stats.stats[name]) {
|
|
861
|
+
delete this.sharedStats.stats[name];
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
this.stats.forEach((sourceStat) => {
|
|
865
|
+
const targetStat = this.sharedStats.get(sourceStat.name, sourceStat.type);
|
|
866
|
+
targetStat.sampleSize = sourceStat.sampleSize;
|
|
867
|
+
targetStat.time = sourceStat.time;
|
|
868
|
+
targetStat.count = sourceStat.count;
|
|
869
|
+
targetStat.samples = sourceStat.samples;
|
|
870
|
+
targetStat.lastTiming = sourceStat.lastTiming;
|
|
871
|
+
targetStat.lastSampleTime = sourceStat.lastSampleTime;
|
|
872
|
+
targetStat.lastSampleCount = sourceStat.lastSampleCount;
|
|
873
|
+
targetStat._count = sourceStat._count;
|
|
874
|
+
targetStat._time = sourceStat._time;
|
|
875
|
+
targetStat._samples = sourceStat._samples;
|
|
876
|
+
targetStat._startTime = sourceStat._startTime;
|
|
877
|
+
targetStat._timerPending = sourceStat._timerPending;
|
|
878
|
+
});
|
|
818
879
|
}
|
|
819
880
|
// Event handling
|
|
820
881
|
_startEventHandling() {
|
|
@@ -843,7 +904,7 @@ var __exports__ = (() => {
|
|
|
843
904
|
},
|
|
844
905
|
onError: (error) => console.error(error),
|
|
845
906
|
// eslint-disable-line no-console
|
|
846
|
-
stats:
|
|
907
|
+
stats: void 0,
|
|
847
908
|
// view parameters
|
|
848
909
|
autoResizeViewport: false
|
|
849
910
|
});
|
|
@@ -875,7 +936,10 @@ var __exports__ = (() => {
|
|
|
875
936
|
return animationLoop;
|
|
876
937
|
}
|
|
877
938
|
function setError(device, error) {
|
|
878
|
-
|
|
939
|
+
if (!device) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const canvas2 = device.getDefaultCanvasContext().canvas;
|
|
879
943
|
if (canvas2 instanceof HTMLCanvasElement) {
|
|
880
944
|
canvas2.style.overflow = "visible";
|
|
881
945
|
let errorDiv = document.getElementById("animation-loop-error");
|
|
@@ -892,6 +956,9 @@ var __exports__ = (() => {
|
|
|
892
956
|
}
|
|
893
957
|
}
|
|
894
958
|
function clearError(device) {
|
|
959
|
+
if (!device) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
895
962
|
const errorDiv = document.getElementById("animation-loop-error");
|
|
896
963
|
if (errorDiv) {
|
|
897
964
|
errorDiv.remove();
|
|
@@ -1019,13 +1086,11 @@ var __exports__ = (() => {
|
|
|
1019
1086
|
return moduleData.defaultPipelineFactory;
|
|
1020
1087
|
}
|
|
1021
1088
|
device;
|
|
1022
|
-
cachingEnabled;
|
|
1023
|
-
destroyPolicy;
|
|
1024
|
-
debug;
|
|
1025
1089
|
_hashCounter = 0;
|
|
1026
1090
|
_hashes = {};
|
|
1027
1091
|
_renderPipelineCache = {};
|
|
1028
1092
|
_computePipelineCache = {};
|
|
1093
|
+
_sharedRenderPipelineCache = {};
|
|
1029
1094
|
get [Symbol.toStringTag]() {
|
|
1030
1095
|
return "PipelineFactory";
|
|
1031
1096
|
}
|
|
@@ -1034,35 +1099,34 @@ var __exports__ = (() => {
|
|
|
1034
1099
|
}
|
|
1035
1100
|
constructor(device) {
|
|
1036
1101
|
this.device = device;
|
|
1037
|
-
this.cachingEnabled = device.props._cachePipelines;
|
|
1038
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1039
|
-
this.debug = device.props.debugFactories;
|
|
1040
1102
|
}
|
|
1041
1103
|
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1042
1104
|
createRenderPipeline(props) {
|
|
1043
|
-
if (!this.
|
|
1105
|
+
if (!this.device.props._cachePipelines) {
|
|
1044
1106
|
return this.device.createRenderPipeline(props);
|
|
1045
1107
|
}
|
|
1046
1108
|
const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
|
|
1047
1109
|
const cache = this._renderPipelineCache;
|
|
1048
1110
|
const hash = this._hashRenderPipeline(allProps);
|
|
1049
|
-
let pipeline = cache[hash]?.
|
|
1111
|
+
let pipeline = cache[hash]?.resource;
|
|
1050
1112
|
if (!pipeline) {
|
|
1113
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
1051
1114
|
pipeline = this.device.createRenderPipeline({
|
|
1052
1115
|
...allProps,
|
|
1053
|
-
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
|
|
1116
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
1117
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
1054
1118
|
});
|
|
1055
1119
|
pipeline.hash = hash;
|
|
1056
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
1057
|
-
if (this.
|
|
1120
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
1121
|
+
if (this.device.props.debugFactories) {
|
|
1058
1122
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1059
1123
|
}
|
|
1060
1124
|
} else {
|
|
1061
1125
|
cache[hash].useCount++;
|
|
1062
|
-
if (this.
|
|
1126
|
+
if (this.device.props.debugFactories) {
|
|
1063
1127
|
import_core4.log.log(
|
|
1064
1128
|
3,
|
|
1065
|
-
`${this}: ${cache[hash].
|
|
1129
|
+
`${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1066
1130
|
)();
|
|
1067
1131
|
}
|
|
1068
1132
|
}
|
|
@@ -1070,36 +1134,36 @@ var __exports__ = (() => {
|
|
|
1070
1134
|
}
|
|
1071
1135
|
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
1072
1136
|
createComputePipeline(props) {
|
|
1073
|
-
if (!this.
|
|
1137
|
+
if (!this.device.props._cachePipelines) {
|
|
1074
1138
|
return this.device.createComputePipeline(props);
|
|
1075
1139
|
}
|
|
1076
1140
|
const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
|
|
1077
1141
|
const cache = this._computePipelineCache;
|
|
1078
1142
|
const hash = this._hashComputePipeline(allProps);
|
|
1079
|
-
let pipeline = cache[hash]?.
|
|
1143
|
+
let pipeline = cache[hash]?.resource;
|
|
1080
1144
|
if (!pipeline) {
|
|
1081
1145
|
pipeline = this.device.createComputePipeline({
|
|
1082
1146
|
...allProps,
|
|
1083
1147
|
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
1084
1148
|
});
|
|
1085
1149
|
pipeline.hash = hash;
|
|
1086
|
-
cache[hash] = { pipeline, useCount: 1 };
|
|
1087
|
-
if (this.
|
|
1150
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
1151
|
+
if (this.device.props.debugFactories) {
|
|
1088
1152
|
import_core4.log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
1089
1153
|
}
|
|
1090
1154
|
} else {
|
|
1091
1155
|
cache[hash].useCount++;
|
|
1092
|
-
if (this.
|
|
1156
|
+
if (this.device.props.debugFactories) {
|
|
1093
1157
|
import_core4.log.log(
|
|
1094
1158
|
3,
|
|
1095
|
-
`${this}: ${cache[hash].
|
|
1159
|
+
`${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`
|
|
1096
1160
|
)();
|
|
1097
1161
|
}
|
|
1098
1162
|
}
|
|
1099
1163
|
return pipeline;
|
|
1100
1164
|
}
|
|
1101
1165
|
release(pipeline) {
|
|
1102
|
-
if (!this.
|
|
1166
|
+
if (!this.device.props._cachePipelines) {
|
|
1103
1167
|
pipeline.destroy();
|
|
1104
1168
|
return;
|
|
1105
1169
|
}
|
|
@@ -1108,28 +1172,55 @@ var __exports__ = (() => {
|
|
|
1108
1172
|
cache[hash].useCount--;
|
|
1109
1173
|
if (cache[hash].useCount === 0) {
|
|
1110
1174
|
this._destroyPipeline(pipeline);
|
|
1111
|
-
if (this.
|
|
1175
|
+
if (this.device.props.debugFactories) {
|
|
1112
1176
|
import_core4.log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
1113
1177
|
}
|
|
1114
1178
|
} else if (cache[hash].useCount < 0) {
|
|
1115
1179
|
import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
1116
1180
|
cache[hash].useCount = 0;
|
|
1117
|
-
} else if (this.
|
|
1181
|
+
} else if (this.device.props.debugFactories) {
|
|
1118
1182
|
import_core4.log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
1119
1183
|
}
|
|
1120
1184
|
}
|
|
1185
|
+
createSharedRenderPipeline(props) {
|
|
1186
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
1187
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1188
|
+
if (!sharedCacheItem) {
|
|
1189
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
1190
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
1191
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
1192
|
+
}
|
|
1193
|
+
sharedCacheItem.useCount++;
|
|
1194
|
+
return sharedCacheItem.resource;
|
|
1195
|
+
}
|
|
1196
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
1197
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
1201
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1202
|
+
if (!sharedCacheItem) {
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
sharedCacheItem.useCount--;
|
|
1206
|
+
if (sharedCacheItem.useCount === 0) {
|
|
1207
|
+
sharedCacheItem.resource.destroy();
|
|
1208
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1121
1211
|
// PRIVATE
|
|
1122
|
-
/** Destroy a cached pipeline, removing it from the cache
|
|
1212
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
1123
1213
|
_destroyPipeline(pipeline) {
|
|
1124
1214
|
const cache = this._getCache(pipeline);
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
return false;
|
|
1128
|
-
case "unused":
|
|
1129
|
-
delete cache[pipeline.hash];
|
|
1130
|
-
pipeline.destroy();
|
|
1131
|
-
return true;
|
|
1215
|
+
if (!this.device.props._destroyPipelines) {
|
|
1216
|
+
return false;
|
|
1132
1217
|
}
|
|
1218
|
+
delete cache[pipeline.hash];
|
|
1219
|
+
pipeline.destroy();
|
|
1220
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
1221
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
1222
|
+
}
|
|
1223
|
+
return true;
|
|
1133
1224
|
}
|
|
1134
1225
|
/** Get the appropriate cache for the type of pipeline */
|
|
1135
1226
|
_getCache(pipeline) {
|
|
@@ -1158,24 +1249,35 @@ var __exports__ = (() => {
|
|
|
1158
1249
|
_hashRenderPipeline(props) {
|
|
1159
1250
|
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
1160
1251
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1161
|
-
const varyingHash =
|
|
1252
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
1162
1253
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
1163
1254
|
const { type } = this.device;
|
|
1164
1255
|
switch (type) {
|
|
1165
1256
|
case "webgl":
|
|
1166
|
-
|
|
1257
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1258
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}BL${bufferLayoutHash}`;
|
|
1167
1259
|
case "webgpu":
|
|
1168
1260
|
default:
|
|
1169
1261
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1170
1262
|
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
1171
1263
|
}
|
|
1172
1264
|
}
|
|
1265
|
+
_hashSharedRenderPipeline(props) {
|
|
1266
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
1267
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1268
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
1269
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
1270
|
+
}
|
|
1173
1271
|
_getHash(key) {
|
|
1174
1272
|
if (this._hashes[key] === void 0) {
|
|
1175
1273
|
this._hashes[key] = this._hashCounter++;
|
|
1176
1274
|
}
|
|
1177
1275
|
return this._hashes[key];
|
|
1178
1276
|
}
|
|
1277
|
+
_getWebGLVaryingHash(props) {
|
|
1278
|
+
const { varyings = [], bufferMode = null } = props;
|
|
1279
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
1280
|
+
}
|
|
1179
1281
|
};
|
|
1180
1282
|
var PipelineFactory = _PipelineFactory;
|
|
1181
1283
|
__publicField(PipelineFactory, "defaultProps", { ...import_core4.RenderPipeline.defaultProps });
|
|
@@ -1190,9 +1292,6 @@ var __exports__ = (() => {
|
|
|
1190
1292
|
return moduleData.defaultShaderFactory;
|
|
1191
1293
|
}
|
|
1192
1294
|
device;
|
|
1193
|
-
cachingEnabled;
|
|
1194
|
-
destroyPolicy;
|
|
1195
|
-
debug;
|
|
1196
1295
|
_cache = {};
|
|
1197
1296
|
get [Symbol.toStringTag]() {
|
|
1198
1297
|
return "ShaderFactory";
|
|
@@ -1203,40 +1302,37 @@ var __exports__ = (() => {
|
|
|
1203
1302
|
/** @internal */
|
|
1204
1303
|
constructor(device) {
|
|
1205
1304
|
this.device = device;
|
|
1206
|
-
this.cachingEnabled = device.props._cacheShaders;
|
|
1207
|
-
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
1208
|
-
this.debug = true;
|
|
1209
1305
|
}
|
|
1210
1306
|
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
1211
1307
|
createShader(props) {
|
|
1212
|
-
if (!this.
|
|
1308
|
+
if (!this.device.props._cacheShaders) {
|
|
1213
1309
|
return this.device.createShader(props);
|
|
1214
1310
|
}
|
|
1215
1311
|
const key = this._hashShader(props);
|
|
1216
1312
|
let cacheEntry = this._cache[key];
|
|
1217
1313
|
if (!cacheEntry) {
|
|
1218
|
-
const
|
|
1314
|
+
const resource = this.device.createShader({
|
|
1219
1315
|
...props,
|
|
1220
1316
|
id: props.id ? `${props.id}-cached` : void 0
|
|
1221
1317
|
});
|
|
1222
|
-
this._cache[key] = cacheEntry = {
|
|
1223
|
-
if (this.
|
|
1224
|
-
import_core5.log.log(3, `${this}: Created new shader ${
|
|
1318
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
1319
|
+
if (this.device.props.debugFactories) {
|
|
1320
|
+
import_core5.log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
1225
1321
|
}
|
|
1226
1322
|
} else {
|
|
1227
1323
|
cacheEntry.useCount++;
|
|
1228
|
-
if (this.
|
|
1324
|
+
if (this.device.props.debugFactories) {
|
|
1229
1325
|
import_core5.log.log(
|
|
1230
1326
|
3,
|
|
1231
|
-
`${this}: Reusing shader ${cacheEntry.
|
|
1327
|
+
`${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`
|
|
1232
1328
|
)();
|
|
1233
1329
|
}
|
|
1234
1330
|
}
|
|
1235
|
-
return cacheEntry.
|
|
1331
|
+
return cacheEntry.resource;
|
|
1236
1332
|
}
|
|
1237
1333
|
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
1238
1334
|
release(shader) {
|
|
1239
|
-
if (!this.
|
|
1335
|
+
if (!this.device.props._cacheShaders) {
|
|
1240
1336
|
shader.destroy();
|
|
1241
1337
|
return;
|
|
1242
1338
|
}
|
|
@@ -1245,16 +1341,16 @@ var __exports__ = (() => {
|
|
|
1245
1341
|
if (cacheEntry) {
|
|
1246
1342
|
cacheEntry.useCount--;
|
|
1247
1343
|
if (cacheEntry.useCount === 0) {
|
|
1248
|
-
if (this.
|
|
1344
|
+
if (this.device.props._destroyShaders) {
|
|
1249
1345
|
delete this._cache[key];
|
|
1250
|
-
cacheEntry.
|
|
1251
|
-
if (this.
|
|
1346
|
+
cacheEntry.resource.destroy();
|
|
1347
|
+
if (this.device.props.debugFactories) {
|
|
1252
1348
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
1253
1349
|
}
|
|
1254
1350
|
}
|
|
1255
1351
|
} else if (cacheEntry.useCount < 0) {
|
|
1256
1352
|
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
1257
|
-
} else if (this.
|
|
1353
|
+
} else if (this.device.props.debugFactories) {
|
|
1258
1354
|
import_core5.log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
1259
1355
|
}
|
|
1260
1356
|
}
|
|
@@ -1408,6 +1504,16 @@ var __exports__ = (() => {
|
|
|
1408
1504
|
};
|
|
1409
1505
|
|
|
1410
1506
|
// src/utils/buffer-layout-order.ts
|
|
1507
|
+
function getMinLocation(attributeNames, shaderLayoutMap) {
|
|
1508
|
+
let minLocation = Infinity;
|
|
1509
|
+
for (const name of attributeNames) {
|
|
1510
|
+
const location = shaderLayoutMap[name];
|
|
1511
|
+
if (location !== void 0) {
|
|
1512
|
+
minLocation = Math.min(minLocation, location);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
return minLocation;
|
|
1516
|
+
}
|
|
1411
1517
|
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
1412
1518
|
const shaderLayoutMap = Object.fromEntries(
|
|
1413
1519
|
shaderLayout.attributes.map((attr) => [attr.name, attr.location])
|
|
@@ -1416,8 +1522,8 @@ var __exports__ = (() => {
|
|
|
1416
1522
|
sortedLayout.sort((a, b) => {
|
|
1417
1523
|
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
1418
1524
|
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
1419
|
-
const minLocationA =
|
|
1420
|
-
const minLocationB =
|
|
1525
|
+
const minLocationA = getMinLocation(attributeNamesA, shaderLayoutMap);
|
|
1526
|
+
const minLocationB = getMinLocation(attributeNamesB, shaderLayoutMap);
|
|
1421
1527
|
return minLocationA - minLocationB;
|
|
1422
1528
|
});
|
|
1423
1529
|
return sortedLayout;
|
|
@@ -1632,6 +1738,15 @@ var __exports__ = (() => {
|
|
|
1632
1738
|
function isTextureImageData(data) {
|
|
1633
1739
|
return typeof data === "object" && data !== null && "data" in data && "width" in data && "height" in data;
|
|
1634
1740
|
}
|
|
1741
|
+
function resolveTextureImageFormat(data) {
|
|
1742
|
+
const { textureFormat, format } = data;
|
|
1743
|
+
if (textureFormat && format && textureFormat !== format) {
|
|
1744
|
+
throw new Error(
|
|
1745
|
+
`Conflicting texture formats "${textureFormat}" and "${format}" provided for the same mip level`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return textureFormat ?? format;
|
|
1749
|
+
}
|
|
1635
1750
|
function getCubeFaceIndex(face) {
|
|
1636
1751
|
const idx = TEXTURE_CUBE_FACE_MAP[face];
|
|
1637
1752
|
if (idx === void 0)
|
|
@@ -1664,6 +1779,7 @@ var __exports__ = (() => {
|
|
|
1664
1779
|
subresources.push({
|
|
1665
1780
|
type: "texture-data",
|
|
1666
1781
|
data: imageData,
|
|
1782
|
+
textureFormat: resolveTextureImageFormat(imageData),
|
|
1667
1783
|
z,
|
|
1668
1784
|
mipLevel
|
|
1669
1785
|
});
|
|
@@ -1700,7 +1816,7 @@ var __exports__ = (() => {
|
|
|
1700
1816
|
data.forEach((cubeData, cubeIndex) => {
|
|
1701
1817
|
for (const [face, faceData] of Object.entries(cubeData)) {
|
|
1702
1818
|
const faceDepth = getCubeArrayFaceIndex(cubeIndex, face);
|
|
1703
|
-
getTexture2DSubresources(faceDepth, faceData);
|
|
1819
|
+
subresources.push(...getTexture2DSubresources(faceDepth, faceData));
|
|
1704
1820
|
}
|
|
1705
1821
|
});
|
|
1706
1822
|
return subresources;
|
|
@@ -1762,6 +1878,9 @@ var __exports__ = (() => {
|
|
|
1762
1878
|
try {
|
|
1763
1879
|
const propsWithSyncData = await this._loadAllData(originalPropsWithAsyncData);
|
|
1764
1880
|
this._checkNotDestroyed();
|
|
1881
|
+
const subresources = propsWithSyncData.data ? getTextureSubresources(propsWithSyncData) : [];
|
|
1882
|
+
const userProvidedFormat = "format" in originalPropsWithAsyncData && originalPropsWithAsyncData.format !== void 0;
|
|
1883
|
+
const userProvidedUsage = "usage" in originalPropsWithAsyncData && originalPropsWithAsyncData.usage !== void 0;
|
|
1765
1884
|
const deduceSize = () => {
|
|
1766
1885
|
if (this.props.width && this.props.height) {
|
|
1767
1886
|
return { width: this.props.width, height: this.props.height };
|
|
@@ -1776,45 +1895,39 @@ var __exports__ = (() => {
|
|
|
1776
1895
|
if (!size || size.width <= 0 || size.height <= 0) {
|
|
1777
1896
|
throw new Error(`${this} size could not be determined or was zero`);
|
|
1778
1897
|
}
|
|
1898
|
+
const textureData = analyzeTextureSubresources(this.device, subresources, size, {
|
|
1899
|
+
format: userProvidedFormat ? originalPropsWithAsyncData.format : void 0
|
|
1900
|
+
});
|
|
1901
|
+
const resolvedFormat = textureData.format ?? this.props.format;
|
|
1779
1902
|
const baseTextureProps = {
|
|
1780
1903
|
...this.props,
|
|
1781
1904
|
...size,
|
|
1905
|
+
format: resolvedFormat,
|
|
1782
1906
|
mipLevels: 1,
|
|
1783
1907
|
// temporary; updated below
|
|
1784
1908
|
data: void 0
|
|
1785
1909
|
};
|
|
1910
|
+
if (this.device.isTextureFormatCompressed(resolvedFormat) && !userProvidedUsage) {
|
|
1911
|
+
baseTextureProps.usage = import_core9.Texture.SAMPLE | import_core9.Texture.COPY_DST;
|
|
1912
|
+
}
|
|
1913
|
+
const shouldGenerateMipmaps = this.props.mipmaps && !textureData.hasExplicitMipChain && !this.device.isTextureFormatCompressed(resolvedFormat);
|
|
1914
|
+
if (this.device.type === "webgpu" && shouldGenerateMipmaps) {
|
|
1915
|
+
const requiredUsage = this.props.dimension === "3d" ? import_core9.Texture.SAMPLE | import_core9.Texture.STORAGE | import_core9.Texture.COPY_DST | import_core9.Texture.COPY_SRC : import_core9.Texture.SAMPLE | import_core9.Texture.RENDER | import_core9.Texture.COPY_DST | import_core9.Texture.COPY_SRC;
|
|
1916
|
+
baseTextureProps.usage |= requiredUsage;
|
|
1917
|
+
}
|
|
1786
1918
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
1787
|
-
const desired = this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1919
|
+
const desired = textureData.hasExplicitMipChain ? textureData.mipLevels : this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1788
1920
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
1789
1921
|
this._texture = this.device.createTexture(finalTextureProps);
|
|
1790
1922
|
this._sampler = this.texture.sampler;
|
|
1791
1923
|
this._view = this.texture.view;
|
|
1792
|
-
if (
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
case "2d":
|
|
1798
|
-
this.setTexture2DData(propsWithSyncData.data);
|
|
1799
|
-
break;
|
|
1800
|
-
case "3d":
|
|
1801
|
-
this.setTexture3DData(propsWithSyncData.data);
|
|
1802
|
-
break;
|
|
1803
|
-
case "2d-array":
|
|
1804
|
-
this.setTextureArrayData(propsWithSyncData.data);
|
|
1805
|
-
break;
|
|
1806
|
-
case "cube":
|
|
1807
|
-
this.setTextureCubeData(propsWithSyncData.data);
|
|
1808
|
-
break;
|
|
1809
|
-
case "cube-array":
|
|
1810
|
-
this.setTextureCubeArrayData(propsWithSyncData.data);
|
|
1811
|
-
break;
|
|
1812
|
-
default: {
|
|
1813
|
-
throw new Error(`Unhandled dimension ${propsWithSyncData.dimension}`);
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1924
|
+
if (textureData.subresources.length) {
|
|
1925
|
+
this._setTextureSubresources(textureData.subresources);
|
|
1926
|
+
}
|
|
1927
|
+
if (this.props.mipmaps && !textureData.hasExplicitMipChain && !shouldGenerateMipmaps) {
|
|
1928
|
+
import_core9.log.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)();
|
|
1816
1929
|
}
|
|
1817
|
-
if (
|
|
1930
|
+
if (shouldGenerateMipmaps) {
|
|
1818
1931
|
this.generateMipmaps();
|
|
1819
1932
|
}
|
|
1820
1933
|
this.isReady = true;
|
|
@@ -1838,10 +1951,10 @@ var __exports__ = (() => {
|
|
|
1838
1951
|
generateMipmaps() {
|
|
1839
1952
|
if (this.device.type === "webgl") {
|
|
1840
1953
|
this.texture.generateMipmapsWebGL();
|
|
1954
|
+
} else if (this.device.type === "webgpu") {
|
|
1955
|
+
this.device.generateMipmapsWebGPU(this.texture);
|
|
1841
1956
|
} else {
|
|
1842
|
-
import_core9.log.warn(
|
|
1843
|
-
"Mipmap generation not yet implemented on WebGPU: your texture data will not be correctly initialized"
|
|
1844
|
-
);
|
|
1957
|
+
import_core9.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
1845
1958
|
}
|
|
1846
1959
|
}
|
|
1847
1960
|
/** Set sampler or create one from props */
|
|
@@ -1939,8 +2052,21 @@ var __exports__ = (() => {
|
|
|
1939
2052
|
this.texture.copyExternalImage({ image, z, mipLevel, flipY });
|
|
1940
2053
|
break;
|
|
1941
2054
|
case "texture-data":
|
|
1942
|
-
const { data } = subresource;
|
|
1943
|
-
|
|
2055
|
+
const { data, textureFormat } = subresource;
|
|
2056
|
+
if (textureFormat && textureFormat !== this.texture.format) {
|
|
2057
|
+
throw new Error(
|
|
2058
|
+
`${this} mip level ${mipLevel} uses format "${textureFormat}" but texture format is "${this.texture.format}"`
|
|
2059
|
+
);
|
|
2060
|
+
}
|
|
2061
|
+
this.texture.writeData(data.data, {
|
|
2062
|
+
x: 0,
|
|
2063
|
+
y: 0,
|
|
2064
|
+
z,
|
|
2065
|
+
width: data.width,
|
|
2066
|
+
height: data.height,
|
|
2067
|
+
depthOrArrayLayers: 1,
|
|
2068
|
+
mipLevel
|
|
2069
|
+
});
|
|
1944
2070
|
break;
|
|
1945
2071
|
default:
|
|
1946
2072
|
throw new Error("Unsupported 2D mip-level payload");
|
|
@@ -1972,6 +2098,140 @@ var __exports__ = (() => {
|
|
|
1972
2098
|
data: null,
|
|
1973
2099
|
mipmaps: false
|
|
1974
2100
|
});
|
|
2101
|
+
function getTextureSubresources(props) {
|
|
2102
|
+
if (!props.data) {
|
|
2103
|
+
return [];
|
|
2104
|
+
}
|
|
2105
|
+
switch (props.dimension) {
|
|
2106
|
+
case "1d":
|
|
2107
|
+
return getTexture1DSubresources(props.data);
|
|
2108
|
+
case "2d":
|
|
2109
|
+
return getTexture2DSubresources(0, props.data);
|
|
2110
|
+
case "3d":
|
|
2111
|
+
return getTexture3DSubresources(props.data);
|
|
2112
|
+
case "2d-array":
|
|
2113
|
+
return getTextureArraySubresources(props.data);
|
|
2114
|
+
case "cube":
|
|
2115
|
+
return getTextureCubeSubresources(props.data);
|
|
2116
|
+
case "cube-array":
|
|
2117
|
+
return getTextureCubeArraySubresources(props.data);
|
|
2118
|
+
default:
|
|
2119
|
+
throw new Error(`Unhandled dimension ${props.dimension}`);
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
function analyzeTextureSubresources(device, subresources, size, options) {
|
|
2123
|
+
if (subresources.length === 0) {
|
|
2124
|
+
return {
|
|
2125
|
+
subresources,
|
|
2126
|
+
mipLevels: 1,
|
|
2127
|
+
format: options.format,
|
|
2128
|
+
hasExplicitMipChain: false
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
const groupedSubresources = /* @__PURE__ */ new Map();
|
|
2132
|
+
for (const subresource of subresources) {
|
|
2133
|
+
const group = groupedSubresources.get(subresource.z) ?? [];
|
|
2134
|
+
group.push(subresource);
|
|
2135
|
+
groupedSubresources.set(subresource.z, group);
|
|
2136
|
+
}
|
|
2137
|
+
const hasExplicitMipChain = subresources.some((subresource) => subresource.mipLevel > 0);
|
|
2138
|
+
let resolvedFormat = options.format;
|
|
2139
|
+
let resolvedMipLevels = Number.POSITIVE_INFINITY;
|
|
2140
|
+
const validSubresources = [];
|
|
2141
|
+
for (const [z, sliceSubresources] of groupedSubresources) {
|
|
2142
|
+
const sortedSubresources = [...sliceSubresources].sort(
|
|
2143
|
+
(left, right) => left.mipLevel - right.mipLevel
|
|
2144
|
+
);
|
|
2145
|
+
const baseLevel = sortedSubresources[0];
|
|
2146
|
+
if (!baseLevel || baseLevel.mipLevel !== 0) {
|
|
2147
|
+
throw new Error(`DynamicTexture: slice ${z} is missing mip level 0`);
|
|
2148
|
+
}
|
|
2149
|
+
const baseSize = getTextureSubresourceSize(device, baseLevel);
|
|
2150
|
+
if (baseSize.width !== size.width || baseSize.height !== size.height) {
|
|
2151
|
+
throw new Error(
|
|
2152
|
+
`DynamicTexture: slice ${z} base level dimensions ${baseSize.width}x${baseSize.height} do not match expected ${size.width}x${size.height}`
|
|
2153
|
+
);
|
|
2154
|
+
}
|
|
2155
|
+
const baseFormat = getTextureSubresourceFormat(baseLevel);
|
|
2156
|
+
if (baseFormat) {
|
|
2157
|
+
if (resolvedFormat && resolvedFormat !== baseFormat) {
|
|
2158
|
+
throw new Error(
|
|
2159
|
+
`DynamicTexture: slice ${z} base level format "${baseFormat}" does not match texture format "${resolvedFormat}"`
|
|
2160
|
+
);
|
|
2161
|
+
}
|
|
2162
|
+
resolvedFormat = baseFormat;
|
|
2163
|
+
}
|
|
2164
|
+
const mipLevelLimit = resolvedFormat && device.isTextureFormatCompressed(resolvedFormat) ? (
|
|
2165
|
+
// Block-compressed formats cannot have mips smaller than a single compression block.
|
|
2166
|
+
getMaxCompressedMipLevels(device, baseSize.width, baseSize.height, resolvedFormat)
|
|
2167
|
+
) : device.getMipLevelCount(baseSize.width, baseSize.height);
|
|
2168
|
+
let validMipLevelsForSlice = 0;
|
|
2169
|
+
for (let expectedMipLevel = 0; expectedMipLevel < sortedSubresources.length; expectedMipLevel++) {
|
|
2170
|
+
const subresource = sortedSubresources[expectedMipLevel];
|
|
2171
|
+
if (!subresource || subresource.mipLevel !== expectedMipLevel) {
|
|
2172
|
+
break;
|
|
2173
|
+
}
|
|
2174
|
+
if (expectedMipLevel >= mipLevelLimit) {
|
|
2175
|
+
break;
|
|
2176
|
+
}
|
|
2177
|
+
const subresourceSize = getTextureSubresourceSize(device, subresource);
|
|
2178
|
+
const expectedWidth = Math.max(1, baseSize.width >> expectedMipLevel);
|
|
2179
|
+
const expectedHeight = Math.max(1, baseSize.height >> expectedMipLevel);
|
|
2180
|
+
if (subresourceSize.width !== expectedWidth || subresourceSize.height !== expectedHeight) {
|
|
2181
|
+
break;
|
|
2182
|
+
}
|
|
2183
|
+
const subresourceFormat = getTextureSubresourceFormat(subresource);
|
|
2184
|
+
if (subresourceFormat) {
|
|
2185
|
+
if (!resolvedFormat) {
|
|
2186
|
+
resolvedFormat = subresourceFormat;
|
|
2187
|
+
}
|
|
2188
|
+
if (subresourceFormat !== resolvedFormat) {
|
|
2189
|
+
break;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
validMipLevelsForSlice++;
|
|
2193
|
+
validSubresources.push(subresource);
|
|
2194
|
+
}
|
|
2195
|
+
resolvedMipLevels = Math.min(resolvedMipLevels, validMipLevelsForSlice);
|
|
2196
|
+
}
|
|
2197
|
+
const mipLevels = Number.isFinite(resolvedMipLevels) ? Math.max(1, resolvedMipLevels) : 1;
|
|
2198
|
+
return {
|
|
2199
|
+
// Keep every slice trimmed to the same mip count so the texture shape stays internally consistent.
|
|
2200
|
+
subresources: validSubresources.filter((subresource) => subresource.mipLevel < mipLevels),
|
|
2201
|
+
mipLevels,
|
|
2202
|
+
format: resolvedFormat,
|
|
2203
|
+
hasExplicitMipChain
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
function getTextureSubresourceFormat(subresource) {
|
|
2207
|
+
if (subresource.type !== "texture-data") {
|
|
2208
|
+
return void 0;
|
|
2209
|
+
}
|
|
2210
|
+
return subresource.textureFormat ?? resolveTextureImageFormat(subresource.data);
|
|
2211
|
+
}
|
|
2212
|
+
function getTextureSubresourceSize(device, subresource) {
|
|
2213
|
+
switch (subresource.type) {
|
|
2214
|
+
case "external-image":
|
|
2215
|
+
return device.getExternalImageSize(subresource.image);
|
|
2216
|
+
case "texture-data":
|
|
2217
|
+
return { width: subresource.data.width, height: subresource.data.height };
|
|
2218
|
+
default:
|
|
2219
|
+
throw new Error("Unsupported texture subresource");
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
function getMaxCompressedMipLevels(device, baseWidth, baseHeight, format) {
|
|
2223
|
+
const { blockWidth = 1, blockHeight = 1 } = device.getTextureFormatInfo(format);
|
|
2224
|
+
let mipLevels = 1;
|
|
2225
|
+
for (let mipLevel = 1; ; mipLevel++) {
|
|
2226
|
+
const width = Math.max(1, baseWidth >> mipLevel);
|
|
2227
|
+
const height = Math.max(1, baseHeight >> mipLevel);
|
|
2228
|
+
if (width < blockWidth || height < blockHeight) {
|
|
2229
|
+
break;
|
|
2230
|
+
}
|
|
2231
|
+
mipLevels++;
|
|
2232
|
+
}
|
|
2233
|
+
return mipLevels;
|
|
2234
|
+
}
|
|
1975
2235
|
async function awaitAllPromises(x) {
|
|
1976
2236
|
x = await x;
|
|
1977
2237
|
if (Array.isArray(x)) {
|
|
@@ -2147,7 +2407,7 @@ var __exports__ = (() => {
|
|
|
2147
2407
|
if (!this._destroyed) {
|
|
2148
2408
|
this.pipelineFactory.release(this.pipeline);
|
|
2149
2409
|
this.shaderFactory.release(this.pipeline.vs);
|
|
2150
|
-
if (this.pipeline.fs) {
|
|
2410
|
+
if (this.pipeline.fs && this.pipeline.fs !== this.pipeline.vs) {
|
|
2151
2411
|
this.shaderFactory.release(this.pipeline.fs);
|
|
2152
2412
|
}
|
|
2153
2413
|
this._uniformStore.destroy();
|
|
@@ -2197,9 +2457,6 @@ var __exports__ = (() => {
|
|
|
2197
2457
|
this._logDrawCallStart();
|
|
2198
2458
|
this.pipeline = this._updatePipeline();
|
|
2199
2459
|
const syncBindings = this._getBindings();
|
|
2200
|
-
this.pipeline.setBindings(syncBindings, {
|
|
2201
|
-
disableWarnings: this.props.disableWarnings
|
|
2202
|
-
});
|
|
2203
2460
|
const { indexBuffer } = this.vertexArray;
|
|
2204
2461
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
2205
2462
|
drawSuccess = this.pipeline.draw({
|
|
@@ -2210,6 +2467,11 @@ var __exports__ = (() => {
|
|
|
2210
2467
|
instanceCount: this.instanceCount,
|
|
2211
2468
|
indexCount,
|
|
2212
2469
|
transformFeedback: this.transformFeedback || void 0,
|
|
2470
|
+
// Pipelines may be shared across models when caching is enabled, so bindings
|
|
2471
|
+
// and WebGL uniforms must be supplied on every draw instead of being stored
|
|
2472
|
+
// on the pipeline instance.
|
|
2473
|
+
bindings: syncBindings,
|
|
2474
|
+
uniforms: this.props.uniforms,
|
|
2213
2475
|
// WebGL shares underlying cached pipelines even for models that have different parameters and topology,
|
|
2214
2476
|
// so we must provide our unique parameters to each draw
|
|
2215
2477
|
// (In WebGPU most parameters are encoded in the pipeline and cannot be changed per draw call)
|
|
@@ -2526,8 +2788,9 @@ var __exports__ = (() => {
|
|
|
2526
2788
|
);
|
|
2527
2789
|
if (prevShaderVs)
|
|
2528
2790
|
this.shaderFactory.release(prevShaderVs);
|
|
2529
|
-
if (prevShaderFs)
|
|
2791
|
+
if (prevShaderFs && prevShaderFs !== prevShaderVs) {
|
|
2530
2792
|
this.shaderFactory.release(prevShaderFs);
|
|
2793
|
+
}
|
|
2531
2794
|
}
|
|
2532
2795
|
return this.pipeline;
|
|
2533
2796
|
}
|
|
@@ -2611,6 +2874,8 @@ var __exports__ = (() => {
|
|
|
2611
2874
|
indexBuffer: null,
|
|
2612
2875
|
attributes: {},
|
|
2613
2876
|
constantAttributes: {},
|
|
2877
|
+
bindings: {},
|
|
2878
|
+
uniforms: {},
|
|
2614
2879
|
varyings: [],
|
|
2615
2880
|
isInstanced: void 0,
|
|
2616
2881
|
instanceCount: 0,
|
|
@@ -2915,9 +3180,9 @@ var __exports__ = (() => {
|
|
|
2915
3180
|
var CLIPSPACE_VERTEX_SHADER_WGSL = (
|
|
2916
3181
|
/* wgsl */
|
|
2917
3182
|
`struct VertexInputs {
|
|
2918
|
-
@location(0)
|
|
2919
|
-
@location(1)
|
|
2920
|
-
@location(2)
|
|
3183
|
+
@location(0) clipSpacePositions: vec2<f32>,
|
|
3184
|
+
@location(1) texCoords: vec2<f32>,
|
|
3185
|
+
@location(2) coordinates: vec2<f32>
|
|
2921
3186
|
}
|
|
2922
3187
|
|
|
2923
3188
|
struct FragmentInputs {
|
|
@@ -2930,10 +3195,10 @@ struct FragmentInputs {
|
|
|
2930
3195
|
@vertex
|
|
2931
3196
|
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
2932
3197
|
var outputs: FragmentInputs;
|
|
2933
|
-
outputs.Position = vec4(inputs.
|
|
2934
|
-
outputs.position = inputs.
|
|
2935
|
-
outputs.coordinate = inputs.
|
|
2936
|
-
outputs.uv = inputs.
|
|
3198
|
+
outputs.Position = vec4(inputs.clipSpacePositions, 0., 1.);
|
|
3199
|
+
outputs.position = inputs.clipSpacePositions;
|
|
3200
|
+
outputs.coordinate = inputs.coordinates;
|
|
3201
|
+
outputs.uv = inputs.texCoords;
|
|
2937
3202
|
return outputs;
|
|
2938
3203
|
}
|
|
2939
3204
|
`
|
|
@@ -2999,15 +3264,15 @@ struct backgroundUniforms {
|
|
|
2999
3264
|
};
|
|
3000
3265
|
@group(0) @binding(2) var<uniform> background: backgroundUniforms;
|
|
3001
3266
|
|
|
3002
|
-
fn billboardTexture_getTextureUV(
|
|
3267
|
+
fn billboardTexture_getTextureUV(uv: vec2<f32>) -> vec2<f32> {
|
|
3003
3268
|
let scale: vec2<f32> = background.scale;
|
|
3004
|
-
var position: vec2<f32> = (
|
|
3269
|
+
var position: vec2<f32> = (uv - vec2<f32>(0.5, 0.5)) / scale + vec2<f32>(0.5, 0.5);
|
|
3005
3270
|
return position;
|
|
3006
3271
|
}
|
|
3007
3272
|
|
|
3008
3273
|
@fragment
|
|
3009
3274
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
3010
|
-
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.
|
|
3275
|
+
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.uv);
|
|
3011
3276
|
return textureSample(backgroundTexture, backgroundTextureSampler, position);
|
|
3012
3277
|
}
|
|
3013
3278
|
`
|
|
@@ -3041,20 +3306,22 @@ void main(void) {
|
|
|
3041
3306
|
backgroundTexture = null;
|
|
3042
3307
|
constructor(device, props) {
|
|
3043
3308
|
super(device, {
|
|
3309
|
+
...props,
|
|
3044
3310
|
id: props.id || "background-texture-model",
|
|
3045
3311
|
source: BACKGROUND_FS_WGSL,
|
|
3046
3312
|
fs: BACKGROUND_FS,
|
|
3047
|
-
modules: [backgroundModule],
|
|
3313
|
+
modules: [...props.modules || [], backgroundModule],
|
|
3048
3314
|
parameters: {
|
|
3049
3315
|
depthWriteEnabled: false,
|
|
3316
|
+
...props.parameters || {},
|
|
3050
3317
|
...props.blend ? {
|
|
3051
3318
|
blend: true,
|
|
3052
3319
|
blendColorOperation: "add",
|
|
3053
3320
|
blendAlphaOperation: "add",
|
|
3054
|
-
blendColorSrcFactor: "one",
|
|
3055
|
-
blendColorDstFactor: "one
|
|
3056
|
-
blendAlphaSrcFactor: "one",
|
|
3057
|
-
blendAlphaDstFactor: "one
|
|
3321
|
+
blendColorSrcFactor: "one-minus-dst-alpha",
|
|
3322
|
+
blendColorDstFactor: "one",
|
|
3323
|
+
blendAlphaSrcFactor: "one-minus-dst-alpha",
|
|
3324
|
+
blendAlphaDstFactor: "one"
|
|
3058
3325
|
} : {}
|
|
3059
3326
|
}
|
|
3060
3327
|
});
|
|
@@ -5140,6 +5407,11 @@ void main(void) {
|
|
|
5140
5407
|
}
|
|
5141
5408
|
|
|
5142
5409
|
// src/scenegraph/scenegraph-node.ts
|
|
5410
|
+
function assert2(condition, message) {
|
|
5411
|
+
if (!condition) {
|
|
5412
|
+
throw new Error(message);
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5143
5415
|
var ScenegraphNode = class {
|
|
5144
5416
|
id;
|
|
5145
5417
|
matrix = new Matrix4();
|
|
@@ -5171,14 +5443,17 @@ void main(void) {
|
|
|
5171
5443
|
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
5172
5444
|
}
|
|
5173
5445
|
setPosition(position) {
|
|
5446
|
+
assert2(position.length === 3, "setPosition requires vector argument");
|
|
5174
5447
|
this.position = position;
|
|
5175
5448
|
return this;
|
|
5176
5449
|
}
|
|
5177
5450
|
setRotation(rotation) {
|
|
5451
|
+
assert2(rotation.length === 3 || rotation.length === 4, "setRotation requires vector argument");
|
|
5178
5452
|
this.rotation = rotation;
|
|
5179
5453
|
return this;
|
|
5180
5454
|
}
|
|
5181
5455
|
setScale(scale2) {
|
|
5456
|
+
assert2(scale2.length === 3, "setScale requires vector argument");
|
|
5182
5457
|
this.scale = scale2;
|
|
5183
5458
|
return this;
|
|
5184
5459
|
}
|
|
@@ -5206,17 +5481,18 @@ void main(void) {
|
|
|
5206
5481
|
return this;
|
|
5207
5482
|
}
|
|
5208
5483
|
updateMatrix() {
|
|
5209
|
-
const pos = this.position;
|
|
5210
|
-
const rot = this.rotation;
|
|
5211
|
-
const scale2 = this.scale;
|
|
5212
5484
|
this.matrix.identity();
|
|
5213
|
-
this.matrix.translate(
|
|
5214
|
-
this.
|
|
5215
|
-
|
|
5485
|
+
this.matrix.translate(this.position);
|
|
5486
|
+
if (this.rotation.length === 4) {
|
|
5487
|
+
const rotationMatrix = new Matrix4().fromQuaternion(this.rotation);
|
|
5488
|
+
this.matrix.multiplyRight(rotationMatrix);
|
|
5489
|
+
} else {
|
|
5490
|
+
this.matrix.rotateXYZ(this.rotation);
|
|
5491
|
+
}
|
|
5492
|
+
this.matrix.scale(this.scale);
|
|
5216
5493
|
return this;
|
|
5217
5494
|
}
|
|
5218
|
-
update(
|
|
5219
|
-
const { position, rotation, scale: scale2 } = options;
|
|
5495
|
+
update({ position, rotation, scale: scale2 } = {}) {
|
|
5220
5496
|
if (position) {
|
|
5221
5497
|
this.setPosition(position);
|
|
5222
5498
|
}
|
|
@@ -5266,16 +5542,17 @@ void main(void) {
|
|
|
5266
5542
|
}
|
|
5267
5543
|
*/
|
|
5268
5544
|
_setScenegraphNodeProps(props) {
|
|
5269
|
-
if (
|
|
5545
|
+
if (props?.position) {
|
|
5270
5546
|
this.setPosition(props.position);
|
|
5271
5547
|
}
|
|
5272
|
-
if (
|
|
5548
|
+
if (props?.rotation) {
|
|
5273
5549
|
this.setRotation(props.rotation);
|
|
5274
5550
|
}
|
|
5275
|
-
if (
|
|
5551
|
+
if (props?.scale) {
|
|
5276
5552
|
this.setScale(props.scale);
|
|
5277
5553
|
}
|
|
5278
|
-
|
|
5554
|
+
this.updateMatrix();
|
|
5555
|
+
if (props?.matrix) {
|
|
5279
5556
|
this.setMatrix(props.matrix);
|
|
5280
5557
|
}
|
|
5281
5558
|
Object.assign(this.props, props);
|
|
@@ -5362,6 +5639,17 @@ void main(void) {
|
|
|
5362
5639
|
}
|
|
5363
5640
|
}
|
|
5364
5641
|
}
|
|
5642
|
+
preorderTraversal(visitor, { worldMatrix = new Matrix4() } = {}) {
|
|
5643
|
+
const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
5644
|
+
visitor(this, { worldMatrix: modelMatrix });
|
|
5645
|
+
for (const child of this.children) {
|
|
5646
|
+
if (child instanceof GroupNode) {
|
|
5647
|
+
child.preorderTraversal(visitor, { worldMatrix: modelMatrix });
|
|
5648
|
+
} else {
|
|
5649
|
+
visitor(child, { worldMatrix: modelMatrix });
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
}
|
|
5365
5653
|
};
|
|
5366
5654
|
|
|
5367
5655
|
// src/scenegraph/model-node.ts
|
|
@@ -6639,26 +6927,16 @@ void main(void) {
|
|
|
6639
6927
|
function getFilterShaderWGSL(func) {
|
|
6640
6928
|
return (
|
|
6641
6929
|
/* wgsl */
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
6645
|
-
@group(0) @binding(2) var textureSampler: sampler;
|
|
6646
|
-
|
|
6647
|
-
// This needs to be aligned with
|
|
6648
|
-
// struct FragmentInputs {
|
|
6649
|
-
// @location(0) fragUV: vec2f,
|
|
6650
|
-
// @location(1) fragPosition: vec4f,
|
|
6651
|
-
// @location(2) fragCoordinate: vec4f
|
|
6652
|
-
// };
|
|
6930
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
6931
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
6653
6932
|
|
|
6654
6933
|
@fragment
|
|
6655
6934
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
6656
|
-
let
|
|
6657
|
-
let
|
|
6658
|
-
let texSize = vec2f(textureDimensions(texture, 0));
|
|
6935
|
+
let texCoord = inputs.coordinate;
|
|
6936
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
6659
6937
|
|
|
6660
|
-
var fragColor = textureSample(
|
|
6661
|
-
fragColor = ${func}(fragColor, texSize,
|
|
6938
|
+
var fragColor = textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
6939
|
+
fragColor = ${func}(fragColor, texSize, texCoord);
|
|
6662
6940
|
return fragColor;
|
|
6663
6941
|
}
|
|
6664
6942
|
`
|
|
@@ -6667,23 +6945,14 @@ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
|
6667
6945
|
function getSamplerShaderWGSL(func) {
|
|
6668
6946
|
return (
|
|
6669
6947
|
/* wgsl */
|
|
6670
|
-
|
|
6671
|
-
@group(0) @binding(
|
|
6672
|
-
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
6673
|
-
@group(0) @binding(2) var sampler: sampler;
|
|
6674
|
-
|
|
6675
|
-
struct FragmentInputs = {
|
|
6676
|
-
@location(0) fragUV: vec2f,
|
|
6677
|
-
@location(1) fragPosition: vec4f,
|
|
6678
|
-
@location(2) fragCoordinate: vec4f
|
|
6679
|
-
};
|
|
6948
|
+
`@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
6949
|
+
@group(0) @binding(2) var sourceTextureSampler: sampler;
|
|
6680
6950
|
|
|
6681
6951
|
@fragment
|
|
6682
6952
|
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
6683
|
-
let
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
return fragColor;
|
|
6953
|
+
let texCoord = inputs.coordinate;
|
|
6954
|
+
let texSize = vec2f(textureDimensions(sourceTexture));
|
|
6955
|
+
return ${func}(sourceTexture, sourceTextureSampler, texSize, texCoord);
|
|
6687
6956
|
}
|
|
6688
6957
|
`
|
|
6689
6958
|
);
|
|
@@ -6742,8 +7011,6 @@ void main() {
|
|
|
6742
7011
|
shaderInputs;
|
|
6743
7012
|
passRenderers;
|
|
6744
7013
|
swapFramebuffers;
|
|
6745
|
-
/** For rendering to the screen */
|
|
6746
|
-
clipSpace;
|
|
6747
7014
|
textureModel;
|
|
6748
7015
|
constructor(device, props) {
|
|
6749
7016
|
this.device = device;
|
|
@@ -6762,33 +7029,6 @@ void main() {
|
|
|
6762
7029
|
this.textureModel = new BackgroundTextureModel(device, {
|
|
6763
7030
|
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
6764
7031
|
});
|
|
6765
|
-
this.clipSpace = new ClipSpace(device, {
|
|
6766
|
-
source: (
|
|
6767
|
-
/* wgsl */
|
|
6768
|
-
` @group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
6769
|
-
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
6770
|
-
|
|
6771
|
-
@fragment
|
|
6772
|
-
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
6773
|
-
let texCoord: vec2<f32> = inputs.coordinate;
|
|
6774
|
-
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
6775
|
-
}
|
|
6776
|
-
`
|
|
6777
|
-
),
|
|
6778
|
-
fs: (
|
|
6779
|
-
/* glsl */
|
|
6780
|
-
`#version 300 es
|
|
6781
|
-
|
|
6782
|
-
uniform sampler2D sourceTexture;
|
|
6783
|
-
in vec2 uv;
|
|
6784
|
-
out vec4 fragColor;
|
|
6785
|
-
|
|
6786
|
-
void main() {
|
|
6787
|
-
fragColor = texture(sourceTexture, uv);
|
|
6788
|
-
}
|
|
6789
|
-
`
|
|
6790
|
-
)
|
|
6791
|
-
});
|
|
6792
7032
|
this.passRenderers = props.shaderPasses.map((shaderPass) => new PassRenderer(device, shaderPass));
|
|
6793
7033
|
}
|
|
6794
7034
|
/** Destroys resources created by this ShaderPassRenderer */
|
|
@@ -6797,7 +7037,6 @@ void main() {
|
|
|
6797
7037
|
subPassRenderer.destroy();
|
|
6798
7038
|
}
|
|
6799
7039
|
this.swapFramebuffers.destroy();
|
|
6800
|
-
this.clipSpace.destroy();
|
|
6801
7040
|
this.textureModel.destroy();
|
|
6802
7041
|
}
|
|
6803
7042
|
resize(size) {
|
|
@@ -6809,15 +7048,15 @@ void main() {
|
|
|
6809
7048
|
if (!outputTexture) {
|
|
6810
7049
|
return false;
|
|
6811
7050
|
}
|
|
6812
|
-
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({
|
|
7051
|
+
const framebuffer = this.device.getDefaultCanvasContext().getCurrentFramebuffer({ depthStencilFormat: false });
|
|
6813
7052
|
const renderPass = this.device.beginRenderPass({
|
|
6814
7053
|
id: "shader-pass-renderer-to-screen",
|
|
6815
7054
|
framebuffer,
|
|
6816
7055
|
// clearColor: [1, 1, 0, 1],
|
|
6817
|
-
clearDepth:
|
|
7056
|
+
clearDepth: false
|
|
6818
7057
|
});
|
|
6819
|
-
this.
|
|
6820
|
-
this.
|
|
7058
|
+
this.textureModel.setProps({ backgroundTexture: outputTexture });
|
|
7059
|
+
this.textureModel.draw(renderPass);
|
|
6821
7060
|
renderPass.end();
|
|
6822
7061
|
return true;
|
|
6823
7062
|
}
|
|
@@ -7329,12 +7568,6 @@ const INDEX_PICKING_MODE_INSTANCE = 0;
|
|
|
7329
7568
|
const INDEX_PICKING_MODE_CUSTOM = 1;
|
|
7330
7569
|
const INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
7331
7570
|
|
|
7332
|
-
struct indexPickingFragmentInputs = {
|
|
7333
|
-
objectIndex: int32;
|
|
7334
|
-
};
|
|
7335
|
-
|
|
7336
|
-
let indexPickingFragmentInputs: indexPickingFragmentInputs;
|
|
7337
|
-
|
|
7338
7571
|
/**
|
|
7339
7572
|
* Vertex shaders should call this function to set the object index.
|
|
7340
7573
|
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|