@luma.gl/engine 9.1.0-alpha.9 → 9.1.0-beta.3
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/key-frames.js +1 -0
- package/dist/animation/key-frames.js.map +1 -0
- package/dist/animation/timeline.js +1 -0
- package/dist/animation/timeline.js.map +1 -0
- package/dist/animation-loop/animation-loop-template.js +1 -0
- package/dist/animation-loop/animation-loop-template.js.map +1 -0
- package/dist/animation-loop/animation-loop.d.ts +2 -0
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +24 -6
- package/dist/animation-loop/animation-loop.js.map +1 -0
- package/dist/animation-loop/animation-props.js +1 -0
- package/dist/animation-loop/animation-props.js.map +1 -0
- package/dist/animation-loop/make-animation-loop.d.ts +5 -1
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +3 -1
- package/dist/animation-loop/make-animation-loop.js.map +1 -0
- package/dist/animation-loop/request-animation-frame.d.ts +4 -2
- package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
- package/dist/animation-loop/request-animation-frame.js +5 -3
- package/dist/animation-loop/request-animation-frame.js.map +1 -0
- package/dist/application-utils/load-file.d.ts +1 -1
- package/dist/application-utils/load-file.d.ts.map +1 -1
- package/dist/application-utils/load-file.js +2 -2
- package/dist/application-utils/load-file.js.map +1 -0
- package/dist/application-utils/random.js +1 -0
- package/dist/application-utils/random.js.map +1 -0
- package/dist/async-texture/async-texture.d.ts +14 -2
- package/dist/async-texture/async-texture.d.ts.map +1 -1
- package/dist/async-texture/async-texture.js +31 -0
- package/dist/async-texture/async-texture.js.map +1 -0
- package/dist/compute/buffer-transform.d.ts +41 -0
- package/dist/compute/buffer-transform.d.ts.map +1 -0
- package/dist/{transform → compute}/buffer-transform.js +19 -12
- package/dist/compute/buffer-transform.js.map +1 -0
- package/dist/{computation.d.ts → compute/computation.d.ts} +3 -3
- package/dist/compute/computation.d.ts.map +1 -0
- package/dist/{computation.js → compute/computation.js} +7 -8
- package/dist/compute/computation.js.map +1 -0
- package/dist/compute/swap.d.ts +48 -0
- package/dist/compute/swap.d.ts.map +1 -0
- package/dist/compute/swap.js +91 -0
- package/dist/compute/swap.js.map +1 -0
- package/dist/{transform → compute}/texture-transform.d.ts +0 -6
- package/dist/compute/texture-transform.d.ts.map +1 -0
- package/dist/{transform → compute}/texture-transform.js +10 -15
- package/dist/compute/texture-transform.js.map +1 -0
- package/dist/debug/copy-texture-to-image.js +1 -0
- package/dist/debug/copy-texture-to-image.js.map +1 -0
- package/dist/debug/debug-framebuffer.js +2 -1
- package/dist/debug/debug-framebuffer.js.map +1 -0
- package/dist/debug/debug-shader-layout.js +2 -1
- package/dist/debug/debug-shader-layout.js.map +1 -0
- package/dist/debug/pixel-data-utils.js +1 -0
- package/dist/debug/pixel-data-utils.js.map +1 -0
- package/dist/dist.dev.js +2697 -5857
- package/dist/dist.min.js +420 -103
- package/dist/{lib → factories}/pipeline-factory.d.ts +11 -1
- package/dist/factories/pipeline-factory.d.ts.map +1 -0
- package/dist/factories/pipeline-factory.js +181 -0
- package/dist/factories/pipeline-factory.js.map +1 -0
- package/dist/{lib → factories}/shader-factory.d.ts +5 -1
- package/dist/factories/shader-factory.d.ts.map +1 -0
- package/dist/{lib → factories}/shader-factory.js +39 -4
- package/dist/factories/shader-factory.js.map +1 -0
- package/dist/geometries/cone-geometry.js +1 -0
- package/dist/geometries/cone-geometry.js.map +1 -0
- package/dist/geometries/cube-geometry.js +1 -0
- package/dist/geometries/cube-geometry.js.map +1 -0
- package/dist/geometries/cylinder-geometry.js +1 -0
- package/dist/geometries/cylinder-geometry.js.map +1 -0
- package/dist/geometries/ico-sphere-geometry.js +1 -0
- package/dist/geometries/ico-sphere-geometry.js.map +1 -0
- package/dist/geometries/plane-geometry.js +1 -0
- package/dist/geometries/plane-geometry.js.map +1 -0
- package/dist/geometries/sphere-geometry.js +1 -0
- package/dist/geometries/sphere-geometry.js.map +1 -0
- package/dist/geometries/truncated-cone-geometry.js +1 -0
- package/dist/geometries/truncated-cone-geometry.js.map +1 -0
- package/dist/geometry/geometry-table.js +1 -0
- package/dist/geometry/geometry-table.js.map +1 -0
- package/dist/geometry/geometry-utils.js +1 -0
- package/dist/geometry/geometry-utils.js.map +1 -0
- package/dist/geometry/geometry.js +1 -0
- package/dist/geometry/geometry.js.map +1 -0
- package/dist/geometry/gpu-geometry.js +1 -0
- package/dist/geometry/gpu-geometry.js.map +1 -0
- package/dist/geometry/gpu-table.js +1 -0
- package/dist/geometry/gpu-table.js.map +1 -0
- package/dist/index.cjs +1416 -209
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +23 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -9
- package/dist/index.js.map +1 -0
- package/dist/model/model.d.ts +11 -10
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +93 -70
- package/dist/model/model.js.map +1 -0
- package/dist/model/split-uniforms-and-bindings.d.ts +1 -1
- package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
- package/dist/model/split-uniforms-and-bindings.js +2 -1
- package/dist/model/split-uniforms-and-bindings.js.map +1 -0
- package/dist/models/billboard-texture-model.d.ts +23 -0
- package/dist/models/billboard-texture-model.d.ts.map +1 -0
- package/dist/models/billboard-texture-model.js +78 -0
- package/dist/models/billboard-texture-model.js.map +1 -0
- package/dist/models/billboard-texture-module.d.ts +10 -0
- package/dist/models/billboard-texture-module.d.ts.map +1 -0
- package/dist/models/billboard-texture-module.js +37 -0
- package/dist/models/billboard-texture-module.js.map +1 -0
- package/dist/{lib → models}/clip-space.d.ts +3 -1
- package/dist/models/clip-space.d.ts.map +1 -0
- package/dist/models/clip-space.js +77 -0
- package/dist/models/clip-space.js.map +1 -0
- package/dist/modules/picking/color-picking.d.ts +28 -0
- package/dist/modules/picking/color-picking.d.ts.map +1 -0
- package/dist/modules/picking/color-picking.js +177 -0
- package/dist/modules/picking/color-picking.js.map +1 -0
- package/dist/modules/picking/index-picking.d.ts +32 -0
- package/dist/modules/picking/index-picking.d.ts.map +1 -0
- package/dist/modules/picking/index-picking.js +148 -0
- package/dist/modules/picking/index-picking.js.map +1 -0
- package/dist/modules/picking/legacy-picking-manager.d.ts +27 -0
- package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -0
- package/dist/modules/picking/legacy-picking-manager.js +76 -0
- package/dist/modules/picking/legacy-picking-manager.js.map +1 -0
- package/dist/modules/picking/picking-manager.d.ts +45 -0
- package/dist/modules/picking/picking-manager.d.ts.map +1 -0
- package/dist/modules/picking/picking-manager.js +101 -0
- package/dist/modules/picking/picking-manager.js.map +1 -0
- package/dist/modules/picking/picking-uniforms.d.ts +79 -0
- package/dist/modules/picking/picking-uniforms.d.ts.map +1 -0
- package/dist/modules/picking/picking-uniforms.js +109 -0
- package/dist/modules/picking/picking-uniforms.js.map +1 -0
- package/dist/passes/get-fragment-shader.d.ts +12 -0
- package/dist/passes/get-fragment-shader.d.ts.map +1 -0
- package/dist/passes/get-fragment-shader.js +117 -0
- package/dist/passes/get-fragment-shader.js.map +1 -0
- package/dist/passes/shader-pass-renderer.d.ts +63 -0
- package/dist/passes/shader-pass-renderer.d.ts.map +1 -0
- package/dist/passes/shader-pass-renderer.js +197 -0
- package/dist/passes/shader-pass-renderer.js.map +1 -0
- package/dist/scenegraph/group-node.js +1 -0
- package/dist/scenegraph/group-node.js.map +1 -0
- package/dist/scenegraph/model-node.js +1 -0
- package/dist/scenegraph/model-node.js.map +1 -0
- package/dist/scenegraph/scenegraph-node.js +1 -0
- package/dist/scenegraph/scenegraph-node.js.map +1 -0
- package/dist/shader-inputs.d.ts +8 -21
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +15 -11
- package/dist/shader-inputs.js.map +1 -0
- package/dist/utils/deep-equal.js +1 -0
- package/dist/utils/deep-equal.js.map +1 -0
- package/dist/utils/uid.js +1 -0
- package/dist/utils/uid.js.map +1 -0
- package/package.json +6 -6
- package/src/animation-loop/animation-loop.ts +27 -6
- package/src/animation-loop/make-animation-loop.ts +8 -3
- package/src/animation-loop/request-animation-frame.ts +4 -3
- package/src/application-utils/load-file.ts +2 -4
- package/src/async-texture/async-texture.ts +39 -7
- package/src/{transform → compute}/buffer-transform.ts +30 -14
- package/src/{computation.ts → compute/computation.ts} +14 -8
- package/src/compute/swap.ts +116 -0
- package/src/{transform → compute}/texture-transform.ts +9 -18
- package/src/debug/debug-framebuffer.ts +1 -1
- package/src/debug/debug-shader-layout.ts +1 -1
- package/src/factories/pipeline-factory.ts +222 -0
- package/src/{lib → factories}/shader-factory.ts +41 -5
- package/src/index.ts +35 -16
- package/src/model/model.ts +133 -78
- package/src/model/split-uniforms-and-bindings.ts +4 -4
- package/src/models/billboard-texture-model.ts +98 -0
- package/src/models/billboard-texture-module.ts +49 -0
- package/src/models/clip-space.ts +88 -0
- package/src/modules/picking/README.md +88 -0
- package/src/modules/picking/color-picking.ts +190 -0
- package/src/modules/picking/index-picking.ts +156 -0
- package/src/modules/picking/legacy-picking-manager.ts +99 -0
- package/src/modules/picking/picking-manager.ts +137 -0
- package/src/modules/picking/picking-uniforms.ts +179 -0
- package/src/passes/get-fragment-shader.ts +129 -0
- package/src/passes/shader-pass-renderer.ts +252 -0
- package/src/shader-inputs.ts +27 -48
- package/dist/computation.d.ts.map +0 -1
- package/dist/lib/clip-space.d.ts.map +0 -1
- package/dist/lib/clip-space.js +0 -46
- package/dist/lib/pipeline-factory.d.ts.map +0 -1
- package/dist/lib/pipeline-factory.js +0 -98
- package/dist/lib/shader-factory.d.ts.map +0 -1
- package/dist/transform/buffer-transform.d.ts +0 -35
- package/dist/transform/buffer-transform.d.ts.map +0 -1
- package/dist/transform/texture-transform.d.ts.map +0 -1
- package/src/lib/clip-space.ts +0 -53
- package/src/lib/pipeline-factory.ts +0 -126
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(dist_exports, {
|
|
|
28
28
|
AnimationLoop: () => AnimationLoop,
|
|
29
29
|
AnimationLoopTemplate: () => AnimationLoopTemplate,
|
|
30
30
|
AsyncTexture: () => AsyncTexture,
|
|
31
|
+
BackgroundTextureModel: () => BackgroundTextureModel,
|
|
31
32
|
BufferTransform: () => BufferTransform,
|
|
32
33
|
ClipSpace: () => ClipSpace,
|
|
33
34
|
Computation: () => Computation,
|
|
@@ -39,23 +40,31 @@ __export(dist_exports, {
|
|
|
39
40
|
GroupNode: () => GroupNode,
|
|
40
41
|
IcoSphereGeometry: () => IcoSphereGeometry,
|
|
41
42
|
KeyFrames: () => KeyFrames,
|
|
43
|
+
LegacyPickingManager: () => LegacyPickingManager,
|
|
42
44
|
Model: () => Model,
|
|
43
45
|
ModelNode: () => ModelNode,
|
|
46
|
+
PickingManager: () => PickingManager,
|
|
44
47
|
PipelineFactory: () => PipelineFactory,
|
|
45
48
|
PlaneGeometry: () => PlaneGeometry,
|
|
46
49
|
ScenegraphNode: () => ScenegraphNode,
|
|
47
50
|
ShaderFactory: () => ShaderFactory,
|
|
51
|
+
ShaderInputs: () => ShaderInputs,
|
|
52
|
+
ShaderPassRenderer: () => ShaderPassRenderer,
|
|
48
53
|
SphereGeometry: () => SphereGeometry,
|
|
54
|
+
Swap: () => Swap,
|
|
55
|
+
SwapBuffers: () => SwapBuffers,
|
|
56
|
+
SwapFramebuffers: () => SwapFramebuffers,
|
|
49
57
|
TextureTransform: () => TextureTransform,
|
|
50
58
|
Timeline: () => Timeline,
|
|
51
59
|
TruncatedConeGeometry: () => TruncatedConeGeometry,
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
cancelAnimationFramePolyfill: () => cancelAnimationFramePolyfill,
|
|
61
|
+
colorPicking: () => picking2,
|
|
62
|
+
indexPicking: () => picking,
|
|
54
63
|
loadImage: () => loadImage,
|
|
55
64
|
loadImageBitmap: () => loadImageBitmap,
|
|
56
65
|
makeAnimationLoop: () => makeAnimationLoop,
|
|
57
66
|
makeRandomGenerator: () => makeRandomGenerator,
|
|
58
|
-
|
|
67
|
+
requestAnimationFramePolyfill: () => requestAnimationFramePolyfill,
|
|
59
68
|
setPathPrefix: () => setPathPrefix
|
|
60
69
|
});
|
|
61
70
|
module.exports = __toCommonJS(dist_exports);
|
|
@@ -235,10 +244,10 @@ var AnimationLoopTemplate = class {
|
|
|
235
244
|
var import_core = require("@luma.gl/core");
|
|
236
245
|
|
|
237
246
|
// dist/animation-loop/request-animation-frame.js
|
|
238
|
-
function
|
|
247
|
+
function requestAnimationFramePolyfill(callback) {
|
|
239
248
|
return typeof window !== "undefined" && window.requestAnimationFrame ? window.requestAnimationFrame(callback) : setTimeout(callback, 1e3 / 60);
|
|
240
249
|
}
|
|
241
|
-
function
|
|
250
|
+
function cancelAnimationFramePolyfill(timerId) {
|
|
242
251
|
return typeof window !== "undefined" && window.cancelAnimationFrame ? window.cancelAnimationFrame(timerId) : clearTimeout(timerId);
|
|
243
252
|
}
|
|
244
253
|
|
|
@@ -281,6 +290,7 @@ var AnimationLoop = class {
|
|
|
281
290
|
_nextFramePromise = null;
|
|
282
291
|
_resolveNextFrame = null;
|
|
283
292
|
_cpuStartTime = 0;
|
|
293
|
+
_error = null;
|
|
284
294
|
// _gpuTimeQuery: Query | null = null;
|
|
285
295
|
/*
|
|
286
296
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
@@ -314,6 +324,22 @@ var AnimationLoop = class {
|
|
|
314
324
|
delete() {
|
|
315
325
|
this.destroy();
|
|
316
326
|
}
|
|
327
|
+
setError(error) {
|
|
328
|
+
var _a, _b;
|
|
329
|
+
this.props.onError(error);
|
|
330
|
+
this._error = Error();
|
|
331
|
+
const canvas2 = (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.canvas;
|
|
332
|
+
if (canvas2 instanceof HTMLCanvasElement) {
|
|
333
|
+
const errorDiv = document.createElement("h1");
|
|
334
|
+
errorDiv.innerHTML = error.message;
|
|
335
|
+
errorDiv.style.position = "absolute";
|
|
336
|
+
errorDiv.style.top = "20%";
|
|
337
|
+
errorDiv.style.left = "10px";
|
|
338
|
+
errorDiv.style.color = "black";
|
|
339
|
+
errorDiv.style.backgroundColor = "red";
|
|
340
|
+
document.body.appendChild(errorDiv);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
317
343
|
/** Flags this animation loop as needing redraw */
|
|
318
344
|
setNeedsRedraw(reason) {
|
|
319
345
|
this.needsRedraw = this.needsRedraw || reason;
|
|
@@ -363,7 +389,7 @@ var AnimationLoop = class {
|
|
|
363
389
|
/** Stops a render loop if already running, finalizing */
|
|
364
390
|
stop() {
|
|
365
391
|
if (this._running) {
|
|
366
|
-
if (this.animationProps) {
|
|
392
|
+
if (this.animationProps && !this._error) {
|
|
367
393
|
this.props.onFinalize(this.animationProps);
|
|
368
394
|
}
|
|
369
395
|
this._cancelAnimationFrame();
|
|
@@ -376,7 +402,7 @@ var AnimationLoop = class {
|
|
|
376
402
|
/** Explicitly draw a frame */
|
|
377
403
|
redraw() {
|
|
378
404
|
var _a;
|
|
379
|
-
if ((_a = this.device) == null ? void 0 : _a.isLost) {
|
|
405
|
+
if (((_a = this.device) == null ? void 0 : _a.isLost) || this._error) {
|
|
380
406
|
return this;
|
|
381
407
|
}
|
|
382
408
|
this._beginFrameTimers();
|
|
@@ -442,13 +468,13 @@ var AnimationLoop = class {
|
|
|
442
468
|
if (!this._running) {
|
|
443
469
|
return;
|
|
444
470
|
}
|
|
445
|
-
this._animationFrameId =
|
|
471
|
+
this._animationFrameId = requestAnimationFramePolyfill(this._animationFrame.bind(this));
|
|
446
472
|
}
|
|
447
473
|
_cancelAnimationFrame() {
|
|
448
474
|
if (this._animationFrameId === null) {
|
|
449
475
|
return;
|
|
450
476
|
}
|
|
451
|
-
|
|
477
|
+
cancelAnimationFramePolyfill(this._animationFrameId);
|
|
452
478
|
this._animationFrameId = null;
|
|
453
479
|
}
|
|
454
480
|
_animationFrame() {
|
|
@@ -633,7 +659,7 @@ var AnimationLoop = class {
|
|
|
633
659
|
var import_core2 = require("@luma.gl/core");
|
|
634
660
|
function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
|
|
635
661
|
let renderLoop = null;
|
|
636
|
-
const device = (props == null ? void 0 : props.device) || import_core2.luma.createDevice({ id: "animation-loop" });
|
|
662
|
+
const device = (props == null ? void 0 : props.device) || import_core2.luma.createDevice({ id: "animation-loop", adapters: props == null ? void 0 : props.adapters, createCanvasContext: true });
|
|
637
663
|
const animationLoop = new AnimationLoop({
|
|
638
664
|
...props,
|
|
639
665
|
device,
|
|
@@ -652,9 +678,6 @@ function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
|
|
|
652
678
|
|
|
653
679
|
// dist/model/model.js
|
|
654
680
|
var import_core7 = require("@luma.gl/core");
|
|
655
|
-
var import_core8 = require("@luma.gl/core");
|
|
656
|
-
var import_core9 = require("@luma.gl/core");
|
|
657
|
-
var import_core10 = require("@luma.gl/core");
|
|
658
681
|
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
659
682
|
|
|
660
683
|
// dist/geometry/gpu-geometry.js
|
|
@@ -765,7 +788,7 @@ function getAttributeBuffersFromGeometry(device, geometry) {
|
|
|
765
788
|
return { attributes, bufferLayout, vertexCount };
|
|
766
789
|
}
|
|
767
790
|
|
|
768
|
-
// dist/
|
|
791
|
+
// dist/factories/pipeline-factory.js
|
|
769
792
|
var import_core4 = require("@luma.gl/core");
|
|
770
793
|
var _PipelineFactory = class {
|
|
771
794
|
/** Get the singleton default pipeline factory for the specified device */
|
|
@@ -774,59 +797,136 @@ var _PipelineFactory = class {
|
|
|
774
797
|
return device._lumaData.defaultPipelineFactory;
|
|
775
798
|
}
|
|
776
799
|
device;
|
|
800
|
+
cachingEnabled;
|
|
777
801
|
destroyPolicy;
|
|
802
|
+
debug;
|
|
778
803
|
_hashCounter = 0;
|
|
779
804
|
_hashes = {};
|
|
780
805
|
_renderPipelineCache = {};
|
|
781
806
|
_computePipelineCache = {};
|
|
807
|
+
get [Symbol.toStringTag]() {
|
|
808
|
+
return "PipelineFactory";
|
|
809
|
+
}
|
|
810
|
+
toString() {
|
|
811
|
+
return `PipelineFactory(${this.device.id})`;
|
|
812
|
+
}
|
|
782
813
|
constructor(device) {
|
|
783
814
|
this.device = device;
|
|
784
|
-
this.
|
|
815
|
+
this.cachingEnabled = device.props._cachePipelines;
|
|
816
|
+
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
817
|
+
this.debug = device.props.debugFactories;
|
|
785
818
|
}
|
|
786
|
-
/** Return a RenderPipeline matching props. Reuses
|
|
819
|
+
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
787
820
|
createRenderPipeline(props) {
|
|
821
|
+
var _a;
|
|
822
|
+
if (!this.cachingEnabled) {
|
|
823
|
+
return this.device.createRenderPipeline(props);
|
|
824
|
+
}
|
|
788
825
|
const allProps = { ...import_core4.RenderPipeline.defaultProps, ...props };
|
|
826
|
+
const cache = this._renderPipelineCache;
|
|
789
827
|
const hash = this._hashRenderPipeline(allProps);
|
|
790
|
-
|
|
791
|
-
|
|
828
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.pipeline;
|
|
829
|
+
if (!pipeline) {
|
|
830
|
+
pipeline = this.device.createRenderPipeline({
|
|
792
831
|
...allProps,
|
|
793
|
-
id: allProps.id ? `${allProps.id}-cached` :
|
|
832
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached")
|
|
794
833
|
});
|
|
795
834
|
pipeline.hash = hash;
|
|
796
|
-
|
|
835
|
+
cache[hash] = { pipeline, useCount: 1 };
|
|
836
|
+
if (this.debug) {
|
|
837
|
+
import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
838
|
+
}
|
|
839
|
+
} else {
|
|
840
|
+
cache[hash].useCount++;
|
|
841
|
+
if (this.debug) {
|
|
842
|
+
import_core4.log.warn(`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
843
|
+
}
|
|
797
844
|
}
|
|
798
|
-
|
|
799
|
-
return this._renderPipelineCache[hash].pipeline;
|
|
845
|
+
return pipeline;
|
|
800
846
|
}
|
|
847
|
+
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
801
848
|
createComputePipeline(props) {
|
|
849
|
+
var _a;
|
|
850
|
+
if (!this.cachingEnabled) {
|
|
851
|
+
return this.device.createComputePipeline(props);
|
|
852
|
+
}
|
|
802
853
|
const allProps = { ...import_core4.ComputePipeline.defaultProps, ...props };
|
|
854
|
+
const cache = this._computePipelineCache;
|
|
803
855
|
const hash = this._hashComputePipeline(allProps);
|
|
804
|
-
|
|
805
|
-
|
|
856
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.pipeline;
|
|
857
|
+
if (!pipeline) {
|
|
858
|
+
pipeline = this.device.createComputePipeline({
|
|
806
859
|
...allProps,
|
|
807
860
|
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
808
861
|
});
|
|
809
862
|
pipeline.hash = hash;
|
|
810
|
-
|
|
863
|
+
cache[hash] = { pipeline, useCount: 1 };
|
|
864
|
+
if (this.debug) {
|
|
865
|
+
import_core4.log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
cache[hash].useCount++;
|
|
869
|
+
if (this.debug) {
|
|
870
|
+
import_core4.log.warn(`${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
871
|
+
}
|
|
811
872
|
}
|
|
812
|
-
|
|
813
|
-
return this._computePipelineCache[hash].pipeline;
|
|
873
|
+
return pipeline;
|
|
814
874
|
}
|
|
815
875
|
release(pipeline) {
|
|
876
|
+
if (!this.cachingEnabled) {
|
|
877
|
+
pipeline.destroy();
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const cache = this._getCache(pipeline);
|
|
816
881
|
const hash = pipeline.hash;
|
|
817
|
-
const cache = pipeline instanceof import_core4.ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
|
|
818
882
|
cache[hash].useCount--;
|
|
819
883
|
if (cache[hash].useCount === 0) {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
884
|
+
this._destroyPipeline(pipeline);
|
|
885
|
+
if (this.debug) {
|
|
886
|
+
import_core4.log.warn(`${this}: ${pipeline} released and destroyed`)();
|
|
823
887
|
}
|
|
888
|
+
} else if (cache[hash].useCount < 0) {
|
|
889
|
+
import_core4.log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
890
|
+
cache[hash].useCount = 0;
|
|
891
|
+
} else if (this.debug) {
|
|
892
|
+
import_core4.log.warn(`${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
824
893
|
}
|
|
825
894
|
}
|
|
826
895
|
// PRIVATE
|
|
896
|
+
/** Destroy a cached pipeline, removing it from the cache (depending on destroy policy) */
|
|
897
|
+
_destroyPipeline(pipeline) {
|
|
898
|
+
const cache = this._getCache(pipeline);
|
|
899
|
+
switch (this.destroyPolicy) {
|
|
900
|
+
case "never":
|
|
901
|
+
return false;
|
|
902
|
+
case "unused":
|
|
903
|
+
delete cache[pipeline.hash];
|
|
904
|
+
pipeline.destroy();
|
|
905
|
+
return true;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
/** Get the appropriate cache for the type of pipeline */
|
|
909
|
+
_getCache(pipeline) {
|
|
910
|
+
let cache;
|
|
911
|
+
if (pipeline instanceof import_core4.ComputePipeline) {
|
|
912
|
+
cache = this._computePipelineCache;
|
|
913
|
+
}
|
|
914
|
+
if (pipeline instanceof import_core4.RenderPipeline) {
|
|
915
|
+
cache = this._renderPipelineCache;
|
|
916
|
+
}
|
|
917
|
+
if (!cache) {
|
|
918
|
+
throw new Error(`${this}`);
|
|
919
|
+
}
|
|
920
|
+
if (!cache[pipeline.hash]) {
|
|
921
|
+
throw new Error(`${this}: ${pipeline} matched incorrect entry`);
|
|
922
|
+
}
|
|
923
|
+
return cache;
|
|
924
|
+
}
|
|
925
|
+
/** Calculate a hash based on all the inputs for a compute pipeline */
|
|
827
926
|
_hashComputePipeline(props) {
|
|
927
|
+
const { type } = this.device;
|
|
828
928
|
const shaderHash = this._getHash(props.shader.source);
|
|
829
|
-
return `${shaderHash}`;
|
|
929
|
+
return `${type}/C/${shaderHash}`;
|
|
830
930
|
}
|
|
831
931
|
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
832
932
|
_hashRenderPipeline(props) {
|
|
@@ -834,12 +934,14 @@ var _PipelineFactory = class {
|
|
|
834
934
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
835
935
|
const varyingHash = "-";
|
|
836
936
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
837
|
-
|
|
937
|
+
const { type } = this.device;
|
|
938
|
+
switch (type) {
|
|
838
939
|
case "webgl":
|
|
839
|
-
return `${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
|
|
940
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
|
|
941
|
+
case "webgpu":
|
|
840
942
|
default:
|
|
841
943
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
842
|
-
return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
944
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
843
945
|
}
|
|
844
946
|
}
|
|
845
947
|
_getHash(key) {
|
|
@@ -852,7 +954,7 @@ var _PipelineFactory = class {
|
|
|
852
954
|
var PipelineFactory = _PipelineFactory;
|
|
853
955
|
__publicField(PipelineFactory, "defaultProps", { ...import_core4.RenderPipeline.defaultProps });
|
|
854
956
|
|
|
855
|
-
// dist/
|
|
957
|
+
// dist/factories/shader-factory.js
|
|
856
958
|
var import_core5 = require("@luma.gl/core");
|
|
857
959
|
var _ShaderFactory = class {
|
|
858
960
|
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
@@ -861,15 +963,28 @@ var _ShaderFactory = class {
|
|
|
861
963
|
return device._lumaData.defaultShaderFactory;
|
|
862
964
|
}
|
|
863
965
|
device;
|
|
966
|
+
cachingEnabled;
|
|
864
967
|
destroyPolicy;
|
|
968
|
+
debug;
|
|
865
969
|
_cache = {};
|
|
970
|
+
get [Symbol.toStringTag]() {
|
|
971
|
+
return "ShaderFactory";
|
|
972
|
+
}
|
|
973
|
+
toString() {
|
|
974
|
+
return `${this[Symbol.toStringTag]}(${this.device.id})`;
|
|
975
|
+
}
|
|
866
976
|
/** @internal */
|
|
867
977
|
constructor(device) {
|
|
868
978
|
this.device = device;
|
|
869
|
-
this.
|
|
979
|
+
this.cachingEnabled = device.props._cacheShaders;
|
|
980
|
+
this.destroyPolicy = device.props._cacheDestroyPolicy;
|
|
981
|
+
this.debug = true;
|
|
870
982
|
}
|
|
871
983
|
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
872
984
|
createShader(props) {
|
|
985
|
+
if (!this.cachingEnabled) {
|
|
986
|
+
return this.device.createShader(props);
|
|
987
|
+
}
|
|
873
988
|
const key = this._hashShader(props);
|
|
874
989
|
let cacheEntry = this._cache[key];
|
|
875
990
|
if (!cacheEntry) {
|
|
@@ -877,13 +992,24 @@ var _ShaderFactory = class {
|
|
|
877
992
|
...props,
|
|
878
993
|
id: props.id ? `${props.id}-cached` : void 0
|
|
879
994
|
});
|
|
880
|
-
this._cache[key] = cacheEntry = { shader, useCount:
|
|
995
|
+
this._cache[key] = cacheEntry = { shader, useCount: 1 };
|
|
996
|
+
if (this.debug) {
|
|
997
|
+
import_core5.log.warn(`${this}: Created new shader ${shader.id}`)();
|
|
998
|
+
}
|
|
999
|
+
} else {
|
|
1000
|
+
cacheEntry.useCount++;
|
|
1001
|
+
if (this.debug) {
|
|
1002
|
+
import_core5.log.warn(`${this}: Reusing shader ${cacheEntry.shader.id} count=${cacheEntry.useCount}`)();
|
|
1003
|
+
}
|
|
881
1004
|
}
|
|
882
|
-
cacheEntry.useCount++;
|
|
883
1005
|
return cacheEntry.shader;
|
|
884
1006
|
}
|
|
885
1007
|
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
886
1008
|
release(shader) {
|
|
1009
|
+
if (!this.cachingEnabled) {
|
|
1010
|
+
shader.destroy();
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
887
1013
|
const key = this._hashShader(shader);
|
|
888
1014
|
const cacheEntry = this._cache[key];
|
|
889
1015
|
if (cacheEntry) {
|
|
@@ -892,7 +1018,14 @@ var _ShaderFactory = class {
|
|
|
892
1018
|
if (this.destroyPolicy === "unused") {
|
|
893
1019
|
delete this._cache[key];
|
|
894
1020
|
cacheEntry.shader.destroy();
|
|
1021
|
+
if (this.debug) {
|
|
1022
|
+
import_core5.log.warn(`${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
1023
|
+
}
|
|
895
1024
|
}
|
|
1025
|
+
} else if (cacheEntry.useCount < 0) {
|
|
1026
|
+
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
1027
|
+
} else if (this.debug) {
|
|
1028
|
+
import_core5.log.warn(`${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
896
1029
|
}
|
|
897
1030
|
}
|
|
898
1031
|
}
|
|
@@ -920,7 +1053,7 @@ function getDebugTableForShaderLayout(layout, name) {
|
|
|
920
1053
|
}
|
|
921
1054
|
for (const varyingDeclaration of layout.varyings || []) {
|
|
922
1055
|
const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`;
|
|
923
|
-
table[`out ${glslDeclaration}`] = { [header]: JSON.stringify(varyingDeclaration
|
|
1056
|
+
table[`out ${glslDeclaration}`] = { [header]: JSON.stringify(varyingDeclaration) };
|
|
924
1057
|
}
|
|
925
1058
|
return table;
|
|
926
1059
|
}
|
|
@@ -937,7 +1070,7 @@ function debugFramebuffer(fbo, { id, minimap, opaque, top = "0", left = "0", rgb
|
|
|
937
1070
|
canvas.style.position = "absolute";
|
|
938
1071
|
canvas.style.top = top;
|
|
939
1072
|
canvas.style.left = left;
|
|
940
|
-
canvas.style.border = "blue
|
|
1073
|
+
canvas.style.border = "blue 5px solid";
|
|
941
1074
|
canvas.style.transform = "scaleY(-1)";
|
|
942
1075
|
document.body.appendChild(canvas);
|
|
943
1076
|
ctx = canvas.getContext("2d");
|
|
@@ -1003,10 +1136,14 @@ function deepEqual(a, b, depth) {
|
|
|
1003
1136
|
return false;
|
|
1004
1137
|
}
|
|
1005
1138
|
|
|
1139
|
+
// dist/shader-inputs.js
|
|
1140
|
+
var import_core6 = require("@luma.gl/core");
|
|
1141
|
+
var import_shadertools = require("@luma.gl/shadertools");
|
|
1142
|
+
|
|
1006
1143
|
// dist/model/split-uniforms-and-bindings.js
|
|
1007
1144
|
var import_types = require("@math.gl/types");
|
|
1008
1145
|
function isUniformValue(value) {
|
|
1009
|
-
return (0, import_types.isNumericArray)(value)
|
|
1146
|
+
return (0, import_types.isNumericArray)(value) || typeof value === "number" || typeof value === "boolean";
|
|
1010
1147
|
}
|
|
1011
1148
|
function splitUniformsAndBindings(uniforms) {
|
|
1012
1149
|
const result = { bindings: {}, uniforms: {} };
|
|
@@ -1022,8 +1159,6 @@ function splitUniformsAndBindings(uniforms) {
|
|
|
1022
1159
|
}
|
|
1023
1160
|
|
|
1024
1161
|
// dist/shader-inputs.js
|
|
1025
|
-
var import_core6 = require("@luma.gl/core");
|
|
1026
|
-
var import_shadertools = require("@luma.gl/shadertools");
|
|
1027
1162
|
var ShaderInputs = class {
|
|
1028
1163
|
/**
|
|
1029
1164
|
* The map of modules
|
|
@@ -1052,9 +1187,10 @@ var ShaderInputs = class {
|
|
|
1052
1187
|
this.moduleUniforms = {};
|
|
1053
1188
|
this.moduleBindings = {};
|
|
1054
1189
|
for (const [name, module2] of Object.entries(modules)) {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1190
|
+
this._addModule(module2);
|
|
1191
|
+
if (module2.name && name !== module2.name) {
|
|
1192
|
+
import_core6.log.warn(`Module name: ${name} vs ${module2.name}`)();
|
|
1193
|
+
}
|
|
1058
1194
|
}
|
|
1059
1195
|
}
|
|
1060
1196
|
/** Destroy */
|
|
@@ -1075,17 +1211,12 @@ var ShaderInputs = class {
|
|
|
1075
1211
|
}
|
|
1076
1212
|
const oldUniforms = this.moduleUniforms[moduleName];
|
|
1077
1213
|
const oldBindings = this.moduleBindings[moduleName];
|
|
1078
|
-
|
|
1079
|
-
uniformsAndBindings ||= { ...this.moduleUniforms[moduleName], ...moduleProps };
|
|
1214
|
+
const uniformsAndBindings = ((_a = module2.getUniforms) == null ? void 0 : _a.call(module2, moduleProps, oldUniforms)) || moduleProps;
|
|
1080
1215
|
const { uniforms, bindings } = splitUniformsAndBindings(uniformsAndBindings);
|
|
1081
1216
|
this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms };
|
|
1082
1217
|
this.moduleBindings[moduleName] = { ...oldBindings, ...bindings };
|
|
1083
1218
|
}
|
|
1084
1219
|
}
|
|
1085
|
-
/** Merges all bindings for the shader (from the various modules) */
|
|
1086
|
-
// getUniformBlocks(): Record<string, Texture | Sampler> {
|
|
1087
|
-
// return this.moduleUniforms;
|
|
1088
|
-
// }
|
|
1089
1220
|
/**
|
|
1090
1221
|
* Return the map of modules
|
|
1091
1222
|
* @todo should should this include the resolved dependencies?
|
|
@@ -1098,13 +1229,15 @@ var ShaderInputs = class {
|
|
|
1098
1229
|
return this.moduleUniforms;
|
|
1099
1230
|
}
|
|
1100
1231
|
/** Merges all bindings for the shader (from the various modules) */
|
|
1101
|
-
|
|
1232
|
+
getBindingValues() {
|
|
1102
1233
|
const bindings = {};
|
|
1103
1234
|
for (const moduleBindings of Object.values(this.moduleBindings)) {
|
|
1104
1235
|
Object.assign(bindings, moduleBindings);
|
|
1105
1236
|
}
|
|
1106
1237
|
return bindings;
|
|
1107
1238
|
}
|
|
1239
|
+
// INTERNAL
|
|
1240
|
+
/** Return a debug table that can be used for console.table() or log.table() */
|
|
1108
1241
|
getDebugTable() {
|
|
1109
1242
|
var _a;
|
|
1110
1243
|
const table = {};
|
|
@@ -1118,6 +1251,11 @@ var ShaderInputs = class {
|
|
|
1118
1251
|
}
|
|
1119
1252
|
return table;
|
|
1120
1253
|
}
|
|
1254
|
+
_addModule(module2) {
|
|
1255
|
+
const moduleName = module2.name;
|
|
1256
|
+
this.moduleUniforms[moduleName] = module2.defaultUniforms || {};
|
|
1257
|
+
this.moduleBindings[moduleName] = {};
|
|
1258
|
+
}
|
|
1121
1259
|
};
|
|
1122
1260
|
|
|
1123
1261
|
// dist/application-utils/load-file.js
|
|
@@ -1130,7 +1268,7 @@ async function loadImageBitmap(url, opts) {
|
|
|
1130
1268
|
image.crossOrigin = (opts == null ? void 0 : opts.crossOrigin) || "anonymous";
|
|
1131
1269
|
image.src = url.startsWith("http") ? url : pathPrefix + url;
|
|
1132
1270
|
await image.decode();
|
|
1133
|
-
return await createImageBitmap(image);
|
|
1271
|
+
return opts ? await createImageBitmap(image, opts) : await createImageBitmap(image);
|
|
1134
1272
|
}
|
|
1135
1273
|
async function loadImage(url, opts) {
|
|
1136
1274
|
return await new Promise((resolve, reject) => {
|
|
@@ -1149,6 +1287,7 @@ async function loadImage(url, opts) {
|
|
|
1149
1287
|
// dist/async-texture/async-texture.js
|
|
1150
1288
|
var AsyncTexture = class {
|
|
1151
1289
|
device;
|
|
1290
|
+
id;
|
|
1152
1291
|
// TODO - should we type these as possibly `null`? It will make usage harder?
|
|
1153
1292
|
// @ts-expect-error
|
|
1154
1293
|
texture;
|
|
@@ -1163,8 +1302,15 @@ var AsyncTexture = class {
|
|
|
1163
1302
|
};
|
|
1164
1303
|
rejectReady = () => {
|
|
1165
1304
|
};
|
|
1305
|
+
get [Symbol.toStringTag]() {
|
|
1306
|
+
return "AsyncTexture";
|
|
1307
|
+
}
|
|
1308
|
+
toString() {
|
|
1309
|
+
return `AsyncTexture:"${this.id}"(${this.isReady ? "ready" : "loading"})`;
|
|
1310
|
+
}
|
|
1166
1311
|
constructor(device, props) {
|
|
1167
1312
|
this.device = device;
|
|
1313
|
+
this.id = props.id || uid("async-texture");
|
|
1168
1314
|
if (typeof (props == null ? void 0 : props.data) === "string" && props.dimension === "2d") {
|
|
1169
1315
|
props = { ...props, data: loadImageBitmap(props.data) };
|
|
1170
1316
|
}
|
|
@@ -1198,6 +1344,26 @@ var AsyncTexture = class {
|
|
|
1198
1344
|
}
|
|
1199
1345
|
this.destroyed = true;
|
|
1200
1346
|
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Textures are immutable and cannot be resized after creation,
|
|
1349
|
+
* but we can create a similar texture with the same parameters but a new size.
|
|
1350
|
+
* @note Does not copy contents of the texture
|
|
1351
|
+
* @todo Abort pending promise and create a texture with the new size?
|
|
1352
|
+
*/
|
|
1353
|
+
resize(size) {
|
|
1354
|
+
if (!this.isReady) {
|
|
1355
|
+
throw new Error("Cannot resize texture before it is ready");
|
|
1356
|
+
}
|
|
1357
|
+
if (size.width === this.texture.width && size.height === this.texture.height) {
|
|
1358
|
+
return false;
|
|
1359
|
+
}
|
|
1360
|
+
if (this.texture) {
|
|
1361
|
+
const texture = this.texture;
|
|
1362
|
+
this.texture = texture.clone(size);
|
|
1363
|
+
texture.destroy();
|
|
1364
|
+
}
|
|
1365
|
+
return true;
|
|
1366
|
+
}
|
|
1201
1367
|
};
|
|
1202
1368
|
async function awaitAllPromises(x) {
|
|
1203
1369
|
x = await x;
|
|
@@ -1280,6 +1446,12 @@ var _Model = class {
|
|
|
1280
1446
|
_destroyed = false;
|
|
1281
1447
|
/** "Time" of last draw. Monotonically increasing timestamp */
|
|
1282
1448
|
_lastDrawTimestamp = -1;
|
|
1449
|
+
get [Symbol.toStringTag]() {
|
|
1450
|
+
return "Model";
|
|
1451
|
+
}
|
|
1452
|
+
toString() {
|
|
1453
|
+
return `Model(${this.id})`;
|
|
1454
|
+
}
|
|
1283
1455
|
constructor(device, props) {
|
|
1284
1456
|
var _a, _b, _c;
|
|
1285
1457
|
this.props = { ..._Model.defaultProps, ...props };
|
|
@@ -1297,22 +1469,22 @@ var _Model = class {
|
|
|
1297
1469
|
const isWebGPU = this.device.type === "webgpu";
|
|
1298
1470
|
if (isWebGPU && this.props.source) {
|
|
1299
1471
|
this.props.shaderLayout ||= (0, import_shadertools2.getShaderLayoutFromWGSL)(this.props.source);
|
|
1300
|
-
const { source, getUniforms } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1472
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1301
1473
|
platformInfo,
|
|
1302
1474
|
...this.props,
|
|
1303
1475
|
modules
|
|
1304
1476
|
});
|
|
1305
|
-
this.source =
|
|
1306
|
-
this._getModuleUniforms =
|
|
1477
|
+
this.source = source3;
|
|
1478
|
+
this._getModuleUniforms = getUniforms2;
|
|
1307
1479
|
} else {
|
|
1308
|
-
const { vs, fs, getUniforms } = this.props.shaderAssembler.assembleGLSLShaderPair({
|
|
1480
|
+
const { vs: vs3, fs: fs3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleGLSLShaderPair({
|
|
1309
1481
|
platformInfo,
|
|
1310
1482
|
...this.props,
|
|
1311
1483
|
modules
|
|
1312
1484
|
});
|
|
1313
|
-
this.vs =
|
|
1314
|
-
this.fs =
|
|
1315
|
-
this._getModuleUniforms =
|
|
1485
|
+
this.vs = vs3;
|
|
1486
|
+
this.fs = fs3;
|
|
1487
|
+
this._getModuleUniforms = getUniforms2;
|
|
1316
1488
|
}
|
|
1317
1489
|
this.vertexCount = this.props.vertexCount;
|
|
1318
1490
|
this.instanceCount = this.props.instanceCount;
|
|
@@ -1326,7 +1498,8 @@ var _Model = class {
|
|
|
1326
1498
|
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1327
1499
|
this.pipeline = this._updatePipeline();
|
|
1328
1500
|
this.vertexArray = device.createVertexArray({
|
|
1329
|
-
|
|
1501
|
+
shaderLayout: this.pipeline.shaderLayout,
|
|
1502
|
+
bufferLayout: this.pipeline.bufferLayout
|
|
1330
1503
|
});
|
|
1331
1504
|
if (this._gpuGeometry) {
|
|
1332
1505
|
this._setGeometryAttributes(this._gpuGeometry);
|
|
@@ -1353,10 +1526,10 @@ var _Model = class {
|
|
|
1353
1526
|
this.setBindings(props.bindings);
|
|
1354
1527
|
}
|
|
1355
1528
|
if (props.uniforms) {
|
|
1356
|
-
this.
|
|
1529
|
+
this.setUniformsWebGL(props.uniforms);
|
|
1357
1530
|
}
|
|
1358
1531
|
if (props.moduleSettings) {
|
|
1359
|
-
this.
|
|
1532
|
+
this.updateModuleSettingsWebGL(props.moduleSettings);
|
|
1360
1533
|
}
|
|
1361
1534
|
if (props.transformFeedback) {
|
|
1362
1535
|
this.transformFeedback = props.transformFeedback;
|
|
@@ -1365,16 +1538,16 @@ var _Model = class {
|
|
|
1365
1538
|
}
|
|
1366
1539
|
destroy() {
|
|
1367
1540
|
var _a;
|
|
1368
|
-
if (this._destroyed)
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1541
|
+
if (!this._destroyed) {
|
|
1542
|
+
this.pipelineFactory.release(this.pipeline);
|
|
1543
|
+
this.shaderFactory.release(this.pipeline.vs);
|
|
1544
|
+
if (this.pipeline.fs) {
|
|
1545
|
+
this.shaderFactory.release(this.pipeline.fs);
|
|
1546
|
+
}
|
|
1547
|
+
this._uniformStore.destroy();
|
|
1548
|
+
(_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
|
|
1549
|
+
this._destroyed = true;
|
|
1374
1550
|
}
|
|
1375
|
-
this._uniformStore.destroy();
|
|
1376
|
-
(_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
|
|
1377
|
-
this._destroyed = true;
|
|
1378
1551
|
}
|
|
1379
1552
|
// Draw call
|
|
1380
1553
|
/** Query redraw status. Clears the status. */
|
|
@@ -1395,9 +1568,20 @@ var _Model = class {
|
|
|
1395
1568
|
this.pipeline = this._updatePipeline();
|
|
1396
1569
|
}
|
|
1397
1570
|
draw(renderPass) {
|
|
1398
|
-
this.
|
|
1571
|
+
const loadingBinding = this._areBindingsLoading();
|
|
1572
|
+
if (loadingBinding) {
|
|
1573
|
+
import_core7.log.info(LOG_DRAW_PRIORITY, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
try {
|
|
1577
|
+
renderPass.pushDebugGroup(`${this}.predraw(${renderPass})`);
|
|
1578
|
+
this.predraw();
|
|
1579
|
+
} finally {
|
|
1580
|
+
renderPass.popDebugGroup();
|
|
1581
|
+
}
|
|
1399
1582
|
let drawSuccess;
|
|
1400
1583
|
try {
|
|
1584
|
+
renderPass.pushDebugGroup(`${this}.draw(${renderPass})`);
|
|
1401
1585
|
this._logDrawCallStart();
|
|
1402
1586
|
this.pipeline = this._updatePipeline();
|
|
1403
1587
|
const syncBindings = this._getBindings();
|
|
@@ -1424,6 +1608,7 @@ var _Model = class {
|
|
|
1424
1608
|
topology: this.topology
|
|
1425
1609
|
});
|
|
1426
1610
|
} finally {
|
|
1611
|
+
renderPass.popDebugGroup();
|
|
1427
1612
|
this._logDrawCallEnd();
|
|
1428
1613
|
}
|
|
1429
1614
|
this._logFramebuffer(renderPass);
|
|
@@ -1447,7 +1632,8 @@ var _Model = class {
|
|
|
1447
1632
|
const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
|
|
1448
1633
|
if (gpuGeometry) {
|
|
1449
1634
|
this.setTopology(gpuGeometry.topology || "triangle-list");
|
|
1450
|
-
|
|
1635
|
+
const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
|
|
1636
|
+
this.bufferLayout = bufferLayoutHelper.mergeBufferLayouts(gpuGeometry.bufferLayout, this.bufferLayout);
|
|
1451
1637
|
if (this.vertexArray) {
|
|
1452
1638
|
this._setGeometryAttributes(gpuGeometry);
|
|
1453
1639
|
}
|
|
@@ -1469,11 +1655,13 @@ var _Model = class {
|
|
|
1469
1655
|
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
1470
1656
|
*/
|
|
1471
1657
|
setBufferLayout(bufferLayout) {
|
|
1472
|
-
|
|
1658
|
+
const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
|
|
1659
|
+
this.bufferLayout = this._gpuGeometry ? bufferLayoutHelper.mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout;
|
|
1473
1660
|
this._setPipelineNeedsUpdate("bufferLayout");
|
|
1474
1661
|
this.pipeline = this._updatePipeline();
|
|
1475
1662
|
this.vertexArray = this.device.createVertexArray({
|
|
1476
|
-
|
|
1663
|
+
shaderLayout: this.pipeline.shaderLayout,
|
|
1664
|
+
bufferLayout: this.pipeline.bufferLayout
|
|
1477
1665
|
});
|
|
1478
1666
|
if (this._gpuGeometry) {
|
|
1479
1667
|
this._setGeometryAttributes(this._gpuGeometry);
|
|
@@ -1513,17 +1701,19 @@ var _Model = class {
|
|
|
1513
1701
|
/** Set the shader inputs */
|
|
1514
1702
|
setShaderInputs(shaderInputs) {
|
|
1515
1703
|
this.shaderInputs = shaderInputs;
|
|
1516
|
-
this._uniformStore = new
|
|
1517
|
-
for (const moduleName of Object.
|
|
1518
|
-
|
|
1519
|
-
|
|
1704
|
+
this._uniformStore = new import_core7.UniformStore(this.shaderInputs.modules);
|
|
1705
|
+
for (const [moduleName, module2] of Object.entries(this.shaderInputs.modules)) {
|
|
1706
|
+
if (shaderModuleHasUniforms(module2)) {
|
|
1707
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1708
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1709
|
+
}
|
|
1520
1710
|
}
|
|
1521
1711
|
this.setNeedsRedraw("shaderInputs");
|
|
1522
1712
|
}
|
|
1523
1713
|
/** Update uniform buffers from the model's shader inputs */
|
|
1524
1714
|
updateShaderInputs() {
|
|
1525
1715
|
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1526
|
-
this.setBindings(this.shaderInputs.
|
|
1716
|
+
this.setBindings(this.shaderInputs.getBindingValues());
|
|
1527
1717
|
this.setNeedsRedraw("shaderInputs");
|
|
1528
1718
|
}
|
|
1529
1719
|
/**
|
|
@@ -1553,16 +1743,20 @@ var _Model = class {
|
|
|
1553
1743
|
* @note Overrides any attributes previously set with the same name
|
|
1554
1744
|
*/
|
|
1555
1745
|
setAttributes(buffers, options) {
|
|
1746
|
+
const disableWarnings = (options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings;
|
|
1556
1747
|
if (buffers.indices) {
|
|
1557
|
-
|
|
1748
|
+
import_core7.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
|
|
1558
1749
|
}
|
|
1750
|
+
const bufferLayoutHelper = new import_core7._BufferLayoutHelper(this.bufferLayout);
|
|
1559
1751
|
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
1560
|
-
const bufferLayout =
|
|
1752
|
+
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
1561
1753
|
if (!bufferLayout) {
|
|
1562
|
-
|
|
1754
|
+
if (!disableWarnings) {
|
|
1755
|
+
import_core7.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
1756
|
+
}
|
|
1563
1757
|
continue;
|
|
1564
1758
|
}
|
|
1565
|
-
const attributeNames =
|
|
1759
|
+
const attributeNames = bufferLayoutHelper.getAttributeNamesForBuffer(bufferLayout);
|
|
1566
1760
|
let set = false;
|
|
1567
1761
|
for (const attributeName of attributeNames) {
|
|
1568
1762
|
const attributeInfo = this._attributeInfos[attributeName];
|
|
@@ -1571,8 +1765,8 @@ var _Model = class {
|
|
|
1571
1765
|
set = true;
|
|
1572
1766
|
}
|
|
1573
1767
|
}
|
|
1574
|
-
if (!set && !
|
|
1575
|
-
|
|
1768
|
+
if (!set && !disableWarnings) {
|
|
1769
|
+
import_core7.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
|
|
1576
1770
|
}
|
|
1577
1771
|
}
|
|
1578
1772
|
this.setNeedsRedraw("attributes");
|
|
@@ -1591,7 +1785,7 @@ var _Model = class {
|
|
|
1591
1785
|
if (attributeInfo) {
|
|
1592
1786
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
1593
1787
|
} else if (!((options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings)) {
|
|
1594
|
-
|
|
1788
|
+
import_core7.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
|
|
1595
1789
|
}
|
|
1596
1790
|
}
|
|
1597
1791
|
this.setNeedsRedraw("constants");
|
|
@@ -1602,7 +1796,7 @@ var _Model = class {
|
|
|
1602
1796
|
* @deprecated WebGL only, use uniform buffers for portability
|
|
1603
1797
|
* @param uniforms
|
|
1604
1798
|
*/
|
|
1605
|
-
|
|
1799
|
+
setUniformsWebGL(uniforms) {
|
|
1606
1800
|
if (!isObjectEmpty(uniforms)) {
|
|
1607
1801
|
this.pipeline.setUniformsWebGL(uniforms);
|
|
1608
1802
|
Object.assign(this.uniforms, uniforms);
|
|
@@ -1612,25 +1806,35 @@ var _Model = class {
|
|
|
1612
1806
|
/**
|
|
1613
1807
|
* @deprecated Updates shader module settings (which results in uniforms being set)
|
|
1614
1808
|
*/
|
|
1615
|
-
|
|
1809
|
+
updateModuleSettingsWebGL(props) {
|
|
1616
1810
|
const { bindings, uniforms } = splitUniformsAndBindings(this._getModuleUniforms(props));
|
|
1617
1811
|
Object.assign(this.bindings, bindings);
|
|
1618
1812
|
Object.assign(this.uniforms, uniforms);
|
|
1619
1813
|
this.setNeedsRedraw("moduleSettings");
|
|
1620
1814
|
}
|
|
1621
1815
|
// Internal methods
|
|
1622
|
-
/**
|
|
1816
|
+
/** Check that bindings are loaded. Returns id of first binding that is still loading. */
|
|
1817
|
+
_areBindingsLoading() {
|
|
1818
|
+
for (const binding of Object.values(this.bindings)) {
|
|
1819
|
+
if (binding instanceof AsyncTexture && !binding.isReady) {
|
|
1820
|
+
return binding.id;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
/** Extracts texture view from loaded async textures. Returns null if any textures have not yet been loaded. */
|
|
1623
1826
|
_getBindings() {
|
|
1624
|
-
|
|
1827
|
+
const validBindings = {};
|
|
1828
|
+
for (const [name, binding] of Object.entries(this.bindings)) {
|
|
1625
1829
|
if (binding instanceof AsyncTexture) {
|
|
1626
1830
|
if (binding.isReady) {
|
|
1627
|
-
|
|
1831
|
+
validBindings[name] = binding.texture;
|
|
1628
1832
|
}
|
|
1629
1833
|
} else {
|
|
1630
|
-
|
|
1834
|
+
validBindings[name] = binding;
|
|
1631
1835
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1836
|
+
}
|
|
1837
|
+
return validBindings;
|
|
1634
1838
|
}
|
|
1635
1839
|
/** Get the timestamp of the latest updated bound GPU memory resource (buffer/texture). */
|
|
1636
1840
|
_getBindingsUpdateTimestamp() {
|
|
@@ -1680,26 +1884,26 @@ var _Model = class {
|
|
|
1680
1884
|
let prevShaderVs = null;
|
|
1681
1885
|
let prevShaderFs = null;
|
|
1682
1886
|
if (this.pipeline) {
|
|
1683
|
-
|
|
1887
|
+
import_core7.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
1684
1888
|
prevShaderVs = this.pipeline.vs;
|
|
1685
1889
|
prevShaderFs = this.pipeline.fs;
|
|
1686
1890
|
}
|
|
1687
1891
|
this._pipelineNeedsUpdate = false;
|
|
1688
|
-
const
|
|
1892
|
+
const vs3 = this.shaderFactory.createShader({
|
|
1689
1893
|
id: `${this.id}-vertex`,
|
|
1690
1894
|
stage: "vertex",
|
|
1691
1895
|
source: this.source || this.vs,
|
|
1692
|
-
|
|
1896
|
+
debugShaders: this.props.debugShaders
|
|
1693
1897
|
});
|
|
1694
|
-
let
|
|
1898
|
+
let fs3 = null;
|
|
1695
1899
|
if (this.source) {
|
|
1696
|
-
|
|
1900
|
+
fs3 = vs3;
|
|
1697
1901
|
} else if (this.fs) {
|
|
1698
|
-
|
|
1902
|
+
fs3 = this.shaderFactory.createShader({
|
|
1699
1903
|
id: `${this.id}-fragment`,
|
|
1700
1904
|
stage: "fragment",
|
|
1701
1905
|
source: this.source || this.fs,
|
|
1702
|
-
|
|
1906
|
+
debugShaders: this.props.debugShaders
|
|
1703
1907
|
});
|
|
1704
1908
|
}
|
|
1705
1909
|
this.pipeline = this.pipelineFactory.createRenderPipeline({
|
|
@@ -1710,10 +1914,10 @@ var _Model = class {
|
|
|
1710
1914
|
// TODO - why set bindings here when we reset them every frame?
|
|
1711
1915
|
// Should we expose a BindGroup abstraction?
|
|
1712
1916
|
bindings: this._getBindings(),
|
|
1713
|
-
vs,
|
|
1714
|
-
fs
|
|
1917
|
+
vs: vs3,
|
|
1918
|
+
fs: fs3
|
|
1715
1919
|
});
|
|
1716
|
-
this._attributeInfos = (0,
|
|
1920
|
+
this._attributeInfos = (0, import_core7.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
|
|
1717
1921
|
if (prevShaderVs)
|
|
1718
1922
|
this.shaderFactory.release(prevShaderVs);
|
|
1719
1923
|
if (prevShaderFs)
|
|
@@ -1725,35 +1929,35 @@ var _Model = class {
|
|
|
1725
1929
|
_lastLogTime = 0;
|
|
1726
1930
|
_logOpen = false;
|
|
1727
1931
|
_logDrawCallStart() {
|
|
1728
|
-
const logDrawTimeout =
|
|
1729
|
-
if (
|
|
1932
|
+
const logDrawTimeout = import_core7.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1933
|
+
if (import_core7.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1730
1934
|
return;
|
|
1731
1935
|
}
|
|
1732
1936
|
this._lastLogTime = Date.now();
|
|
1733
1937
|
this._logOpen = true;
|
|
1734
|
-
|
|
1938
|
+
import_core7.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core7.log.level <= 2 })();
|
|
1735
1939
|
}
|
|
1736
1940
|
_logDrawCallEnd() {
|
|
1737
1941
|
if (this._logOpen) {
|
|
1738
1942
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
1739
|
-
|
|
1943
|
+
import_core7.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
|
|
1740
1944
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1741
1945
|
for (const [name, value] of Object.entries(this.uniforms)) {
|
|
1742
1946
|
uniformTable[name] = { value };
|
|
1743
1947
|
}
|
|
1744
|
-
|
|
1948
|
+
import_core7.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1745
1949
|
const attributeTable = this._getAttributeDebugTable();
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1950
|
+
import_core7.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
|
|
1951
|
+
import_core7.log.table(LOG_DRAW_PRIORITY, attributeTable)();
|
|
1952
|
+
import_core7.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1749
1953
|
this._logOpen = false;
|
|
1750
1954
|
}
|
|
1751
1955
|
}
|
|
1752
1956
|
_drawCount = 0;
|
|
1753
1957
|
_logFramebuffer(renderPass) {
|
|
1754
|
-
const debugFramebuffers =
|
|
1958
|
+
const debugFramebuffers = this.device.props.debugFramebuffers;
|
|
1755
1959
|
this._drawCount++;
|
|
1756
|
-
if (!debugFramebuffers
|
|
1960
|
+
if (!debugFramebuffers) {
|
|
1757
1961
|
return;
|
|
1758
1962
|
}
|
|
1759
1963
|
const framebuffer = renderPass.props.framebuffer;
|
|
@@ -1784,14 +1988,14 @@ var _Model = class {
|
|
|
1784
1988
|
}
|
|
1785
1989
|
// TODO - fix typing of luma data types
|
|
1786
1990
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
1787
|
-
const TypedArrayConstructor = (0,
|
|
1991
|
+
const TypedArrayConstructor = (0, import_core7.getTypedArrayFromDataType)(dataType);
|
|
1788
1992
|
const typedArray = attribute instanceof import_core7.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1789
1993
|
return typedArray.toString();
|
|
1790
1994
|
}
|
|
1791
1995
|
};
|
|
1792
1996
|
var Model = _Model;
|
|
1793
1997
|
__publicField(Model, "defaultProps", {
|
|
1794
|
-
...
|
|
1998
|
+
...import_core7.RenderPipeline.defaultProps,
|
|
1795
1999
|
source: void 0,
|
|
1796
2000
|
vs: null,
|
|
1797
2001
|
fs: null,
|
|
@@ -1817,17 +2021,8 @@ __publicField(Model, "defaultProps", {
|
|
|
1817
2021
|
debugShaders: void 0,
|
|
1818
2022
|
disableWarnings: void 0
|
|
1819
2023
|
});
|
|
1820
|
-
function
|
|
1821
|
-
|
|
1822
|
-
for (const attribute of layouts2) {
|
|
1823
|
-
const index = layouts.findIndex((attribute2) => attribute2.name === attribute.name);
|
|
1824
|
-
if (index < 0) {
|
|
1825
|
-
layouts.push(attribute);
|
|
1826
|
-
} else {
|
|
1827
|
-
layouts[index] = attribute;
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
return layouts;
|
|
2024
|
+
function shaderModuleHasUniforms(module2) {
|
|
2025
|
+
return Boolean(module2.uniformTypes && !isObjectEmpty(module2.uniformTypes));
|
|
1831
2026
|
}
|
|
1832
2027
|
function getPlatformInfo(device) {
|
|
1833
2028
|
return {
|
|
@@ -1839,33 +2034,26 @@ function getPlatformInfo(device) {
|
|
|
1839
2034
|
features: device.features
|
|
1840
2035
|
};
|
|
1841
2036
|
}
|
|
1842
|
-
function getAttributeNames(bufferLayout) {
|
|
1843
|
-
var _a;
|
|
1844
|
-
return bufferLayout.attributes ? (_a = bufferLayout.attributes) == null ? void 0 : _a.map((layout) => layout.attribute) : [bufferLayout.name];
|
|
1845
|
-
}
|
|
1846
2037
|
function isObjectEmpty(obj) {
|
|
1847
|
-
let isEmpty = true;
|
|
1848
2038
|
for (const key in obj) {
|
|
1849
|
-
|
|
1850
|
-
break;
|
|
2039
|
+
return false;
|
|
1851
2040
|
}
|
|
1852
|
-
return
|
|
2041
|
+
return true;
|
|
1853
2042
|
}
|
|
1854
2043
|
|
|
1855
|
-
// dist/
|
|
1856
|
-
var
|
|
2044
|
+
// dist/compute/buffer-transform.js
|
|
2045
|
+
var import_core8 = require("@luma.gl/core");
|
|
1857
2046
|
var import_shadertools3 = require("@luma.gl/shadertools");
|
|
1858
|
-
var
|
|
2047
|
+
var _BufferTransform = class {
|
|
1859
2048
|
device;
|
|
1860
2049
|
model;
|
|
1861
2050
|
transformFeedback;
|
|
1862
|
-
/** @deprecated Use device feature test. */
|
|
1863
2051
|
static isSupported(device) {
|
|
1864
2052
|
var _a;
|
|
1865
2053
|
return ((_a = device == null ? void 0 : device.info) == null ? void 0 : _a.type) === "webgl";
|
|
1866
2054
|
}
|
|
1867
|
-
constructor(device, props =
|
|
1868
|
-
if (!
|
|
2055
|
+
constructor(device, props = _BufferTransform.defaultProps) {
|
|
2056
|
+
if (!_BufferTransform.isSupported(device)) {
|
|
1869
2057
|
throw new Error("BufferTransform not yet implemented on WebGPU");
|
|
1870
2058
|
}
|
|
1871
2059
|
this.device = device;
|
|
@@ -1873,6 +2061,7 @@ var BufferTransform = class {
|
|
|
1873
2061
|
id: props.id || "buffer-transform-model",
|
|
1874
2062
|
fs: props.fs || (0, import_shadertools3.getPassthroughFS)(),
|
|
1875
2063
|
topology: props.topology || "point-list",
|
|
2064
|
+
varyings: props.outputs || props.varyings,
|
|
1876
2065
|
...props
|
|
1877
2066
|
});
|
|
1878
2067
|
this.transformFeedback = this.device.createTransformFeedback({
|
|
@@ -1895,32 +2084,42 @@ var BufferTransform = class {
|
|
|
1895
2084
|
}
|
|
1896
2085
|
/** Run one transform loop. */
|
|
1897
2086
|
run(options) {
|
|
2087
|
+
if (options == null ? void 0 : options.inputBuffers) {
|
|
2088
|
+
this.model.setAttributes(options.inputBuffers);
|
|
2089
|
+
}
|
|
2090
|
+
if (options == null ? void 0 : options.outputBuffers) {
|
|
2091
|
+
this.transformFeedback.setBuffers(options.outputBuffers);
|
|
2092
|
+
}
|
|
1898
2093
|
const renderPass = this.device.beginRenderPass(options);
|
|
1899
2094
|
this.model.draw(renderPass);
|
|
1900
2095
|
renderPass.end();
|
|
1901
2096
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
console.warn("TextureTransform#update() not implemented");
|
|
1905
|
-
}
|
|
1906
|
-
/** Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
2097
|
+
// DEPRECATED METHODS
|
|
2098
|
+
/** @deprecated App knows what buffers it is passing in - Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
1907
2099
|
getBuffer(varyingName) {
|
|
1908
2100
|
return this.transformFeedback.getBuffer(varyingName);
|
|
1909
2101
|
}
|
|
2102
|
+
/** @deprecated App knows what buffers it is passing in - Reads the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
1910
2103
|
readAsync(varyingName) {
|
|
1911
2104
|
const result = this.getBuffer(varyingName);
|
|
1912
2105
|
if (!result) {
|
|
1913
2106
|
throw new Error("BufferTransform#getBuffer");
|
|
1914
2107
|
}
|
|
1915
|
-
if (result instanceof
|
|
2108
|
+
if (result instanceof import_core8.Buffer) {
|
|
1916
2109
|
return result.readAsync();
|
|
1917
2110
|
}
|
|
1918
2111
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
1919
2112
|
return buffer.readAsync(byteOffset, byteLength);
|
|
1920
2113
|
}
|
|
1921
2114
|
};
|
|
2115
|
+
var BufferTransform = _BufferTransform;
|
|
2116
|
+
__publicField(BufferTransform, "defaultProps", {
|
|
2117
|
+
...Model.defaultProps,
|
|
2118
|
+
outputs: void 0,
|
|
2119
|
+
feedbackBuffers: void 0
|
|
2120
|
+
});
|
|
1922
2121
|
|
|
1923
|
-
// dist/
|
|
2122
|
+
// dist/compute/texture-transform.js
|
|
1924
2123
|
var import_shadertools4 = require("@luma.gl/shadertools");
|
|
1925
2124
|
var FS_OUTPUT_VARIABLE = "transform_output";
|
|
1926
2125
|
var TextureTransform = class {
|
|
@@ -1943,7 +2142,7 @@ var TextureTransform = class {
|
|
|
1943
2142
|
mipmapFilter: "nearest"
|
|
1944
2143
|
});
|
|
1945
2144
|
this.model = new Model(this.device, {
|
|
1946
|
-
id: props.id || "texture-transform-model",
|
|
2145
|
+
id: props.id || uid("texture-transform-model"),
|
|
1947
2146
|
fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
|
|
1948
2147
|
input: props.targetTextureVarying,
|
|
1949
2148
|
inputChannels: props.targetTextureChannels,
|
|
@@ -1958,6 +2157,11 @@ var TextureTransform = class {
|
|
|
1958
2157
|
}
|
|
1959
2158
|
// Delete owned resources.
|
|
1960
2159
|
destroy() {
|
|
2160
|
+
var _a;
|
|
2161
|
+
this.model.destroy();
|
|
2162
|
+
for (const binding of this.bindings) {
|
|
2163
|
+
(_a = binding.framebuffer) == null ? void 0 : _a.destroy();
|
|
2164
|
+
}
|
|
1961
2165
|
}
|
|
1962
2166
|
/** @deprecated Use {@link destroy}. */
|
|
1963
2167
|
delete() {
|
|
@@ -1969,13 +2173,6 @@ var TextureTransform = class {
|
|
|
1969
2173
|
this.model.draw(renderPass);
|
|
1970
2174
|
renderPass.end();
|
|
1971
2175
|
}
|
|
1972
|
-
/** @deprecated */
|
|
1973
|
-
update(...args) {
|
|
1974
|
-
console.warn("TextureTransform#update() not implemented");
|
|
1975
|
-
}
|
|
1976
|
-
getData({ packed = false } = {}) {
|
|
1977
|
-
throw new Error("getData() not implemented");
|
|
1978
|
-
}
|
|
1979
2176
|
getTargetTexture() {
|
|
1980
2177
|
const { targetTexture } = this.bindings[this.currentIndex];
|
|
1981
2178
|
return targetTexture;
|
|
@@ -2111,56 +2308,161 @@ var Geometry = class {
|
|
|
2111
2308
|
}
|
|
2112
2309
|
};
|
|
2113
2310
|
|
|
2114
|
-
// dist/
|
|
2311
|
+
// dist/models/clip-space.js
|
|
2312
|
+
var CLIPSPACE_VERTEX_SHADER_WGSL = (
|
|
2313
|
+
/* wgsl */
|
|
2314
|
+
`struct VertexInputs {
|
|
2315
|
+
@location(0) clipSpacePosition: vec2<f32>,
|
|
2316
|
+
@location(1) texCoord: vec2<f32>,
|
|
2317
|
+
@location(2) coordinate: vec2<f32>
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
struct FragmentInputs {
|
|
2321
|
+
@builtin(position) Position : vec4<f32>,
|
|
2322
|
+
@location(0) position : vec2<f32>,
|
|
2323
|
+
@location(1) coordinate : vec2<f32>,
|
|
2324
|
+
@location(2) uv : vec2<f32>
|
|
2325
|
+
};
|
|
2326
|
+
|
|
2327
|
+
@vertex
|
|
2328
|
+
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
2329
|
+
var outputs: FragmentInputs;
|
|
2330
|
+
outputs.Position = vec4(inputs.clipSpacePosition, 0., 1.);
|
|
2331
|
+
outputs.position = inputs.clipSpacePosition;
|
|
2332
|
+
outputs.coordinate = inputs.coordinate;
|
|
2333
|
+
outputs.uv = inputs.texCoord;
|
|
2334
|
+
return outputs;
|
|
2335
|
+
}
|
|
2336
|
+
`
|
|
2337
|
+
);
|
|
2115
2338
|
var CLIPSPACE_VERTEX_SHADER = (
|
|
2116
2339
|
/* glsl */
|
|
2117
2340
|
`#version 300 es
|
|
2118
|
-
in vec2
|
|
2119
|
-
in vec2
|
|
2120
|
-
in vec2
|
|
2341
|
+
in vec2 clipSpacePosition;
|
|
2342
|
+
in vec2 texCoord;
|
|
2343
|
+
in vec2 coordinate;
|
|
2121
2344
|
|
|
2122
2345
|
out vec2 position;
|
|
2123
2346
|
out vec2 coordinate;
|
|
2124
2347
|
out vec2 uv;
|
|
2125
2348
|
|
|
2126
2349
|
void main(void) {
|
|
2127
|
-
gl_Position = vec4(
|
|
2128
|
-
position =
|
|
2129
|
-
coordinate =
|
|
2130
|
-
uv =
|
|
2350
|
+
gl_Position = vec4(clipSpacePosition, 0., 1.);
|
|
2351
|
+
position = clipSpacePosition;
|
|
2352
|
+
coordinate = coordinate;
|
|
2353
|
+
uv = texCoord;
|
|
2131
2354
|
}
|
|
2132
2355
|
`
|
|
2133
2356
|
);
|
|
2134
2357
|
var POSITIONS = [-1, -1, 1, -1, -1, 1, 1, 1];
|
|
2135
2358
|
var ClipSpace = class extends Model {
|
|
2136
|
-
constructor(device,
|
|
2359
|
+
constructor(device, props) {
|
|
2137
2360
|
const TEX_COORDS = POSITIONS.map((coord) => coord === -1 ? 0 : coord);
|
|
2361
|
+
if (props.source) {
|
|
2362
|
+
props = { ...props, source: `${CLIPSPACE_VERTEX_SHADER_WGSL}
|
|
2363
|
+
${props.source}` };
|
|
2364
|
+
}
|
|
2138
2365
|
super(device, {
|
|
2139
|
-
|
|
2366
|
+
id: props.id || uid("clip-space"),
|
|
2367
|
+
...props,
|
|
2140
2368
|
vs: CLIPSPACE_VERTEX_SHADER,
|
|
2141
2369
|
vertexCount: 4,
|
|
2142
2370
|
geometry: new Geometry({
|
|
2143
2371
|
topology: "triangle-strip",
|
|
2144
2372
|
vertexCount: 4,
|
|
2145
2373
|
attributes: {
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2374
|
+
clipSpacePosition: { size: 2, value: new Float32Array(POSITIONS) },
|
|
2375
|
+
texCoord: { size: 2, value: new Float32Array(TEX_COORDS) },
|
|
2376
|
+
coordinate: { size: 2, value: new Float32Array(TEX_COORDS) }
|
|
2149
2377
|
}
|
|
2150
2378
|
})
|
|
2151
2379
|
});
|
|
2152
2380
|
}
|
|
2153
2381
|
};
|
|
2154
2382
|
|
|
2383
|
+
// dist/models/billboard-texture-model.js
|
|
2384
|
+
var BACKGROUND_FS_WGSL = (
|
|
2385
|
+
/* wgsl */
|
|
2386
|
+
`@group(0) @binding(0) var backgroundTexture: texture_2d<f32>;
|
|
2387
|
+
@group(0) @binding(1) var backgroundTextureSampler: sampler;
|
|
2388
|
+
|
|
2389
|
+
fn billboardTexture_getTextureUV(coordinates: vec2<f32>) -> vec2<f32> {
|
|
2390
|
+
let iTexSize: vec2<u32> = textureDimensions(backgroundTexture, 0) * 2;
|
|
2391
|
+
let texSize: vec2<f32> = vec2<f32>(f32(iTexSize.x), f32(iTexSize.y));
|
|
2392
|
+
var position: vec2<f32> = coordinates.xy / texSize;
|
|
2393
|
+
return position;
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
@fragment
|
|
2397
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
2398
|
+
let position: vec2<f32> = billboardTexture_getTextureUV(inputs.coordinate);
|
|
2399
|
+
return textureSample(backgroundTexture, backgroundTextureSampler, position);
|
|
2400
|
+
}
|
|
2401
|
+
`
|
|
2402
|
+
);
|
|
2403
|
+
var BACKGROUND_FS = (
|
|
2404
|
+
/* glsl */
|
|
2405
|
+
`#version 300 es
|
|
2406
|
+
precision highp float;
|
|
2407
|
+
|
|
2408
|
+
uniform sampler2D backgroundTexture;
|
|
2409
|
+
out vec4 fragColor;
|
|
2410
|
+
|
|
2411
|
+
vec2 billboardTexture_getTextureUV() {
|
|
2412
|
+
ivec2 iTexSize = textureDimensions(backgroundTexture, 0) * 2;
|
|
2413
|
+
vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
|
|
2414
|
+
vec2 position = gl_FragCoord.xy / texSize;
|
|
2415
|
+
return position;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
void main(void) {
|
|
2419
|
+
vec2 position = billboardTexture_getTextureUV();
|
|
2420
|
+
fragColor = texture(backgroundTexture, position);
|
|
2421
|
+
}
|
|
2422
|
+
`
|
|
2423
|
+
);
|
|
2424
|
+
var BackgroundTextureModel = class extends ClipSpace {
|
|
2425
|
+
constructor(device, props) {
|
|
2426
|
+
super(device, {
|
|
2427
|
+
id: props.id || "background-texture-model",
|
|
2428
|
+
source: BACKGROUND_FS_WGSL,
|
|
2429
|
+
fs: BACKGROUND_FS,
|
|
2430
|
+
parameters: {
|
|
2431
|
+
depthWriteEnabled: false,
|
|
2432
|
+
depthCompare: "always",
|
|
2433
|
+
...props.blend ? {
|
|
2434
|
+
blend: true,
|
|
2435
|
+
blendColorOperation: "add",
|
|
2436
|
+
blendAlphaOperation: "add",
|
|
2437
|
+
blendColorSrcFactor: "one",
|
|
2438
|
+
blendColorDstFactor: "one-minus-src-color",
|
|
2439
|
+
blendAlphaSrcFactor: "one",
|
|
2440
|
+
blendAlphaDstFactor: "one-minus-src-alpha"
|
|
2441
|
+
} : {}
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
this.setTexture(props.backgroundTexture);
|
|
2445
|
+
}
|
|
2446
|
+
setTexture(backgroundTexture) {
|
|
2447
|
+
this.setBindings({
|
|
2448
|
+
backgroundTexture
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
predraw() {
|
|
2452
|
+
this.shaderInputs.setProps({});
|
|
2453
|
+
super.predraw();
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
|
|
2155
2457
|
// dist/scenegraph/scenegraph-node.js
|
|
2156
|
-
var
|
|
2458
|
+
var import_core9 = require("@math.gl/core");
|
|
2157
2459
|
var ScenegraphNode = class {
|
|
2158
2460
|
id;
|
|
2159
|
-
matrix = new
|
|
2461
|
+
matrix = new import_core9.Matrix4();
|
|
2160
2462
|
display = true;
|
|
2161
|
-
position = new
|
|
2162
|
-
rotation = new
|
|
2163
|
-
scale = new
|
|
2463
|
+
position = new import_core9.Vector3();
|
|
2464
|
+
rotation = new import_core9.Vector3();
|
|
2465
|
+
scale = new import_core9.Vector3(1, 1, 1);
|
|
2164
2466
|
userData = {};
|
|
2165
2467
|
props = {};
|
|
2166
2468
|
constructor(props = {}) {
|
|
@@ -2245,7 +2547,7 @@ var ScenegraphNode = class {
|
|
|
2245
2547
|
}
|
|
2246
2548
|
getCoordinateUniforms(viewMatrix, modelMatrix) {
|
|
2247
2549
|
modelMatrix = modelMatrix || this.matrix;
|
|
2248
|
-
const worldMatrix = new
|
|
2550
|
+
const worldMatrix = new import_core9.Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
2249
2551
|
const worldInverse = worldMatrix.invert();
|
|
2250
2552
|
const worldInverseTranspose = worldInverse.transpose();
|
|
2251
2553
|
return {
|
|
@@ -2297,14 +2599,14 @@ var ScenegraphNode = class {
|
|
|
2297
2599
|
};
|
|
2298
2600
|
|
|
2299
2601
|
// dist/scenegraph/group-node.js
|
|
2300
|
-
var
|
|
2301
|
-
var
|
|
2602
|
+
var import_core10 = require("@math.gl/core");
|
|
2603
|
+
var import_core11 = require("@luma.gl/core");
|
|
2302
2604
|
var GroupNode = class extends ScenegraphNode {
|
|
2303
2605
|
children;
|
|
2304
2606
|
constructor(props = {}) {
|
|
2305
2607
|
props = Array.isArray(props) ? { children: props } : props;
|
|
2306
2608
|
const { children = [] } = props;
|
|
2307
|
-
|
|
2609
|
+
import_core11.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
|
|
2308
2610
|
super(props);
|
|
2309
2611
|
this.children = children;
|
|
2310
2612
|
}
|
|
@@ -2319,12 +2621,12 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
2319
2621
|
return;
|
|
2320
2622
|
}
|
|
2321
2623
|
const [min, max] = bounds;
|
|
2322
|
-
const center = new
|
|
2624
|
+
const center = new import_core10.Vector3(min).add(max).divide([2, 2, 2]);
|
|
2323
2625
|
worldMatrix.transformAsPoint(center, center);
|
|
2324
|
-
const halfSize = new
|
|
2626
|
+
const halfSize = new import_core10.Vector3(max).subtract(min).divide([2, 2, 2]);
|
|
2325
2627
|
worldMatrix.transformAsVector(halfSize, halfSize);
|
|
2326
2628
|
for (let v = 0; v < 8; v++) {
|
|
2327
|
-
const position = new
|
|
2629
|
+
const position = new import_core10.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
|
|
2328
2630
|
for (let i = 0; i < 3; i++) {
|
|
2329
2631
|
result[0][i] = Math.min(result[0][i], position[i]);
|
|
2330
2632
|
result[1][i] = Math.max(result[1][i], position[i]);
|
|
@@ -2364,8 +2666,8 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
2364
2666
|
this.children = [];
|
|
2365
2667
|
return this;
|
|
2366
2668
|
}
|
|
2367
|
-
traverse(visitor, { worldMatrix = new
|
|
2368
|
-
const modelMatrix = new
|
|
2669
|
+
traverse(visitor, { worldMatrix = new import_core10.Matrix4() } = {}) {
|
|
2670
|
+
const modelMatrix = new import_core10.Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
2369
2671
|
for (const child of this.children) {
|
|
2370
2672
|
if (child instanceof GroupNode) {
|
|
2371
2673
|
child.traverse(visitor, { worldMatrix: modelMatrix });
|
|
@@ -3147,7 +3449,7 @@ var CylinderGeometry = class extends TruncatedConeGeometry {
|
|
|
3147
3449
|
};
|
|
3148
3450
|
|
|
3149
3451
|
// dist/geometries/ico-sphere-geometry.js
|
|
3150
|
-
var
|
|
3452
|
+
var import_core12 = require("@math.gl/core");
|
|
3151
3453
|
var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
|
|
3152
3454
|
var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
|
|
3153
3455
|
var IcoSphereGeometry = class extends Geometry {
|
|
@@ -3245,7 +3547,7 @@ function tesselateIcosaHedron(props) {
|
|
|
3245
3547
|
const u3 = 1 - phi3 / PI2;
|
|
3246
3548
|
const vec1 = [x3 - x2, y3 - y2, z3 - z2];
|
|
3247
3549
|
const vec2 = [x1 - x2, y1 - y2, z1 - z2];
|
|
3248
|
-
const normal = new
|
|
3550
|
+
const normal = new import_core12.Vector3(vec1).cross(vec2).normalize();
|
|
3249
3551
|
let newIndex;
|
|
3250
3552
|
if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
|
|
3251
3553
|
positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
|
|
@@ -3505,11 +3807,377 @@ function fract(n) {
|
|
|
3505
3807
|
return n - Math.floor(n);
|
|
3506
3808
|
}
|
|
3507
3809
|
|
|
3508
|
-
// dist/
|
|
3509
|
-
var import_core16 = require("@luma.gl/core");
|
|
3510
|
-
var import_core17 = require("@luma.gl/core");
|
|
3511
|
-
var import_core18 = require("@luma.gl/core");
|
|
3810
|
+
// dist/passes/shader-pass-renderer.js
|
|
3512
3811
|
var import_shadertools5 = require("@luma.gl/shadertools");
|
|
3812
|
+
|
|
3813
|
+
// dist/compute/swap.js
|
|
3814
|
+
var import_core13 = require("@luma.gl/core");
|
|
3815
|
+
var Swap = class {
|
|
3816
|
+
/** The current resource - usually the source for renders or computations */
|
|
3817
|
+
current;
|
|
3818
|
+
/** The next resource - usually the target/destination for transforms / computations */
|
|
3819
|
+
next;
|
|
3820
|
+
constructor(props) {
|
|
3821
|
+
this.current = props.current;
|
|
3822
|
+
this.next = props.next;
|
|
3823
|
+
}
|
|
3824
|
+
/** Destroys the two managed resources */
|
|
3825
|
+
destroy() {
|
|
3826
|
+
var _a, _b;
|
|
3827
|
+
(_a = this.current) == null ? void 0 : _a.destroy();
|
|
3828
|
+
(_b = this.next) == null ? void 0 : _b.destroy();
|
|
3829
|
+
}
|
|
3830
|
+
/** Make the next resource into the current resource, and reuse the current resource as the next resource */
|
|
3831
|
+
swap() {
|
|
3832
|
+
const current = this.current;
|
|
3833
|
+
this.current = this.next;
|
|
3834
|
+
this.next = current;
|
|
3835
|
+
}
|
|
3836
|
+
};
|
|
3837
|
+
var SwapFramebuffers = class extends Swap {
|
|
3838
|
+
constructor(device, props) {
|
|
3839
|
+
var _a, _b;
|
|
3840
|
+
props = { ...props };
|
|
3841
|
+
let colorAttachments = (_a = props.colorAttachments) == null ? void 0 : _a.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
3842
|
+
format: colorAttachment,
|
|
3843
|
+
usage: import_core13.Texture.COPY_DST | import_core13.Texture.RENDER_ATTACHMENT
|
|
3844
|
+
}));
|
|
3845
|
+
const current = device.createFramebuffer({ ...props, colorAttachments });
|
|
3846
|
+
colorAttachments = (_b = props.colorAttachments) == null ? void 0 : _b.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
3847
|
+
format: colorAttachment,
|
|
3848
|
+
usage: import_core13.Texture.COPY_DST | import_core13.Texture.RENDER_ATTACHMENT
|
|
3849
|
+
}));
|
|
3850
|
+
const next = device.createFramebuffer({ ...props, colorAttachments });
|
|
3851
|
+
super({ current, next });
|
|
3852
|
+
}
|
|
3853
|
+
/**
|
|
3854
|
+
* Resizes the Framebuffers.
|
|
3855
|
+
* @returns true if the size changed, otherwise exiting framebuffers were preserved
|
|
3856
|
+
* @note any contents are not preserved!
|
|
3857
|
+
*/
|
|
3858
|
+
resize(size) {
|
|
3859
|
+
if (size.width === this.current.width && size.height === this.current.height) {
|
|
3860
|
+
return false;
|
|
3861
|
+
}
|
|
3862
|
+
const { current, next } = this;
|
|
3863
|
+
this.current = current.clone(size);
|
|
3864
|
+
current.destroy();
|
|
3865
|
+
this.next = next.clone(size);
|
|
3866
|
+
next.destroy();
|
|
3867
|
+
return true;
|
|
3868
|
+
}
|
|
3869
|
+
};
|
|
3870
|
+
var SwapBuffers = class extends Swap {
|
|
3871
|
+
constructor(device, props) {
|
|
3872
|
+
super({ current: device.createBuffer(props), next: device.createBuffer(props) });
|
|
3873
|
+
}
|
|
3874
|
+
/**
|
|
3875
|
+
* Resizes the Buffers.
|
|
3876
|
+
* @returns true if the size changed, otherwise exiting buffers were preserved.
|
|
3877
|
+
* @note any contents are not preserved!
|
|
3878
|
+
*/
|
|
3879
|
+
resize(props) {
|
|
3880
|
+
if (props.byteLength === this.current.byteLength) {
|
|
3881
|
+
return false;
|
|
3882
|
+
}
|
|
3883
|
+
const { current, next } = this;
|
|
3884
|
+
this.current = current.clone(props);
|
|
3885
|
+
current.destroy();
|
|
3886
|
+
this.next = next.clone(props);
|
|
3887
|
+
next.destroy();
|
|
3888
|
+
return true;
|
|
3889
|
+
}
|
|
3890
|
+
};
|
|
3891
|
+
|
|
3892
|
+
// dist/passes/get-fragment-shader.js
|
|
3893
|
+
function getFragmentShaderForRenderPass(options) {
|
|
3894
|
+
const { shaderPass, action, shadingLanguage } = options;
|
|
3895
|
+
switch (action) {
|
|
3896
|
+
case "filter":
|
|
3897
|
+
const filterFunc = `${shaderPass.name}_filterColor_ext`;
|
|
3898
|
+
return shadingLanguage === "wgsl" ? getFilterShaderWGSL(filterFunc) : getFilterShaderGLSL(filterFunc);
|
|
3899
|
+
case "sample":
|
|
3900
|
+
const samplerFunc = `${shaderPass.name}_sampleColor`;
|
|
3901
|
+
return shadingLanguage === "wgsl" ? getSamplerShaderWGSL(samplerFunc) : getSamplerShaderGLSL(samplerFunc);
|
|
3902
|
+
default:
|
|
3903
|
+
throw new Error(`${shaderPass.name} no fragment shader generated for shader pass`);
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
function getFilterShaderWGSL(func) {
|
|
3907
|
+
return (
|
|
3908
|
+
/* wgsl */
|
|
3909
|
+
`// Binding 0:1 is reserved for shader passes
|
|
3910
|
+
@group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
|
|
3911
|
+
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
3912
|
+
@group(0) @binding(2) var sampler: sampler;
|
|
3913
|
+
|
|
3914
|
+
struct FragmentInputs = {
|
|
3915
|
+
@location(0) fragUV: vec2f,
|
|
3916
|
+
@location(1) fragPosition: vec4f,
|
|
3917
|
+
@location(2) fragCoordinate: vec4f
|
|
3918
|
+
};
|
|
3919
|
+
|
|
3920
|
+
@fragment
|
|
3921
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
3922
|
+
let texSize = textureDimensions(texture, 0);
|
|
3923
|
+
var fragColor = textureSample(texture, sampler, fragUV);
|
|
3924
|
+
fragColor = ${func}(gl_FragColor, texSize, texCoord);
|
|
3925
|
+
return fragColor;
|
|
3926
|
+
}
|
|
3927
|
+
`
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
function getSamplerShaderWGSL(func) {
|
|
3931
|
+
return (
|
|
3932
|
+
/* wgsl */
|
|
3933
|
+
`// Binding 0:1 is reserved for shader passes
|
|
3934
|
+
@group(0) @binding(0) var<uniform> brightnessContrast : brightnessContrastUniforms;
|
|
3935
|
+
@group(0) @binding(1) var texture: texture_2d<f32>;
|
|
3936
|
+
@group(0) @binding(2) var sampler: sampler;
|
|
3937
|
+
|
|
3938
|
+
struct FragmentInputs = {
|
|
3939
|
+
@location(0) fragUV: vec2f,
|
|
3940
|
+
@location(1) fragPosition: vec4f,
|
|
3941
|
+
@location(2) fragCoordinate: vec4f
|
|
3942
|
+
};
|
|
3943
|
+
|
|
3944
|
+
@fragment
|
|
3945
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
3946
|
+
let texSize = textureDimensions(texture, 0);
|
|
3947
|
+
var fragColor = textureSample(texture, sampler, fragUV);
|
|
3948
|
+
fragColor = ${func}(gl_FragColor, texSize, texCoord);
|
|
3949
|
+
return fragColor;
|
|
3950
|
+
}
|
|
3951
|
+
`
|
|
3952
|
+
);
|
|
3953
|
+
}
|
|
3954
|
+
function getFilterShaderGLSL(func) {
|
|
3955
|
+
return (
|
|
3956
|
+
/* glsl */
|
|
3957
|
+
`#version 300 es
|
|
3958
|
+
|
|
3959
|
+
uniform sampler2D sourceTexture;
|
|
3960
|
+
|
|
3961
|
+
in vec2 position;
|
|
3962
|
+
in vec2 coordinate;
|
|
3963
|
+
in vec2 uv;
|
|
3964
|
+
|
|
3965
|
+
out vec4 fragColor;
|
|
3966
|
+
|
|
3967
|
+
void main() {
|
|
3968
|
+
vec2 texCoord = coordinate;
|
|
3969
|
+
ivec2 iTexSize = textureSize(sourceTexture, 0);
|
|
3970
|
+
vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
|
|
3971
|
+
|
|
3972
|
+
fragColor = texture(sourceTexture, texCoord);
|
|
3973
|
+
fragColor = ${func}(fragColor, texSize, texCoord);
|
|
3974
|
+
}
|
|
3975
|
+
`
|
|
3976
|
+
);
|
|
3977
|
+
}
|
|
3978
|
+
function getSamplerShaderGLSL(func) {
|
|
3979
|
+
return (
|
|
3980
|
+
/* glsl */
|
|
3981
|
+
`#version 300 es
|
|
3982
|
+
|
|
3983
|
+
uniform sampler2D sourceTexture;
|
|
3984
|
+
|
|
3985
|
+
in vec2 position;
|
|
3986
|
+
in vec2 coordinate;
|
|
3987
|
+
in vec2 uv;
|
|
3988
|
+
|
|
3989
|
+
out vec4 fragColor;
|
|
3990
|
+
|
|
3991
|
+
void main() {
|
|
3992
|
+
vec2 texCoord = coordinate;
|
|
3993
|
+
ivec2 iTexSize = textureSize(sourceTexture, 0);
|
|
3994
|
+
vec2 texSize = vec2(float(iTexSize.x), float(iTexSize.y));
|
|
3995
|
+
|
|
3996
|
+
fragColor = ${func}(sourceTexture, texSize, texCoord);
|
|
3997
|
+
}
|
|
3998
|
+
`
|
|
3999
|
+
);
|
|
4000
|
+
}
|
|
4001
|
+
|
|
4002
|
+
// dist/passes/shader-pass-renderer.js
|
|
4003
|
+
var ShaderPassRenderer = class {
|
|
4004
|
+
device;
|
|
4005
|
+
shaderInputs;
|
|
4006
|
+
passRenderers;
|
|
4007
|
+
swapFramebuffers;
|
|
4008
|
+
/** For rendering to the screen */
|
|
4009
|
+
clipSpace;
|
|
4010
|
+
textureModel;
|
|
4011
|
+
constructor(device, props) {
|
|
4012
|
+
this.device = device;
|
|
4013
|
+
props.shaderPasses.map((shaderPass) => (0, import_shadertools5.initializeShaderModule)(shaderPass));
|
|
4014
|
+
const modules = props.shaderPasses.reduce((object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }), {});
|
|
4015
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(modules);
|
|
4016
|
+
const size = device.getCanvasContext().getPixelSize();
|
|
4017
|
+
this.swapFramebuffers = new SwapFramebuffers(device, {
|
|
4018
|
+
colorAttachments: ["rgba8unorm"],
|
|
4019
|
+
width: size[0],
|
|
4020
|
+
height: size[1]
|
|
4021
|
+
});
|
|
4022
|
+
this.textureModel = new BackgroundTextureModel(device, {
|
|
4023
|
+
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
4024
|
+
});
|
|
4025
|
+
this.clipSpace = new ClipSpace(device, {
|
|
4026
|
+
source: (
|
|
4027
|
+
/* wgsl */
|
|
4028
|
+
` @group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
4029
|
+
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
4030
|
+
|
|
4031
|
+
@fragment
|
|
4032
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
4033
|
+
let texCoord: vec2<f32> = inputs.coordinate;
|
|
4034
|
+
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
4035
|
+
}
|
|
4036
|
+
`
|
|
4037
|
+
),
|
|
4038
|
+
fs: (
|
|
4039
|
+
/* glsl */
|
|
4040
|
+
`#version 300 es
|
|
4041
|
+
|
|
4042
|
+
uniform sampler2D sourceTexture;
|
|
4043
|
+
in vec2 uv;
|
|
4044
|
+
in vec2 coordinate;
|
|
4045
|
+
out vec4 fragColor;
|
|
4046
|
+
|
|
4047
|
+
void main() {
|
|
4048
|
+
vec2 texCoord = coordinate;
|
|
4049
|
+
fragColor = texture(sourceTexture, coordinate);
|
|
4050
|
+
}
|
|
4051
|
+
`
|
|
4052
|
+
)
|
|
4053
|
+
});
|
|
4054
|
+
this.passRenderers = props.shaderPasses.map((shaderPass) => new PassRenderer(device, shaderPass));
|
|
4055
|
+
}
|
|
4056
|
+
/** Destroys resources created by this ShaderPassRenderer */
|
|
4057
|
+
destroy() {
|
|
4058
|
+
for (const subPassRenderer of this.passRenderers) {
|
|
4059
|
+
subPassRenderer.destroy();
|
|
4060
|
+
}
|
|
4061
|
+
this.swapFramebuffers.destroy();
|
|
4062
|
+
this.clipSpace.destroy();
|
|
4063
|
+
}
|
|
4064
|
+
resize(width, height) {
|
|
4065
|
+
this.swapFramebuffers.resize({ width, height });
|
|
4066
|
+
}
|
|
4067
|
+
renderToScreen(options) {
|
|
4068
|
+
const outputTexture = this.renderToTexture(options);
|
|
4069
|
+
if (!outputTexture) {
|
|
4070
|
+
return false;
|
|
4071
|
+
}
|
|
4072
|
+
const renderPass = this.device.beginRenderPass({ clearColor: [0, 0, 0, 1], clearDepth: 1 });
|
|
4073
|
+
this.clipSpace.setBindings({ sourceTexture: outputTexture });
|
|
4074
|
+
this.clipSpace.draw(renderPass);
|
|
4075
|
+
renderPass.end();
|
|
4076
|
+
return true;
|
|
4077
|
+
}
|
|
4078
|
+
/** Runs the shaderPasses in sequence on the sourceTexture and returns a texture with the results.
|
|
4079
|
+
* @returns null if the the sourceTexture has not yet been loaded
|
|
4080
|
+
*/
|
|
4081
|
+
renderToTexture(options) {
|
|
4082
|
+
const { sourceTexture } = options;
|
|
4083
|
+
if (!sourceTexture.isReady) {
|
|
4084
|
+
return null;
|
|
4085
|
+
}
|
|
4086
|
+
this.textureModel.destroy();
|
|
4087
|
+
this.textureModel = new BackgroundTextureModel(this.device, {
|
|
4088
|
+
backgroundTexture: sourceTexture
|
|
4089
|
+
});
|
|
4090
|
+
const clearTexturePass = this.device.beginRenderPass({
|
|
4091
|
+
framebuffer: this.swapFramebuffers.current,
|
|
4092
|
+
clearColor: [0, 0, 0, 1]
|
|
4093
|
+
});
|
|
4094
|
+
this.textureModel.draw(clearTexturePass);
|
|
4095
|
+
clearTexturePass.end();
|
|
4096
|
+
let first = true;
|
|
4097
|
+
for (const passRenderer of this.passRenderers) {
|
|
4098
|
+
for (const subPassRenderer of passRenderer.subPassRenderers) {
|
|
4099
|
+
if (!first) {
|
|
4100
|
+
this.swapFramebuffers.swap();
|
|
4101
|
+
}
|
|
4102
|
+
first = false;
|
|
4103
|
+
const swapBufferTexture = this.swapFramebuffers.current.colorAttachments[0].texture;
|
|
4104
|
+
const bindings = {
|
|
4105
|
+
sourceTexture: swapBufferTexture
|
|
4106
|
+
// texSize: [sourceTextures.width, sourceTextures.height]
|
|
4107
|
+
};
|
|
4108
|
+
const renderPass = this.device.beginRenderPass({
|
|
4109
|
+
framebuffer: this.swapFramebuffers.next,
|
|
4110
|
+
clearColor: [0, 0, 0, 1],
|
|
4111
|
+
clearDepth: 1
|
|
4112
|
+
});
|
|
4113
|
+
subPassRenderer.render({ renderPass, bindings });
|
|
4114
|
+
renderPass.end();
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
this.swapFramebuffers.swap();
|
|
4118
|
+
const outputTexture = this.swapFramebuffers.current.colorAttachments[0].texture;
|
|
4119
|
+
return outputTexture;
|
|
4120
|
+
}
|
|
4121
|
+
};
|
|
4122
|
+
var PassRenderer = class {
|
|
4123
|
+
shaderPass;
|
|
4124
|
+
subPassRenderers;
|
|
4125
|
+
constructor(device, shaderPass, props = {}) {
|
|
4126
|
+
this.shaderPass = shaderPass;
|
|
4127
|
+
const subPasses = shaderPass.passes || [];
|
|
4128
|
+
this.subPassRenderers = subPasses.map((subPass) => {
|
|
4129
|
+
return new SubPassRenderer(device, shaderPass, subPass);
|
|
4130
|
+
});
|
|
4131
|
+
}
|
|
4132
|
+
destroy() {
|
|
4133
|
+
for (const subPassRenderer of this.subPassRenderers) {
|
|
4134
|
+
subPassRenderer.destroy();
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
};
|
|
4138
|
+
var SubPassRenderer = class {
|
|
4139
|
+
model;
|
|
4140
|
+
shaderPass;
|
|
4141
|
+
subPass;
|
|
4142
|
+
constructor(device, shaderPass, subPass) {
|
|
4143
|
+
this.shaderPass = shaderPass;
|
|
4144
|
+
this.subPass = subPass;
|
|
4145
|
+
const action = subPass.action || subPass.filter && "filter" || subPass.sampler && "sample" || "filter";
|
|
4146
|
+
const fs3 = getFragmentShaderForRenderPass({
|
|
4147
|
+
shaderPass,
|
|
4148
|
+
action,
|
|
4149
|
+
shadingLanguage: device.info.shadingLanguage
|
|
4150
|
+
});
|
|
4151
|
+
this.model = new ClipSpace(device, {
|
|
4152
|
+
id: `${shaderPass.name}-subpass`,
|
|
4153
|
+
source: fs3,
|
|
4154
|
+
fs: fs3,
|
|
4155
|
+
modules: [shaderPass],
|
|
4156
|
+
parameters: {
|
|
4157
|
+
depthWriteEnabled: false,
|
|
4158
|
+
depthCompare: "always"
|
|
4159
|
+
}
|
|
4160
|
+
});
|
|
4161
|
+
}
|
|
4162
|
+
destroy() {
|
|
4163
|
+
this.model.destroy();
|
|
4164
|
+
}
|
|
4165
|
+
render(options) {
|
|
4166
|
+
const { renderPass, bindings } = options;
|
|
4167
|
+
this.model.shaderInputs.setProps({
|
|
4168
|
+
[this.shaderPass.name]: this.shaderPass.uniforms || {}
|
|
4169
|
+
});
|
|
4170
|
+
this.model.shaderInputs.setProps({
|
|
4171
|
+
[this.shaderPass.name]: this.subPass.uniforms || {}
|
|
4172
|
+
});
|
|
4173
|
+
this.model.setBindings(bindings || {});
|
|
4174
|
+
this.model.draw(renderPass);
|
|
4175
|
+
}
|
|
4176
|
+
};
|
|
4177
|
+
|
|
4178
|
+
// dist/compute/computation.js
|
|
4179
|
+
var import_core14 = require("@luma.gl/core");
|
|
4180
|
+
var import_shadertools6 = require("@luma.gl/shadertools");
|
|
3513
4181
|
var import_types2 = require("@math.gl/types");
|
|
3514
4182
|
var LOG_DRAW_PRIORITY2 = 2;
|
|
3515
4183
|
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
@@ -3549,18 +4217,18 @@ var _Computation = class {
|
|
|
3549
4217
|
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
3550
4218
|
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
3551
4219
|
this.setShaderInputs(this.shaderInputs);
|
|
3552
|
-
this.props.shaderLayout ||= (0,
|
|
4220
|
+
this.props.shaderLayout ||= (0, import_shadertools6.getShaderLayoutFromWGSL)(this.props.source);
|
|
3553
4221
|
const platformInfo = getPlatformInfo2(device);
|
|
3554
4222
|
const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
|
|
3555
4223
|
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
3556
4224
|
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
3557
|
-
const { source, getUniforms } = this.props.shaderAssembler.assembleWGSLShader({
|
|
4225
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
3558
4226
|
platformInfo,
|
|
3559
4227
|
...this.props,
|
|
3560
4228
|
modules
|
|
3561
4229
|
});
|
|
3562
|
-
this.source =
|
|
3563
|
-
this._getModuleUniforms =
|
|
4230
|
+
this.source = source3;
|
|
4231
|
+
this._getModuleUniforms = getUniforms2;
|
|
3564
4232
|
this.pipeline = this._updatePipeline();
|
|
3565
4233
|
if (props.bindings) {
|
|
3566
4234
|
this.setBindings(props.bindings);
|
|
@@ -3607,7 +4275,7 @@ var _Computation = class {
|
|
|
3607
4275
|
}
|
|
3608
4276
|
setShaderInputs(shaderInputs) {
|
|
3609
4277
|
this.shaderInputs = shaderInputs;
|
|
3610
|
-
this._uniformStore = new
|
|
4278
|
+
this._uniformStore = new import_core14.UniformStore(this.shaderInputs.modules);
|
|
3611
4279
|
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
3612
4280
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
3613
4281
|
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
@@ -3644,7 +4312,7 @@ var _Computation = class {
|
|
|
3644
4312
|
if (this._pipelineNeedsUpdate) {
|
|
3645
4313
|
let prevShader = null;
|
|
3646
4314
|
if (this.pipeline) {
|
|
3647
|
-
|
|
4315
|
+
import_core14.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
3648
4316
|
prevShader = this.shader;
|
|
3649
4317
|
}
|
|
3650
4318
|
this._pipelineNeedsUpdate = false;
|
|
@@ -3652,7 +4320,7 @@ var _Computation = class {
|
|
|
3652
4320
|
id: `${this.id}-fragment`,
|
|
3653
4321
|
stage: "compute",
|
|
3654
4322
|
source: this.source,
|
|
3655
|
-
|
|
4323
|
+
debugShaders: this.props.debugShaders
|
|
3656
4324
|
});
|
|
3657
4325
|
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
3658
4326
|
...this.props,
|
|
@@ -3668,33 +4336,33 @@ var _Computation = class {
|
|
|
3668
4336
|
_lastLogTime = 0;
|
|
3669
4337
|
_logOpen = false;
|
|
3670
4338
|
_logDrawCallStart() {
|
|
3671
|
-
const logDrawTimeout =
|
|
3672
|
-
if (
|
|
4339
|
+
const logDrawTimeout = import_core14.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
4340
|
+
if (import_core14.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
3673
4341
|
return;
|
|
3674
4342
|
}
|
|
3675
4343
|
this._lastLogTime = Date.now();
|
|
3676
4344
|
this._logOpen = true;
|
|
3677
|
-
|
|
4345
|
+
import_core14.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core14.log.level <= 2 })();
|
|
3678
4346
|
}
|
|
3679
4347
|
_logDrawCallEnd() {
|
|
3680
4348
|
if (this._logOpen) {
|
|
3681
4349
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
3682
|
-
|
|
3683
|
-
|
|
4350
|
+
import_core14.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
4351
|
+
import_core14.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
3684
4352
|
this._logOpen = false;
|
|
3685
4353
|
}
|
|
3686
4354
|
}
|
|
3687
4355
|
_drawCount = 0;
|
|
3688
4356
|
// TODO - fix typing of luma data types
|
|
3689
4357
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
3690
|
-
const TypedArrayConstructor = (0,
|
|
3691
|
-
const typedArray = attribute instanceof
|
|
4358
|
+
const TypedArrayConstructor = (0, import_core14.getTypedArrayFromDataType)(dataType);
|
|
4359
|
+
const typedArray = attribute instanceof import_core14.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
3692
4360
|
return typedArray.toString();
|
|
3693
4361
|
}
|
|
3694
4362
|
};
|
|
3695
4363
|
var Computation = _Computation;
|
|
3696
4364
|
__publicField(Computation, "defaultProps", {
|
|
3697
|
-
...
|
|
4365
|
+
...import_core14.ComputePipeline.defaultProps,
|
|
3698
4366
|
id: "unnamed",
|
|
3699
4367
|
handle: void 0,
|
|
3700
4368
|
userData: {},
|
|
@@ -3705,7 +4373,7 @@ __publicField(Computation, "defaultProps", {
|
|
|
3705
4373
|
shaderInputs: void 0,
|
|
3706
4374
|
pipelineFactory: void 0,
|
|
3707
4375
|
shaderFactory: void 0,
|
|
3708
|
-
shaderAssembler:
|
|
4376
|
+
shaderAssembler: import_shadertools6.ShaderAssembler.getDefaultShaderAssembler(),
|
|
3709
4377
|
debugShaders: void 0
|
|
3710
4378
|
});
|
|
3711
4379
|
function getPlatformInfo2(device) {
|
|
@@ -3718,4 +4386,543 @@ function getPlatformInfo2(device) {
|
|
|
3718
4386
|
features: device.features
|
|
3719
4387
|
};
|
|
3720
4388
|
}
|
|
4389
|
+
|
|
4390
|
+
// dist/modules/picking/picking-uniforms.js
|
|
4391
|
+
var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
|
|
4392
|
+
var INVALID_INDEX = -1;
|
|
4393
|
+
var uniformTypes = {
|
|
4394
|
+
isActive: "i32",
|
|
4395
|
+
indexMode: "i32",
|
|
4396
|
+
batchIndex: "i32",
|
|
4397
|
+
isHighlightActive: "i32",
|
|
4398
|
+
highlightedBatchIndex: "i32",
|
|
4399
|
+
highlightedObjectIndex: "i32",
|
|
4400
|
+
highlightColor: "vec4<f32>"
|
|
4401
|
+
};
|
|
4402
|
+
var GLSL_UNIFORMS = (
|
|
4403
|
+
/* glsl */
|
|
4404
|
+
`precision highp float;
|
|
4405
|
+
precision highp int;
|
|
4406
|
+
|
|
4407
|
+
uniform pickingUniforms {
|
|
4408
|
+
int isActive;
|
|
4409
|
+
int indexMode;
|
|
4410
|
+
int batchIndex;
|
|
4411
|
+
|
|
4412
|
+
int isHighlightActive;
|
|
4413
|
+
int highlightedBatchIndex;
|
|
4414
|
+
int highlightedObjectIndex;
|
|
4415
|
+
vec4 highlightColor;
|
|
4416
|
+
} picking;
|
|
4417
|
+
`
|
|
4418
|
+
);
|
|
4419
|
+
var WGSL_UNIFORMS = (
|
|
4420
|
+
/* wgsl */
|
|
4421
|
+
`struct pickingUniforms {
|
|
4422
|
+
isActive: int32;
|
|
4423
|
+
indexMode: int32;
|
|
4424
|
+
batchIndex: int32;
|
|
4425
|
+
|
|
4426
|
+
isHighlightActive: int32;
|
|
4427
|
+
highlightedBatchIndex: int32;
|
|
4428
|
+
highlightedObjectIndex: int32;
|
|
4429
|
+
highlightColor: vec4<f32>;
|
|
4430
|
+
} picking;
|
|
4431
|
+
`
|
|
4432
|
+
);
|
|
4433
|
+
function getUniforms(props = {}, prevUniforms) {
|
|
4434
|
+
const uniforms = { ...prevUniforms };
|
|
4435
|
+
if (props.isActive !== void 0) {
|
|
4436
|
+
uniforms.isActive = Boolean(props.isActive);
|
|
4437
|
+
}
|
|
4438
|
+
switch (props.indexMode) {
|
|
4439
|
+
case "instance":
|
|
4440
|
+
uniforms.indexMode = 0;
|
|
4441
|
+
break;
|
|
4442
|
+
case "custom":
|
|
4443
|
+
uniforms.indexMode = 1;
|
|
4444
|
+
break;
|
|
4445
|
+
case void 0:
|
|
4446
|
+
break;
|
|
4447
|
+
}
|
|
4448
|
+
switch (props.highlightedObjectIndex) {
|
|
4449
|
+
case void 0:
|
|
4450
|
+
break;
|
|
4451
|
+
case null:
|
|
4452
|
+
uniforms.isHighlightActive = false;
|
|
4453
|
+
uniforms.highlightedObjectIndex = INVALID_INDEX;
|
|
4454
|
+
break;
|
|
4455
|
+
default:
|
|
4456
|
+
uniforms.isHighlightActive = true;
|
|
4457
|
+
uniforms.highlightedObjectIndex = props.highlightedObjectIndex;
|
|
4458
|
+
}
|
|
4459
|
+
if (typeof props.highlightedBatchIndex === "number") {
|
|
4460
|
+
uniforms.highlightedBatchIndex = props.highlightedBatchIndex;
|
|
4461
|
+
}
|
|
4462
|
+
if (props.highlightColor) {
|
|
4463
|
+
uniforms.highlightColor = props.highlightColor;
|
|
4464
|
+
}
|
|
4465
|
+
return uniforms;
|
|
4466
|
+
}
|
|
4467
|
+
var pickingUniforms = {
|
|
4468
|
+
props: {},
|
|
4469
|
+
uniforms: {},
|
|
4470
|
+
name: "picking",
|
|
4471
|
+
uniformTypes,
|
|
4472
|
+
defaultUniforms: {
|
|
4473
|
+
isActive: false,
|
|
4474
|
+
indexMode: 0,
|
|
4475
|
+
batchIndex: 0,
|
|
4476
|
+
isHighlightActive: true,
|
|
4477
|
+
highlightedBatchIndex: INVALID_INDEX,
|
|
4478
|
+
highlightedObjectIndex: INVALID_INDEX,
|
|
4479
|
+
highlightColor: DEFAULT_HIGHLIGHT_COLOR
|
|
4480
|
+
},
|
|
4481
|
+
getUniforms
|
|
4482
|
+
};
|
|
4483
|
+
|
|
4484
|
+
// dist/modules/picking/picking-manager.js
|
|
4485
|
+
var _PickingManager = class {
|
|
4486
|
+
device;
|
|
4487
|
+
props;
|
|
4488
|
+
/** Info from latest pick operation */
|
|
4489
|
+
pickInfo = { batchIndex: null, objectIndex: null };
|
|
4490
|
+
/** Framebuffer used for picking */
|
|
4491
|
+
framebuffer = null;
|
|
4492
|
+
constructor(device, props) {
|
|
4493
|
+
this.device = device;
|
|
4494
|
+
this.props = { ..._PickingManager.defaultProps, ...props };
|
|
4495
|
+
}
|
|
4496
|
+
destroy() {
|
|
4497
|
+
var _a;
|
|
4498
|
+
(_a = this.framebuffer) == null ? void 0 : _a.destroy();
|
|
4499
|
+
}
|
|
4500
|
+
// TODO - Ask for a cached framebuffer? a Framebuffer factory?
|
|
4501
|
+
getFramebuffer() {
|
|
4502
|
+
if (!this.framebuffer) {
|
|
4503
|
+
this.framebuffer = this.device.createFramebuffer({
|
|
4504
|
+
colorAttachments: ["rgba8unorm", "rg32sint"],
|
|
4505
|
+
depthStencilAttachment: "depth24plus"
|
|
4506
|
+
});
|
|
4507
|
+
}
|
|
4508
|
+
return this.framebuffer;
|
|
4509
|
+
}
|
|
4510
|
+
/** Clear highlighted / picked object */
|
|
4511
|
+
clearPickState() {
|
|
4512
|
+
this.props.shaderInputs.setProps({ picking: { highlightedObjectIndex: null } });
|
|
4513
|
+
}
|
|
4514
|
+
/** Prepare for rendering picking colors */
|
|
4515
|
+
beginRenderPass() {
|
|
4516
|
+
var _a;
|
|
4517
|
+
const framebuffer = this.getFramebuffer();
|
|
4518
|
+
framebuffer.resize(this.device.getDefaultCanvasContext().getPixelSize());
|
|
4519
|
+
(_a = this.props.shaderInputs) == null ? void 0 : _a.setProps({ picking: { isActive: true } });
|
|
4520
|
+
const pickingPass = this.device.beginRenderPass({
|
|
4521
|
+
framebuffer,
|
|
4522
|
+
clearColors: [new Float32Array([0, 0, 0, 0]), new Int32Array([-1, -1, 0, 0])],
|
|
4523
|
+
clearDepth: 1
|
|
4524
|
+
});
|
|
4525
|
+
return pickingPass;
|
|
4526
|
+
}
|
|
4527
|
+
getPickInfo(mousePosition) {
|
|
4528
|
+
var _a;
|
|
4529
|
+
const framebuffer = this.getFramebuffer();
|
|
4530
|
+
const [pickX, pickY] = this.getPickPosition(mousePosition);
|
|
4531
|
+
const pixelData = this.device.readPixelsToArrayWebGL(framebuffer, {
|
|
4532
|
+
sourceX: pickX,
|
|
4533
|
+
sourceY: pickY,
|
|
4534
|
+
sourceWidth: 1,
|
|
4535
|
+
sourceHeight: 1,
|
|
4536
|
+
sourceAttachment: 1
|
|
4537
|
+
});
|
|
4538
|
+
if (!pixelData) {
|
|
4539
|
+
return null;
|
|
4540
|
+
}
|
|
4541
|
+
const pickInfo = {
|
|
4542
|
+
objectIndex: pixelData[0] === INVALID_INDEX ? null : pixelData[0],
|
|
4543
|
+
batchIndex: pixelData[1] === INVALID_INDEX ? null : pixelData[1]
|
|
4544
|
+
};
|
|
4545
|
+
if (pickInfo.objectIndex !== this.pickInfo.objectIndex || pickInfo.batchIndex !== this.pickInfo.batchIndex) {
|
|
4546
|
+
this.pickInfo = pickInfo;
|
|
4547
|
+
this.props.onObjectPicked(pickInfo);
|
|
4548
|
+
}
|
|
4549
|
+
(_a = this.props.shaderInputs) == null ? void 0 : _a.setProps({
|
|
4550
|
+
picking: {
|
|
4551
|
+
isActive: false,
|
|
4552
|
+
highlightedBatchIndex: pickInfo.batchIndex,
|
|
4553
|
+
highlightedObjectIndex: pickInfo.objectIndex
|
|
4554
|
+
}
|
|
4555
|
+
});
|
|
4556
|
+
return this.pickInfo;
|
|
4557
|
+
}
|
|
4558
|
+
/**
|
|
4559
|
+
* Get pick position in device pixel range
|
|
4560
|
+
* use the center pixel location in device pixel range
|
|
4561
|
+
*/
|
|
4562
|
+
getPickPosition(mousePosition) {
|
|
4563
|
+
const devicePixels = this.device.getDefaultCanvasContext().cssToDevicePixels(mousePosition);
|
|
4564
|
+
const pickX = devicePixels.x + Math.floor(devicePixels.width / 2);
|
|
4565
|
+
const pickY = devicePixels.y + Math.floor(devicePixels.height / 2);
|
|
4566
|
+
return [pickX, pickY];
|
|
4567
|
+
}
|
|
4568
|
+
};
|
|
4569
|
+
var PickingManager = _PickingManager;
|
|
4570
|
+
__publicField(PickingManager, "defaultProps", {
|
|
4571
|
+
shaderInputs: void 0,
|
|
4572
|
+
onObjectPicked: () => {
|
|
4573
|
+
}
|
|
4574
|
+
});
|
|
4575
|
+
|
|
4576
|
+
// dist/modules/picking/index-picking.js
|
|
4577
|
+
var source = (
|
|
4578
|
+
/* wgsl */
|
|
4579
|
+
`${WGSL_UNIFORMS}
|
|
4580
|
+
|
|
4581
|
+
const INDEX_PICKING_MODE_INSTANCE = 0;
|
|
4582
|
+
const INDEX_PICKING_MODE_CUSTOM = 1;
|
|
4583
|
+
const INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
4584
|
+
|
|
4585
|
+
struct indexPickingFragmentInputs = {
|
|
4586
|
+
objectIndex: int32;
|
|
4587
|
+
};
|
|
4588
|
+
|
|
4589
|
+
let indexPickingFragmentInputs: indexPickingFragmentInputs;
|
|
4590
|
+
|
|
4591
|
+
/**
|
|
4592
|
+
* Vertex shaders should call this function to set the object index.
|
|
4593
|
+
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|
|
4594
|
+
*/
|
|
4595
|
+
fn picking_setObjectIndex(objectIndex: int32) {
|
|
4596
|
+
switch (picking.indexMode) {
|
|
4597
|
+
case INDEX_PICKING_MODE_INSTANCE, default: {
|
|
4598
|
+
picking_objectIndex = instance_index;
|
|
4599
|
+
};
|
|
4600
|
+
case INDEX_PICKING_MODE_CUSTOM: {
|
|
4601
|
+
picking_objectIndex = objectIndex;
|
|
4602
|
+
};
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
4605
|
+
|
|
4606
|
+
`
|
|
4607
|
+
);
|
|
4608
|
+
var vs = (
|
|
4609
|
+
/* glsl */
|
|
4610
|
+
`${GLSL_UNIFORMS}
|
|
4611
|
+
|
|
4612
|
+
const int INDEX_PICKING_MODE_INSTANCE = 0;
|
|
4613
|
+
const int INDEX_PICKING_MODE_CUSTOM = 1;
|
|
4614
|
+
|
|
4615
|
+
const int INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
4616
|
+
|
|
4617
|
+
flat out int picking_objectIndex;
|
|
4618
|
+
|
|
4619
|
+
/**
|
|
4620
|
+
* Vertex shaders should call this function to set the object index.
|
|
4621
|
+
* If using instance or vertex mode, argument will be ignored, 0 can be supplied.
|
|
4622
|
+
*/
|
|
4623
|
+
void picking_setObjectIndex(int objectIndex) {
|
|
4624
|
+
switch (picking.indexMode) {
|
|
4625
|
+
case INDEX_PICKING_MODE_INSTANCE:
|
|
4626
|
+
picking_objectIndex = gl_InstanceID;
|
|
4627
|
+
break;
|
|
4628
|
+
case INDEX_PICKING_MODE_CUSTOM:
|
|
4629
|
+
picking_objectIndex = objectIndex;
|
|
4630
|
+
break;
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
`
|
|
4634
|
+
);
|
|
4635
|
+
var fs = (
|
|
4636
|
+
/* glsl */
|
|
4637
|
+
`${GLSL_UNIFORMS}
|
|
4638
|
+
|
|
4639
|
+
const int INDEX_PICKING_INVALID_INDEX = ${INVALID_INDEX}; // 2^32 - 1
|
|
4640
|
+
|
|
4641
|
+
flat in int picking_objectIndex;
|
|
4642
|
+
|
|
4643
|
+
/**
|
|
4644
|
+
* Check if this vertex is highlighted (part of the selected batch and object)
|
|
4645
|
+
*/
|
|
4646
|
+
bool picking_isFragmentHighlighted() {
|
|
4647
|
+
return
|
|
4648
|
+
bool(picking.isHighlightActive) &&
|
|
4649
|
+
picking.highlightedBatchIndex == picking.batchIndex &&
|
|
4650
|
+
picking.highlightedObjectIndex == picking_objectIndex
|
|
4651
|
+
;
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4654
|
+
/**
|
|
4655
|
+
* Returns highlight color if this item is selected.
|
|
4656
|
+
*/
|
|
4657
|
+
vec4 picking_filterHighlightColor(vec4 color) {
|
|
4658
|
+
// If we are still picking, we don't highlight
|
|
4659
|
+
if (bool(picking.isActive)) {
|
|
4660
|
+
return color;
|
|
4661
|
+
}
|
|
4662
|
+
|
|
4663
|
+
// If we are not highlighted, return color as is
|
|
4664
|
+
if (!picking_isFragmentHighlighted()) {
|
|
4665
|
+
return color;
|
|
4666
|
+
}
|
|
4667
|
+
|
|
4668
|
+
// Blend in highlight color based on its alpha value
|
|
4669
|
+
float highLightAlpha = picking.highlightColor.a;
|
|
4670
|
+
float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);
|
|
4671
|
+
float highLightRatio = highLightAlpha / blendedAlpha;
|
|
4672
|
+
|
|
4673
|
+
vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);
|
|
4674
|
+
return vec4(blendedRGB, blendedAlpha);
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4677
|
+
/*
|
|
4678
|
+
* Returns picking color if picking enabled else unmodified argument.
|
|
4679
|
+
*/
|
|
4680
|
+
ivec4 picking_getPickingColor() {
|
|
4681
|
+
// Assumes that colorAttachment0 is rg32int
|
|
4682
|
+
// TODO? - we could render indices into a second color attachment and not mess with fragColor
|
|
4683
|
+
return ivec4(picking_objectIndex, picking.batchIndex, 0u, 0u);
|
|
4684
|
+
}
|
|
4685
|
+
|
|
4686
|
+
vec4 picking_filterPickingColor(vec4 color) {
|
|
4687
|
+
if (bool(picking.isActive)) {
|
|
4688
|
+
if (picking_objectIndex == INDEX_PICKING_INVALID_INDEX) {
|
|
4689
|
+
discard;
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
return color;
|
|
4693
|
+
}
|
|
4694
|
+
|
|
4695
|
+
/*
|
|
4696
|
+
* Returns picking color if picking is enabled if not
|
|
4697
|
+
* highlight color if this item is selected, otherwise unmodified argument.
|
|
4698
|
+
*/
|
|
4699
|
+
vec4 picking_filterColor(vec4 color) {
|
|
4700
|
+
vec4 outColor = color;
|
|
4701
|
+
outColor = picking_filterHighlightColor(outColor);
|
|
4702
|
+
outColor = picking_filterPickingColor(outColor);
|
|
4703
|
+
return outColor;
|
|
4704
|
+
}
|
|
4705
|
+
`
|
|
4706
|
+
);
|
|
4707
|
+
var picking = {
|
|
4708
|
+
...pickingUniforms,
|
|
4709
|
+
name: "picking",
|
|
4710
|
+
source,
|
|
4711
|
+
vs,
|
|
4712
|
+
fs
|
|
4713
|
+
};
|
|
4714
|
+
|
|
4715
|
+
// dist/modules/picking/color-picking.js
|
|
4716
|
+
var source2 = (
|
|
4717
|
+
/* wgsl */
|
|
4718
|
+
`${WGSL_UNIFORMS}
|
|
4719
|
+
`
|
|
4720
|
+
);
|
|
4721
|
+
var vs2 = (
|
|
4722
|
+
/* glsl */
|
|
4723
|
+
`${GLSL_UNIFORMS}
|
|
4724
|
+
out vec4 picking_vRGBcolor_Avalid;
|
|
4725
|
+
|
|
4726
|
+
// Normalize unsigned byte color to 0-1 range
|
|
4727
|
+
vec3 picking_normalizeColor(vec3 color) {
|
|
4728
|
+
return picking.useFloatColors > 0.5 ? color : color / 255.0;
|
|
4729
|
+
}
|
|
4730
|
+
|
|
4731
|
+
// Normalize unsigned byte color to 0-1 range
|
|
4732
|
+
vec4 picking_normalizeColor(vec4 color) {
|
|
4733
|
+
return picking.useFloatColors > 0.5 ? color : color / 255.0;
|
|
4734
|
+
}
|
|
4735
|
+
|
|
4736
|
+
bool picking_isColorZero(vec3 color) {
|
|
4737
|
+
return dot(color, vec3(1.0)) < 0.00001;
|
|
4738
|
+
}
|
|
4739
|
+
|
|
4740
|
+
bool picking_isColorValid(vec3 color) {
|
|
4741
|
+
return dot(color, vec3(1.0)) > 0.00001;
|
|
4742
|
+
}
|
|
4743
|
+
|
|
4744
|
+
// Check if this vertex is highlighted
|
|
4745
|
+
bool isVertexHighlighted(vec3 vertexColor) {
|
|
4746
|
+
vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor);
|
|
4747
|
+
return
|
|
4748
|
+
bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor));
|
|
4749
|
+
}
|
|
4750
|
+
|
|
4751
|
+
// Set the current picking color
|
|
4752
|
+
void picking_setPickingColor(vec3 pickingColor) {
|
|
4753
|
+
pickingColor = picking_normalizeColor(pickingColor);
|
|
4754
|
+
|
|
4755
|
+
if (bool(picking.isActive)) {
|
|
4756
|
+
// Use alpha as the validity flag. If pickingColor is [0, 0, 0] fragment is non-pickable
|
|
4757
|
+
picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor));
|
|
4758
|
+
|
|
4759
|
+
if (!bool(picking.isAttribute)) {
|
|
4760
|
+
// Stores the picking color so that the fragment shader can render it during picking
|
|
4761
|
+
picking_vRGBcolor_Avalid.rgb = pickingColor;
|
|
4762
|
+
}
|
|
4763
|
+
} else {
|
|
4764
|
+
// Do the comparison with selected item color in vertex shader as it should mean fewer compares
|
|
4765
|
+
picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor));
|
|
4766
|
+
}
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4769
|
+
void picking_setObjectIndex(uint objectIndex) {
|
|
4770
|
+
if (bool(picking.isActive)) {
|
|
4771
|
+
uint index = objectIndex;
|
|
4772
|
+
if (picking.indexMode == PICKING_INDEX_MODE_INSTANCE) {
|
|
4773
|
+
index = uint(gl_InstanceID);
|
|
4774
|
+
}
|
|
4775
|
+
picking_vRGBcolor_Avalid.r = float(index % 255) / 255.0;
|
|
4776
|
+
picking_vRGBcolor_Avalid.g = float((index / 255) % 255) / 255.0;
|
|
4777
|
+
picking_vRGBcolor_Avalid.b = float((index / 255 / 255) %255) / 255.0;
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
|
|
4781
|
+
void picking_setPickingAttribute(float value) {
|
|
4782
|
+
if (bool(picking.isAttribute)) {
|
|
4783
|
+
picking_vRGBcolor_Avalid.r = value;
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
|
|
4787
|
+
void picking_setPickingAttribute(vec2 value) {
|
|
4788
|
+
if (bool(picking.isAttribute)) {
|
|
4789
|
+
picking_vRGBcolor_Avalid.rg = value;
|
|
4790
|
+
}
|
|
4791
|
+
}
|
|
4792
|
+
|
|
4793
|
+
void picking_setPickingAttribute(vec3 value) {
|
|
4794
|
+
if (bool(picking.isAttribute)) {
|
|
4795
|
+
picking_vRGBcolor_Avalid.rgb = value;
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
`
|
|
4799
|
+
);
|
|
4800
|
+
var fs2 = (
|
|
4801
|
+
/* glsl */
|
|
4802
|
+
`${GLSL_UNIFORMS}
|
|
4803
|
+
|
|
4804
|
+
in vec4 picking_vRGBcolor_Avalid;
|
|
4805
|
+
|
|
4806
|
+
/*
|
|
4807
|
+
* Returns highlight color if this item is selected.
|
|
4808
|
+
*/
|
|
4809
|
+
vec4 picking_filterHighlightColor(vec4 color) {
|
|
4810
|
+
// If we are still picking, we don't highlight
|
|
4811
|
+
if (picking.isActive > 0.5) {
|
|
4812
|
+
return color;
|
|
4813
|
+
}
|
|
4814
|
+
|
|
4815
|
+
bool selected = bool(picking_vRGBcolor_Avalid.a);
|
|
4816
|
+
|
|
4817
|
+
if (selected) {
|
|
4818
|
+
// Blend in highlight color based on its alpha value
|
|
4819
|
+
float highLightAlpha = picking.highlightColor.a;
|
|
4820
|
+
float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);
|
|
4821
|
+
float highLightRatio = highLightAlpha / blendedAlpha;
|
|
4822
|
+
|
|
4823
|
+
vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);
|
|
4824
|
+
return vec4(blendedRGB, blendedAlpha);
|
|
4825
|
+
} else {
|
|
4826
|
+
return color;
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4829
|
+
|
|
4830
|
+
/*
|
|
4831
|
+
* Returns picking color if picking enabled else unmodified argument.
|
|
4832
|
+
*/
|
|
4833
|
+
vec4 picking_filterPickingColor(vec4 color) {
|
|
4834
|
+
if (bool(picking.isActive)) {
|
|
4835
|
+
if (picking_vRGBcolor_Avalid.a == 0.0) {
|
|
4836
|
+
discard;
|
|
4837
|
+
}
|
|
4838
|
+
return picking_vRGBcolor_Avalid;
|
|
4839
|
+
}
|
|
4840
|
+
return color;
|
|
4841
|
+
}
|
|
4842
|
+
|
|
4843
|
+
/*
|
|
4844
|
+
* Returns picking color if picking is enabled if not
|
|
4845
|
+
* highlight color if this item is selected, otherwise unmodified argument.
|
|
4846
|
+
*/
|
|
4847
|
+
vec4 picking_filterColor(vec4 color) {
|
|
4848
|
+
vec4 highlightColor = picking_filterHighlightColor(color);
|
|
4849
|
+
return picking_filterPickingColor(highlightColor);
|
|
4850
|
+
}
|
|
4851
|
+
`
|
|
4852
|
+
);
|
|
4853
|
+
var picking2 = {
|
|
4854
|
+
...pickingUniforms,
|
|
4855
|
+
name: "picking",
|
|
4856
|
+
source: source2,
|
|
4857
|
+
vs: vs2,
|
|
4858
|
+
fs: fs2
|
|
4859
|
+
};
|
|
4860
|
+
|
|
4861
|
+
// dist/modules/picking/legacy-picking-manager.js
|
|
4862
|
+
var LegacyPickingManager = class {
|
|
4863
|
+
device;
|
|
4864
|
+
framebuffer = null;
|
|
4865
|
+
shaderInputs;
|
|
4866
|
+
constructor(device, shaderInputs) {
|
|
4867
|
+
this.device = device;
|
|
4868
|
+
this.shaderInputs = shaderInputs;
|
|
4869
|
+
}
|
|
4870
|
+
destroy() {
|
|
4871
|
+
var _a;
|
|
4872
|
+
(_a = this.framebuffer) == null ? void 0 : _a.destroy();
|
|
4873
|
+
}
|
|
4874
|
+
getFramebuffer() {
|
|
4875
|
+
if (!this.framebuffer) {
|
|
4876
|
+
this.framebuffer = this.device.createFramebuffer({
|
|
4877
|
+
colorAttachments: ["rgba8unorm"],
|
|
4878
|
+
depthStencilAttachment: "depth24plus"
|
|
4879
|
+
});
|
|
4880
|
+
}
|
|
4881
|
+
return this.framebuffer;
|
|
4882
|
+
}
|
|
4883
|
+
/** Clear highlighted / picked object */
|
|
4884
|
+
clearPickState() {
|
|
4885
|
+
this.shaderInputs.setProps({ picking: { highlightedObjectColor: null } });
|
|
4886
|
+
}
|
|
4887
|
+
/** Prepare for rendering picking colors */
|
|
4888
|
+
beginRenderPass() {
|
|
4889
|
+
const framebuffer = this.getFramebuffer();
|
|
4890
|
+
framebuffer.resize(this.device.getCanvasContext().getPixelSize());
|
|
4891
|
+
this.shaderInputs.setProps({ picking: { isActive: true } });
|
|
4892
|
+
const pickingPass = this.device.beginRenderPass({
|
|
4893
|
+
framebuffer,
|
|
4894
|
+
clearColor: [0, 0, 0, 0],
|
|
4895
|
+
clearDepth: 1
|
|
4896
|
+
});
|
|
4897
|
+
return pickingPass;
|
|
4898
|
+
}
|
|
4899
|
+
updatePickState(mousePosition) {
|
|
4900
|
+
const framebuffer = this.getFramebuffer();
|
|
4901
|
+
const [pickX, pickY] = this.getPickPosition(mousePosition);
|
|
4902
|
+
const color255 = this.device.readPixelsToArrayWebGL(framebuffer, {
|
|
4903
|
+
sourceX: pickX,
|
|
4904
|
+
sourceY: pickY,
|
|
4905
|
+
sourceWidth: 1,
|
|
4906
|
+
sourceHeight: 1
|
|
4907
|
+
});
|
|
4908
|
+
let highlightedObjectColor = [...color255].map((x) => x / 255);
|
|
4909
|
+
const isHighlightActive = highlightedObjectColor[0] + highlightedObjectColor[1] + highlightedObjectColor[2] > 0;
|
|
4910
|
+
if (!isHighlightActive) {
|
|
4911
|
+
highlightedObjectColor = null;
|
|
4912
|
+
}
|
|
4913
|
+
this.shaderInputs.setProps({
|
|
4914
|
+
picking: { isActive: false, highlightedObjectColor }
|
|
4915
|
+
});
|
|
4916
|
+
}
|
|
4917
|
+
/**
|
|
4918
|
+
* Get pick position in device pixel range
|
|
4919
|
+
* use the center pixel location in device pixel range
|
|
4920
|
+
*/
|
|
4921
|
+
getPickPosition(mousePosition) {
|
|
4922
|
+
const devicePixels = this.device.getCanvasContext().cssToDevicePixels(mousePosition);
|
|
4923
|
+
const pickX = devicePixels.x + Math.floor(devicePixels.width / 2);
|
|
4924
|
+
const pickY = devicePixels.y + Math.floor(devicePixels.height / 2);
|
|
4925
|
+
return [pickX, pickY];
|
|
4926
|
+
}
|
|
4927
|
+
};
|
|
3721
4928
|
//# sourceMappingURL=index.cjs.map
|