@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
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {luma, Device} from '@luma.gl/core';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
requestAnimationFramePolyfill,
|
|
8
|
+
cancelAnimationFramePolyfill
|
|
9
|
+
} from './request-animation-frame';
|
|
7
10
|
import {Timeline} from '../animation/timeline';
|
|
8
11
|
import {AnimationProps} from './animation-props';
|
|
9
12
|
import {Stats, Stat} from '@probe.gl/stats';
|
|
@@ -77,6 +80,7 @@ export class AnimationLoop {
|
|
|
77
80
|
_nextFramePromise: Promise<AnimationLoop> | null = null;
|
|
78
81
|
_resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;
|
|
79
82
|
_cpuStartTime: number = 0;
|
|
83
|
+
_error: Error | null = null;
|
|
80
84
|
|
|
81
85
|
// _gpuTimeQuery: Query | null = null;
|
|
82
86
|
|
|
@@ -123,6 +127,23 @@ export class AnimationLoop {
|
|
|
123
127
|
this.destroy();
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
setError(error: Error): void {
|
|
131
|
+
this.props.onError(error);
|
|
132
|
+
this._error = Error();
|
|
133
|
+
const canvas = this.device?.canvasContext?.canvas;
|
|
134
|
+
if (canvas instanceof HTMLCanvasElement) {
|
|
135
|
+
const errorDiv = document.createElement('h1');
|
|
136
|
+
errorDiv.innerHTML = error.message;
|
|
137
|
+
errorDiv.style.position = 'absolute';
|
|
138
|
+
errorDiv.style.top = '20%'; // left: 50%; transform: translate(-50%, -50%);';
|
|
139
|
+
errorDiv.style.left = '10px';
|
|
140
|
+
errorDiv.style.color = 'black';
|
|
141
|
+
errorDiv.style.backgroundColor = 'red';
|
|
142
|
+
document.body.appendChild(errorDiv);
|
|
143
|
+
// canvas.style.position = 'absolute';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
126
147
|
/** Flags this animation loop as needing redraw */
|
|
127
148
|
setNeedsRedraw(reason: string): this {
|
|
128
149
|
this.needsRedraw = this.needsRedraw || reason;
|
|
@@ -189,7 +210,7 @@ export class AnimationLoop {
|
|
|
189
210
|
if (this._running) {
|
|
190
211
|
// call callback
|
|
191
212
|
// If stop is called immediately, we can end up in a state where props haven't been initialized...
|
|
192
|
-
if (this.animationProps) {
|
|
213
|
+
if (this.animationProps && !this._error) {
|
|
193
214
|
this.props.onFinalize(this.animationProps);
|
|
194
215
|
}
|
|
195
216
|
|
|
@@ -203,7 +224,7 @@ export class AnimationLoop {
|
|
|
203
224
|
|
|
204
225
|
/** Explicitly draw a frame */
|
|
205
226
|
redraw(): this {
|
|
206
|
-
if (this.device?.isLost) {
|
|
227
|
+
if (this.device?.isLost || this._error) {
|
|
207
228
|
return this;
|
|
208
229
|
}
|
|
209
230
|
|
|
@@ -302,7 +323,7 @@ export class AnimationLoop {
|
|
|
302
323
|
// if (this.display && this.display.requestAnimationFrame) {
|
|
303
324
|
// this._animationFrameId = this.display.requestAnimationFrame(this._animationFrame.bind(this));
|
|
304
325
|
// }
|
|
305
|
-
this._animationFrameId =
|
|
326
|
+
this._animationFrameId = requestAnimationFramePolyfill(this._animationFrame.bind(this));
|
|
306
327
|
}
|
|
307
328
|
|
|
308
329
|
_cancelAnimationFrame(): void {
|
|
@@ -313,10 +334,10 @@ export class AnimationLoop {
|
|
|
313
334
|
// VR display has a separate animation frame to sync with headset
|
|
314
335
|
// TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/
|
|
315
336
|
// See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame
|
|
316
|
-
// if (this.display && this.display.
|
|
337
|
+
// if (this.display && this.display.cancelAnimationFramePolyfill) {
|
|
317
338
|
// this.display.cancelAnimationFrame(this._animationFrameId);
|
|
318
339
|
// }
|
|
319
|
-
|
|
340
|
+
cancelAnimationFramePolyfill(this._animationFrameId);
|
|
320
341
|
this._animationFrameId = null;
|
|
321
342
|
}
|
|
322
343
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {luma} from '@luma.gl/core';
|
|
5
|
+
import {luma, Adapter} from '@luma.gl/core';
|
|
6
6
|
import {AnimationLoopTemplate} from './animation-loop-template';
|
|
7
7
|
import {AnimationLoop, AnimationLoopProps} from './animation-loop';
|
|
8
8
|
import type {AnimationProps} from './animation-props';
|
|
@@ -10,7 +10,10 @@ import type {AnimationProps} from './animation-props';
|
|
|
10
10
|
export type MakeAnimationLoopProps = Omit<
|
|
11
11
|
AnimationLoopProps,
|
|
12
12
|
'onCreateDevice' | 'onInitialize' | 'onRedraw' | 'onFinalize'
|
|
13
|
-
|
|
13
|
+
> & {
|
|
14
|
+
/** List of adapters to use when creating the device */
|
|
15
|
+
adapters?: Adapter[];
|
|
16
|
+
};
|
|
14
17
|
|
|
15
18
|
/** Instantiates and runs the render loop */
|
|
16
19
|
export function makeAnimationLoop(
|
|
@@ -19,7 +22,9 @@ export function makeAnimationLoop(
|
|
|
19
22
|
): AnimationLoop {
|
|
20
23
|
let renderLoop: AnimationLoopTemplate | null = null;
|
|
21
24
|
|
|
22
|
-
const device =
|
|
25
|
+
const device =
|
|
26
|
+
props?.device ||
|
|
27
|
+
luma.createDevice({id: 'animation-loop', adapters: props?.adapters, createCanvasContext: true});
|
|
23
28
|
|
|
24
29
|
// Create an animation loop;
|
|
25
30
|
const animationLoop = new AnimationLoop({
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
// Node.js polyfills for requestAnimationFrame and cancelAnimationFrame
|
|
6
5
|
/* global window, setTimeout, clearTimeout */
|
|
7
6
|
|
|
7
|
+
/** Node.js polyfill for requestAnimationFrame */
|
|
8
8
|
// / <reference types="@types/node" />
|
|
9
|
-
export function
|
|
9
|
+
export function requestAnimationFramePolyfill(callback: (time?: any) => void): any {
|
|
10
10
|
return typeof window !== 'undefined' && window.requestAnimationFrame
|
|
11
11
|
? window.requestAnimationFrame(callback)
|
|
12
12
|
: setTimeout(callback, 1000 / 60);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
/** Node.js polyfill for cancelAnimationFrame */
|
|
16
|
+
export function cancelAnimationFramePolyfill(timerId: any): void {
|
|
16
17
|
return typeof window !== 'undefined' && window.cancelAnimationFrame
|
|
17
18
|
? window.cancelAnimationFrame(timerId)
|
|
18
19
|
: clearTimeout(timerId);
|
|
@@ -11,8 +11,6 @@ export function setPathPrefix(prefix: string) {
|
|
|
11
11
|
pathPrefix = prefix;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// TODO - keep only loadImageBitmap
|
|
15
|
-
|
|
16
14
|
/**
|
|
17
15
|
* Loads ImageBitmap asynchronously. Respects setPathPrefix.
|
|
18
16
|
* image.crossOrigin can be set via opts.crossOrigin, default to 'anonymous'
|
|
@@ -20,13 +18,13 @@ export function setPathPrefix(prefix: string) {
|
|
|
20
18
|
*/
|
|
21
19
|
export async function loadImageBitmap(
|
|
22
20
|
url: string,
|
|
23
|
-
opts?: {crossOrigin?: string}
|
|
21
|
+
opts?: {crossOrigin?: string} & ImageBitmapOptions
|
|
24
22
|
): Promise<ImageBitmap> {
|
|
25
23
|
const image = new Image();
|
|
26
24
|
image.crossOrigin = opts?.crossOrigin || 'anonymous';
|
|
27
25
|
image.src = url.startsWith('http') ? url : pathPrefix + url;
|
|
28
26
|
await image.decode();
|
|
29
|
-
return await createImageBitmap(image);
|
|
27
|
+
return opts ? await createImageBitmap(image, opts) : await createImageBitmap(image);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
/**
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
2
|
// Copyright (c) vis.gl contributors
|
|
3
3
|
|
|
4
|
-
import type {Texture, TextureProps, Sampler, TextureView, Device} from '@luma.gl/core';
|
|
5
|
-
|
|
6
4
|
import type {
|
|
5
|
+
Texture,
|
|
6
|
+
TextureProps,
|
|
7
|
+
Sampler,
|
|
8
|
+
TextureView,
|
|
9
|
+
Device,
|
|
7
10
|
Texture1DData,
|
|
8
11
|
Texture2DData,
|
|
9
12
|
Texture3DData,
|
|
@@ -13,6 +16,7 @@ import type {
|
|
|
13
16
|
} from '@luma.gl/core';
|
|
14
17
|
|
|
15
18
|
import {loadImageBitmap} from '../application-utils/load-file';
|
|
19
|
+
import {uid} from '../utils/uid';
|
|
16
20
|
|
|
17
21
|
export type AsyncTextureProps = Omit<TextureProps, 'data'> & AsyncTextureDataProps;
|
|
18
22
|
|
|
@@ -51,6 +55,7 @@ type AsyncTextureData = AsyncTextureProps['data'];
|
|
|
51
55
|
*/
|
|
52
56
|
export class AsyncTexture {
|
|
53
57
|
readonly device: Device;
|
|
58
|
+
readonly id: string;
|
|
54
59
|
|
|
55
60
|
// TODO - should we type these as possibly `null`? It will make usage harder?
|
|
56
61
|
// @ts-expect-error
|
|
@@ -67,8 +72,18 @@ export class AsyncTexture {
|
|
|
67
72
|
protected resolveReady: () => void = () => {};
|
|
68
73
|
protected rejectReady: (error: Error) => void = () => {};
|
|
69
74
|
|
|
75
|
+
get [Symbol.toStringTag]() {
|
|
76
|
+
return 'AsyncTexture';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
toString(): string {
|
|
80
|
+
return `AsyncTexture:"${this.id}"(${this.isReady ? 'ready' : 'loading'})`;
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
constructor(device: Device, props: AsyncTextureProps) {
|
|
71
84
|
this.device = device;
|
|
85
|
+
this.id = props.id || uid('async-texture');
|
|
86
|
+
// this.id = typeof props?.data === 'string' ? props.data.slice(-20) : uid('async-texture');
|
|
72
87
|
|
|
73
88
|
// Signature: new AsyncTexture(device, {data: url})
|
|
74
89
|
if (typeof props?.data === 'string' && props.dimension === '2d') {
|
|
@@ -117,11 +132,28 @@ export class AsyncTexture {
|
|
|
117
132
|
this.destroyed = true;
|
|
118
133
|
}
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Textures are immutable and cannot be resized after creation,
|
|
137
|
+
* but we can create a similar texture with the same parameters but a new size.
|
|
138
|
+
* @note Does not copy contents of the texture
|
|
139
|
+
* @todo Abort pending promise and create a texture with the new size?
|
|
140
|
+
*/
|
|
141
|
+
resize(size: {width: number; height: number}): boolean {
|
|
142
|
+
if (!this.isReady) {
|
|
143
|
+
throw new Error('Cannot resize texture before it is ready');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (size.width === this.texture.width && size.height === this.texture.height) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (this.texture) {
|
|
151
|
+
const texture = this.texture;
|
|
152
|
+
this.texture = texture.clone(size);
|
|
153
|
+
texture.destroy();
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
125
157
|
}
|
|
126
158
|
|
|
127
159
|
// HELPERS
|
|
@@ -9,28 +9,37 @@ import type {ModelProps} from '../model/model';
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Properties for creating a {@link BufferTransform}
|
|
12
|
-
* @
|
|
12
|
+
* @note Only works under WebGL2.
|
|
13
13
|
*/
|
|
14
14
|
export type BufferTransformProps = Omit<ModelProps, 'fs'> & {
|
|
15
|
+
/** Optional fragment shader - normally not used in transforms */
|
|
15
16
|
fs?: ModelProps['fs']; // override as optional
|
|
17
|
+
/** A list of named outputs corresponding to shader declarations (varyings in WebGL) */
|
|
18
|
+
outputs?: string[];
|
|
19
|
+
/** @deprecated Use run({outputBuffers}) instead - Map of output buffers that the shaders will write results of computations to */
|
|
16
20
|
feedbackBuffers?: Record<string, Buffer | BufferRange>;
|
|
17
21
|
};
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
24
|
+
* Manages a WebGL program (pipeline) for buffer→buffer transforms.
|
|
25
|
+
* @note Only works under WebGL2.
|
|
22
26
|
*/
|
|
23
27
|
export class BufferTransform {
|
|
24
28
|
readonly device: Device;
|
|
25
29
|
readonly model: Model;
|
|
26
30
|
readonly transformFeedback: TransformFeedback;
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
static defaultProps: Required<BufferTransformProps> = {
|
|
33
|
+
...Model.defaultProps,
|
|
34
|
+
outputs: undefined!,
|
|
35
|
+
feedbackBuffers: undefined!
|
|
36
|
+
};
|
|
37
|
+
|
|
29
38
|
static isSupported(device: Device): boolean {
|
|
30
39
|
return device?.info?.type === 'webgl';
|
|
31
40
|
}
|
|
32
41
|
|
|
33
|
-
constructor(device: Device, props: BufferTransformProps =
|
|
42
|
+
constructor(device: Device, props: BufferTransformProps = BufferTransform.defaultProps) {
|
|
34
43
|
if (!BufferTransform.isSupported(device)) {
|
|
35
44
|
throw new Error('BufferTransform not yet implemented on WebGPU');
|
|
36
45
|
}
|
|
@@ -41,6 +50,7 @@ export class BufferTransform {
|
|
|
41
50
|
id: props.id || 'buffer-transform-model',
|
|
42
51
|
fs: props.fs || getPassthroughFS(),
|
|
43
52
|
topology: props.topology || 'point-list',
|
|
53
|
+
varyings: props.outputs || props.varyings,
|
|
44
54
|
...props
|
|
45
55
|
});
|
|
46
56
|
|
|
@@ -68,25 +78,31 @@ export class BufferTransform {
|
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
/** Run one transform loop. */
|
|
71
|
-
run(
|
|
81
|
+
run(
|
|
82
|
+
options?: RenderPassProps & {
|
|
83
|
+
inputBuffers?: Record<string, Buffer>;
|
|
84
|
+
outputBuffers?: Record<string, Buffer>;
|
|
85
|
+
}
|
|
86
|
+
): void {
|
|
87
|
+
if (options?.inputBuffers) {
|
|
88
|
+
this.model.setAttributes(options.inputBuffers);
|
|
89
|
+
}
|
|
90
|
+
if (options?.outputBuffers) {
|
|
91
|
+
this.transformFeedback.setBuffers(options.outputBuffers);
|
|
92
|
+
}
|
|
72
93
|
const renderPass = this.device.beginRenderPass(options);
|
|
73
94
|
this.model.draw(renderPass);
|
|
74
95
|
renderPass.end();
|
|
75
96
|
}
|
|
76
97
|
|
|
77
|
-
|
|
78
|
-
update(...args: any[]): void {
|
|
79
|
-
// TODO(v9): Method should likely be removed for v9. Keeping a method stub
|
|
80
|
-
// to assist with migrating DeckGL usage.
|
|
81
|
-
// eslint-disable-next-line no-console
|
|
82
|
-
console.warn('TextureTransform#update() not implemented');
|
|
83
|
-
}
|
|
98
|
+
// DEPRECATED METHODS
|
|
84
99
|
|
|
85
|
-
/** Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
100
|
+
/** @deprecated App knows what buffers it is passing in - Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
86
101
|
getBuffer(varyingName: string): Buffer | BufferRange | null {
|
|
87
102
|
return this.transformFeedback.getBuffer(varyingName);
|
|
88
103
|
}
|
|
89
104
|
|
|
105
|
+
/** @deprecated App knows what buffers it is passing in - Reads the {@link Buffer} or {@link BufferRange} for given varying name. */
|
|
90
106
|
readAsync(varyingName: string): Promise<Uint8Array> {
|
|
91
107
|
const result = this.getBuffer(varyingName);
|
|
92
108
|
if (!result) {
|
|
@@ -3,16 +3,22 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import type {DeviceFeature, ComputePipelineProps, Shader, Binding} from '@luma.gl/core';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import {
|
|
7
|
+
Device,
|
|
8
|
+
Buffer,
|
|
9
|
+
ComputePipeline,
|
|
10
|
+
ComputePass,
|
|
11
|
+
UniformStore,
|
|
12
|
+
log,
|
|
13
|
+
getTypedArrayFromDataType
|
|
14
|
+
} from '@luma.gl/core';
|
|
9
15
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
10
16
|
import {ShaderAssembler, getShaderLayoutFromWGSL} from '@luma.gl/shadertools';
|
|
11
17
|
import {TypedArray, isNumericArray} from '@math.gl/types';
|
|
12
|
-
import {ShaderInputs} from '
|
|
13
|
-
import {PipelineFactory} from '
|
|
14
|
-
import {ShaderFactory} from '
|
|
15
|
-
import {uid} from '
|
|
18
|
+
import {ShaderInputs} from '../shader-inputs';
|
|
19
|
+
import {PipelineFactory} from '../factories/pipeline-factory';
|
|
20
|
+
import {ShaderFactory} from '../factories/shader-factory';
|
|
21
|
+
import {uid} from '../utils/uid';
|
|
16
22
|
// import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
|
|
17
23
|
|
|
18
24
|
const LOG_DRAW_PRIORITY = 2;
|
|
@@ -282,7 +288,7 @@ export class Computation {
|
|
|
282
288
|
id: `${this.id}-fragment`,
|
|
283
289
|
stage: 'compute',
|
|
284
290
|
source: this.source,
|
|
285
|
-
|
|
291
|
+
debugShaders: this.props.debugShaders
|
|
286
292
|
});
|
|
287
293
|
|
|
288
294
|
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {BufferProps, FramebufferProps} from '@luma.gl/core';
|
|
6
|
+
import {Device, Resource, Buffer, Framebuffer, Texture} from '@luma.gl/core';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Helper class for working with repeated transformations / computations
|
|
10
|
+
* Primarily intended for GPU buffers `Swap<Buffer>` or textures `Swap<Texture>`)
|
|
11
|
+
* @note the two resources are expected to be structurally identical (same size, length, format, etc)
|
|
12
|
+
* @note the two resources can be destroyed by calling `destroy()`
|
|
13
|
+
*/
|
|
14
|
+
export class Swap<T extends Resource<any>> {
|
|
15
|
+
/** The current resource - usually the source for renders or computations */
|
|
16
|
+
current: T;
|
|
17
|
+
/** The next resource - usually the target/destination for transforms / computations */
|
|
18
|
+
next: T;
|
|
19
|
+
|
|
20
|
+
constructor(props: {current: T; next: T}) {
|
|
21
|
+
this.current = props.current;
|
|
22
|
+
this.next = props.next;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Destroys the two managed resources */
|
|
26
|
+
destroy() {
|
|
27
|
+
this.current?.destroy();
|
|
28
|
+
this.next?.destroy();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Make the next resource into the current resource, and reuse the current resource as the next resource */
|
|
32
|
+
swap() {
|
|
33
|
+
const current = this.current;
|
|
34
|
+
this.current = this.next;
|
|
35
|
+
this.next = current;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Helper for managing double-buffered framebuffers */
|
|
40
|
+
export class SwapFramebuffers extends Swap<Framebuffer> {
|
|
41
|
+
constructor(device: Device, props: FramebufferProps) {
|
|
42
|
+
props = {...props};
|
|
43
|
+
|
|
44
|
+
let colorAttachments = props.colorAttachments?.map(colorAttachment =>
|
|
45
|
+
typeof colorAttachment !== 'string'
|
|
46
|
+
? colorAttachment
|
|
47
|
+
: device.createTexture({
|
|
48
|
+
format: colorAttachment,
|
|
49
|
+
usage: Texture.COPY_DST | Texture.RENDER_ATTACHMENT
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const current = device.createFramebuffer({...props, colorAttachments});
|
|
54
|
+
|
|
55
|
+
colorAttachments = props.colorAttachments?.map(colorAttachment =>
|
|
56
|
+
typeof colorAttachment !== 'string'
|
|
57
|
+
? colorAttachment
|
|
58
|
+
: device.createTexture({
|
|
59
|
+
format: colorAttachment,
|
|
60
|
+
usage: Texture.COPY_DST | Texture.RENDER_ATTACHMENT
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const next = device.createFramebuffer({...props, colorAttachments});
|
|
65
|
+
|
|
66
|
+
super({current, next});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resizes the Framebuffers.
|
|
71
|
+
* @returns true if the size changed, otherwise exiting framebuffers were preserved
|
|
72
|
+
* @note any contents are not preserved!
|
|
73
|
+
*/
|
|
74
|
+
resize(size: {width: number; height: number}): boolean {
|
|
75
|
+
if (size.width === this.current.width && size.height === this.current.height) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const {current, next} = this;
|
|
79
|
+
|
|
80
|
+
this.current = current.clone(size);
|
|
81
|
+
current.destroy();
|
|
82
|
+
|
|
83
|
+
this.next = next.clone(size);
|
|
84
|
+
next.destroy();
|
|
85
|
+
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Helper for managing double-buffered GPU buffers */
|
|
91
|
+
export class SwapBuffers extends Swap<Buffer> {
|
|
92
|
+
constructor(device: Device, props: BufferProps) {
|
|
93
|
+
super({current: device.createBuffer(props), next: device.createBuffer(props)});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Resizes the Buffers.
|
|
98
|
+
* @returns true if the size changed, otherwise exiting buffers were preserved.
|
|
99
|
+
* @note any contents are not preserved!
|
|
100
|
+
*/
|
|
101
|
+
resize(props: {byteLength: number}) {
|
|
102
|
+
if (props.byteLength === this.current.byteLength) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const {current, next} = this;
|
|
107
|
+
|
|
108
|
+
this.current = current.clone(props);
|
|
109
|
+
current.destroy();
|
|
110
|
+
|
|
111
|
+
this.next = next.clone(props);
|
|
112
|
+
next.destroy();
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {Buffer, Device, Framebuffer, RenderPassProps, Sampler, Texture} from '@luma.gl/core';
|
|
6
|
-
import {Model, ModelProps} from '../model/model';
|
|
7
6
|
import {getPassthroughFS} from '@luma.gl/shadertools';
|
|
7
|
+
import {Model, ModelProps} from '../model/model';
|
|
8
|
+
import {uid} from '../utils/uid';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Properties for creating a {@link TextureTransform}
|
|
11
|
-
* @deprecated
|
|
12
12
|
*/
|
|
13
13
|
export type TextureTransformProps = Omit<ModelProps, 'fs'> & {
|
|
14
14
|
fs?: ModelProps['fs']; // override as optional
|
|
@@ -61,7 +61,7 @@ export class TextureTransform {
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
this.model = new Model(this.device, {
|
|
64
|
-
id: props.id || 'texture-transform-model',
|
|
64
|
+
id: props.id || uid('texture-transform-model'),
|
|
65
65
|
fs:
|
|
66
66
|
props.fs ||
|
|
67
67
|
getPassthroughFS({
|
|
@@ -78,7 +78,12 @@ export class TextureTransform {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// Delete owned resources.
|
|
81
|
-
destroy(): void {
|
|
81
|
+
destroy(): void {
|
|
82
|
+
this.model.destroy();
|
|
83
|
+
for (const binding of this.bindings) {
|
|
84
|
+
binding.framebuffer?.destroy();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
82
87
|
|
|
83
88
|
/** @deprecated Use {@link destroy}. */
|
|
84
89
|
delete(): void {
|
|
@@ -92,20 +97,6 @@ export class TextureTransform {
|
|
|
92
97
|
renderPass.end();
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
/** @deprecated */
|
|
96
|
-
update(...args: any[]): void {
|
|
97
|
-
// TODO(v9): Method should likely be removed for v9. Keeping a method stub
|
|
98
|
-
// to assist with migrating DeckGL usage.
|
|
99
|
-
// eslint-disable-next-line no-console
|
|
100
|
-
console.warn('TextureTransform#update() not implemented');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
getData({packed = false} = {}) {
|
|
104
|
-
// TODO(v9): Method should likely be removed for v9. Keeping a method stub
|
|
105
|
-
// to assist with migrating DeckGL usage.
|
|
106
|
-
throw new Error('getData() not implemented');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
100
|
getTargetTexture(): Texture {
|
|
110
101
|
const {targetTexture} = this.bindings[this.currentIndex];
|
|
111
102
|
return targetTexture;
|
|
@@ -38,7 +38,7 @@ export function debugFramebuffer(
|
|
|
38
38
|
canvas.style.position = 'absolute';
|
|
39
39
|
canvas.style.top = top; // ⚠️
|
|
40
40
|
canvas.style.left = left; // ⚠️
|
|
41
|
-
canvas.style.border = 'blue
|
|
41
|
+
canvas.style.border = 'blue 5px solid';
|
|
42
42
|
canvas.style.transform = 'scaleY(-1)';
|
|
43
43
|
document.body.appendChild(canvas);
|
|
44
44
|
|
|
@@ -31,7 +31,7 @@ export function getDebugTableForShaderLayout(
|
|
|
31
31
|
|
|
32
32
|
for (const varyingDeclaration of layout.varyings || []) {
|
|
33
33
|
const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`;
|
|
34
|
-
table[`out ${glslDeclaration}`] = {[header]: JSON.stringify(varyingDeclaration
|
|
34
|
+
table[`out ${glslDeclaration}`] = {[header]: JSON.stringify(varyingDeclaration)};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
return table;
|