@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.
Files changed (196) hide show
  1. package/dist/animation/key-frames.js +1 -0
  2. package/dist/animation/key-frames.js.map +1 -0
  3. package/dist/animation/timeline.js +1 -0
  4. package/dist/animation/timeline.js.map +1 -0
  5. package/dist/animation-loop/animation-loop-template.js +1 -0
  6. package/dist/animation-loop/animation-loop-template.js.map +1 -0
  7. package/dist/animation-loop/animation-loop.d.ts +2 -0
  8. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  9. package/dist/animation-loop/animation-loop.js +24 -6
  10. package/dist/animation-loop/animation-loop.js.map +1 -0
  11. package/dist/animation-loop/animation-props.js +1 -0
  12. package/dist/animation-loop/animation-props.js.map +1 -0
  13. package/dist/animation-loop/make-animation-loop.d.ts +5 -1
  14. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
  15. package/dist/animation-loop/make-animation-loop.js +3 -1
  16. package/dist/animation-loop/make-animation-loop.js.map +1 -0
  17. package/dist/animation-loop/request-animation-frame.d.ts +4 -2
  18. package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
  19. package/dist/animation-loop/request-animation-frame.js +5 -3
  20. package/dist/animation-loop/request-animation-frame.js.map +1 -0
  21. package/dist/application-utils/load-file.d.ts +1 -1
  22. package/dist/application-utils/load-file.d.ts.map +1 -1
  23. package/dist/application-utils/load-file.js +2 -2
  24. package/dist/application-utils/load-file.js.map +1 -0
  25. package/dist/application-utils/random.js +1 -0
  26. package/dist/application-utils/random.js.map +1 -0
  27. package/dist/async-texture/async-texture.d.ts +14 -2
  28. package/dist/async-texture/async-texture.d.ts.map +1 -1
  29. package/dist/async-texture/async-texture.js +31 -0
  30. package/dist/async-texture/async-texture.js.map +1 -0
  31. package/dist/compute/buffer-transform.d.ts +41 -0
  32. package/dist/compute/buffer-transform.d.ts.map +1 -0
  33. package/dist/{transform → compute}/buffer-transform.js +19 -12
  34. package/dist/compute/buffer-transform.js.map +1 -0
  35. package/dist/{computation.d.ts → compute/computation.d.ts} +3 -3
  36. package/dist/compute/computation.d.ts.map +1 -0
  37. package/dist/{computation.js → compute/computation.js} +7 -8
  38. package/dist/compute/computation.js.map +1 -0
  39. package/dist/compute/swap.d.ts +48 -0
  40. package/dist/compute/swap.d.ts.map +1 -0
  41. package/dist/compute/swap.js +91 -0
  42. package/dist/compute/swap.js.map +1 -0
  43. package/dist/{transform → compute}/texture-transform.d.ts +0 -6
  44. package/dist/compute/texture-transform.d.ts.map +1 -0
  45. package/dist/{transform → compute}/texture-transform.js +10 -15
  46. package/dist/compute/texture-transform.js.map +1 -0
  47. package/dist/debug/copy-texture-to-image.js +1 -0
  48. package/dist/debug/copy-texture-to-image.js.map +1 -0
  49. package/dist/debug/debug-framebuffer.js +2 -1
  50. package/dist/debug/debug-framebuffer.js.map +1 -0
  51. package/dist/debug/debug-shader-layout.js +2 -1
  52. package/dist/debug/debug-shader-layout.js.map +1 -0
  53. package/dist/debug/pixel-data-utils.js +1 -0
  54. package/dist/debug/pixel-data-utils.js.map +1 -0
  55. package/dist/dist.dev.js +2697 -5857
  56. package/dist/dist.min.js +420 -103
  57. package/dist/{lib → factories}/pipeline-factory.d.ts +11 -1
  58. package/dist/factories/pipeline-factory.d.ts.map +1 -0
  59. package/dist/factories/pipeline-factory.js +181 -0
  60. package/dist/factories/pipeline-factory.js.map +1 -0
  61. package/dist/{lib → factories}/shader-factory.d.ts +5 -1
  62. package/dist/factories/shader-factory.d.ts.map +1 -0
  63. package/dist/{lib → factories}/shader-factory.js +39 -4
  64. package/dist/factories/shader-factory.js.map +1 -0
  65. package/dist/geometries/cone-geometry.js +1 -0
  66. package/dist/geometries/cone-geometry.js.map +1 -0
  67. package/dist/geometries/cube-geometry.js +1 -0
  68. package/dist/geometries/cube-geometry.js.map +1 -0
  69. package/dist/geometries/cylinder-geometry.js +1 -0
  70. package/dist/geometries/cylinder-geometry.js.map +1 -0
  71. package/dist/geometries/ico-sphere-geometry.js +1 -0
  72. package/dist/geometries/ico-sphere-geometry.js.map +1 -0
  73. package/dist/geometries/plane-geometry.js +1 -0
  74. package/dist/geometries/plane-geometry.js.map +1 -0
  75. package/dist/geometries/sphere-geometry.js +1 -0
  76. package/dist/geometries/sphere-geometry.js.map +1 -0
  77. package/dist/geometries/truncated-cone-geometry.js +1 -0
  78. package/dist/geometries/truncated-cone-geometry.js.map +1 -0
  79. package/dist/geometry/geometry-table.js +1 -0
  80. package/dist/geometry/geometry-table.js.map +1 -0
  81. package/dist/geometry/geometry-utils.js +1 -0
  82. package/dist/geometry/geometry-utils.js.map +1 -0
  83. package/dist/geometry/geometry.js +1 -0
  84. package/dist/geometry/geometry.js.map +1 -0
  85. package/dist/geometry/gpu-geometry.js +1 -0
  86. package/dist/geometry/gpu-geometry.js.map +1 -0
  87. package/dist/geometry/gpu-table.js +1 -0
  88. package/dist/geometry/gpu-table.js.map +1 -0
  89. package/dist/index.cjs +1416 -209
  90. package/dist/index.cjs.map +4 -4
  91. package/dist/index.d.ts +23 -12
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +19 -9
  94. package/dist/index.js.map +1 -0
  95. package/dist/model/model.d.ts +11 -10
  96. package/dist/model/model.d.ts.map +1 -1
  97. package/dist/model/model.js +93 -70
  98. package/dist/model/model.js.map +1 -0
  99. package/dist/model/split-uniforms-and-bindings.d.ts +1 -1
  100. package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
  101. package/dist/model/split-uniforms-and-bindings.js +2 -1
  102. package/dist/model/split-uniforms-and-bindings.js.map +1 -0
  103. package/dist/models/billboard-texture-model.d.ts +23 -0
  104. package/dist/models/billboard-texture-model.d.ts.map +1 -0
  105. package/dist/models/billboard-texture-model.js +78 -0
  106. package/dist/models/billboard-texture-model.js.map +1 -0
  107. package/dist/models/billboard-texture-module.d.ts +10 -0
  108. package/dist/models/billboard-texture-module.d.ts.map +1 -0
  109. package/dist/models/billboard-texture-module.js +37 -0
  110. package/dist/models/billboard-texture-module.js.map +1 -0
  111. package/dist/{lib → models}/clip-space.d.ts +3 -1
  112. package/dist/models/clip-space.d.ts.map +1 -0
  113. package/dist/models/clip-space.js +77 -0
  114. package/dist/models/clip-space.js.map +1 -0
  115. package/dist/modules/picking/color-picking.d.ts +28 -0
  116. package/dist/modules/picking/color-picking.d.ts.map +1 -0
  117. package/dist/modules/picking/color-picking.js +177 -0
  118. package/dist/modules/picking/color-picking.js.map +1 -0
  119. package/dist/modules/picking/index-picking.d.ts +32 -0
  120. package/dist/modules/picking/index-picking.d.ts.map +1 -0
  121. package/dist/modules/picking/index-picking.js +148 -0
  122. package/dist/modules/picking/index-picking.js.map +1 -0
  123. package/dist/modules/picking/legacy-picking-manager.d.ts +27 -0
  124. package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -0
  125. package/dist/modules/picking/legacy-picking-manager.js +76 -0
  126. package/dist/modules/picking/legacy-picking-manager.js.map +1 -0
  127. package/dist/modules/picking/picking-manager.d.ts +45 -0
  128. package/dist/modules/picking/picking-manager.d.ts.map +1 -0
  129. package/dist/modules/picking/picking-manager.js +101 -0
  130. package/dist/modules/picking/picking-manager.js.map +1 -0
  131. package/dist/modules/picking/picking-uniforms.d.ts +79 -0
  132. package/dist/modules/picking/picking-uniforms.d.ts.map +1 -0
  133. package/dist/modules/picking/picking-uniforms.js +109 -0
  134. package/dist/modules/picking/picking-uniforms.js.map +1 -0
  135. package/dist/passes/get-fragment-shader.d.ts +12 -0
  136. package/dist/passes/get-fragment-shader.d.ts.map +1 -0
  137. package/dist/passes/get-fragment-shader.js +117 -0
  138. package/dist/passes/get-fragment-shader.js.map +1 -0
  139. package/dist/passes/shader-pass-renderer.d.ts +63 -0
  140. package/dist/passes/shader-pass-renderer.d.ts.map +1 -0
  141. package/dist/passes/shader-pass-renderer.js +197 -0
  142. package/dist/passes/shader-pass-renderer.js.map +1 -0
  143. package/dist/scenegraph/group-node.js +1 -0
  144. package/dist/scenegraph/group-node.js.map +1 -0
  145. package/dist/scenegraph/model-node.js +1 -0
  146. package/dist/scenegraph/model-node.js.map +1 -0
  147. package/dist/scenegraph/scenegraph-node.js +1 -0
  148. package/dist/scenegraph/scenegraph-node.js.map +1 -0
  149. package/dist/shader-inputs.d.ts +8 -21
  150. package/dist/shader-inputs.d.ts.map +1 -1
  151. package/dist/shader-inputs.js +15 -11
  152. package/dist/shader-inputs.js.map +1 -0
  153. package/dist/utils/deep-equal.js +1 -0
  154. package/dist/utils/deep-equal.js.map +1 -0
  155. package/dist/utils/uid.js +1 -0
  156. package/dist/utils/uid.js.map +1 -0
  157. package/package.json +6 -6
  158. package/src/animation-loop/animation-loop.ts +27 -6
  159. package/src/animation-loop/make-animation-loop.ts +8 -3
  160. package/src/animation-loop/request-animation-frame.ts +4 -3
  161. package/src/application-utils/load-file.ts +2 -4
  162. package/src/async-texture/async-texture.ts +39 -7
  163. package/src/{transform → compute}/buffer-transform.ts +30 -14
  164. package/src/{computation.ts → compute/computation.ts} +14 -8
  165. package/src/compute/swap.ts +116 -0
  166. package/src/{transform → compute}/texture-transform.ts +9 -18
  167. package/src/debug/debug-framebuffer.ts +1 -1
  168. package/src/debug/debug-shader-layout.ts +1 -1
  169. package/src/factories/pipeline-factory.ts +222 -0
  170. package/src/{lib → factories}/shader-factory.ts +41 -5
  171. package/src/index.ts +35 -16
  172. package/src/model/model.ts +133 -78
  173. package/src/model/split-uniforms-and-bindings.ts +4 -4
  174. package/src/models/billboard-texture-model.ts +98 -0
  175. package/src/models/billboard-texture-module.ts +49 -0
  176. package/src/models/clip-space.ts +88 -0
  177. package/src/modules/picking/README.md +88 -0
  178. package/src/modules/picking/color-picking.ts +190 -0
  179. package/src/modules/picking/index-picking.ts +156 -0
  180. package/src/modules/picking/legacy-picking-manager.ts +99 -0
  181. package/src/modules/picking/picking-manager.ts +137 -0
  182. package/src/modules/picking/picking-uniforms.ts +179 -0
  183. package/src/passes/get-fragment-shader.ts +129 -0
  184. package/src/passes/shader-pass-renderer.ts +252 -0
  185. package/src/shader-inputs.ts +27 -48
  186. package/dist/computation.d.ts.map +0 -1
  187. package/dist/lib/clip-space.d.ts.map +0 -1
  188. package/dist/lib/clip-space.js +0 -46
  189. package/dist/lib/pipeline-factory.d.ts.map +0 -1
  190. package/dist/lib/pipeline-factory.js +0 -98
  191. package/dist/lib/shader-factory.d.ts.map +0 -1
  192. package/dist/transform/buffer-transform.d.ts +0 -35
  193. package/dist/transform/buffer-transform.d.ts.map +0 -1
  194. package/dist/transform/texture-transform.d.ts.map +0 -1
  195. package/src/lib/clip-space.ts +0 -53
  196. 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 {requestAnimationFrame, cancelAnimationFrame} from './request-animation-frame';
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 = requestAnimationFrame(this._animationFrame.bind(this));
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.cancelAnimationFrame) {
337
+ // if (this.display && this.display.cancelAnimationFramePolyfill) {
317
338
  // this.display.cancelAnimationFrame(this._animationFrameId);
318
339
  // }
319
- cancelAnimationFrame(this._animationFrameId);
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 = props?.device || luma.createDevice({id: 'animation-loop'});
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 requestAnimationFrame(callback: (time?: any) => void): any {
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
- export function cancelAnimationFrame(timerId: any): void {
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
- // We could implement resize by replacing the texture
121
- // resize(width: number, height: number): boolean {
122
- // throw new Error('Not implemented');
123
- // // return false;
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
- * @deprecated
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
- * Creates a pipeline for buffer→buffer transforms.
21
- * @deprecated
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
- /** @deprecated Use device feature test. */
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 = Model.defaultProps) {
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(options?: RenderPassProps): void {
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
- /** @deprecated */
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 {Device, Buffer, ComputePipeline, ComputePass, UniformStore} from '@luma.gl/core';
7
- import {log} from '@luma.gl/core';
8
- import {getTypedArrayFromDataType} from '@luma.gl/core';
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 './shader-inputs';
13
- import {PipelineFactory} from './lib/pipeline-factory';
14
- import {ShaderFactory} from './lib/shader-factory';
15
- import {uid} from './utils/uid';
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
- debug: this.props.debugShaders
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 1px solid';
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.accessor)};
34
+ table[`out ${glslDeclaration}`] = {[header]: JSON.stringify(varyingDeclaration)};
35
35
  }
36
36
 
37
37
  return table;