@luma.gl/engine 9.0.0-alpha.9 → 9.0.0-beta.10

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 (187) hide show
  1. package/LICENSE +3 -1
  2. package/dist/animation/key-frames.d.ts +1 -1
  3. package/dist/animation/key-frames.d.ts.map +1 -1
  4. package/dist/animation/key-frames.js +51 -72
  5. package/dist/animation/timeline.d.ts +8 -8
  6. package/dist/animation/timeline.d.ts.map +1 -1
  7. package/dist/animation/timeline.js +95 -131
  8. package/dist/animation-loop/animation-loop-template.d.ts +23 -0
  9. package/dist/animation-loop/animation-loop-template.d.ts.map +1 -0
  10. package/dist/animation-loop/animation-loop-template.js +21 -0
  11. package/dist/{lib → animation-loop}/animation-loop.d.ts +31 -23
  12. package/dist/animation-loop/animation-loop.d.ts.map +1 -0
  13. package/dist/animation-loop/animation-loop.js +442 -0
  14. package/dist/{lib → animation-loop}/animation-props.d.ts +4 -5
  15. package/dist/animation-loop/animation-props.d.ts.map +1 -0
  16. package/dist/animation-loop/animation-props.js +1 -0
  17. package/dist/animation-loop/make-animation-loop.d.ts +6 -0
  18. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -0
  19. package/dist/animation-loop/make-animation-loop.js +32 -0
  20. package/dist/computation.d.ts +95 -0
  21. package/dist/computation.d.ts.map +1 -0
  22. package/dist/computation.js +248 -0
  23. package/dist/debug/copy-texture-to-image.d.ts +26 -0
  24. package/dist/debug/copy-texture-to-image.d.ts.map +1 -0
  25. package/dist/debug/copy-texture-to-image.js +43 -0
  26. package/dist/debug/debug-framebuffer.d.ts +11 -0
  27. package/dist/debug/debug-framebuffer.d.ts.map +1 -0
  28. package/dist/debug/debug-framebuffer.js +46 -0
  29. package/dist/debug/debug-shader-layout.d.ts +9 -0
  30. package/dist/debug/debug-shader-layout.d.ts.map +1 -0
  31. package/dist/debug/debug-shader-layout.js +27 -0
  32. package/dist/debug/pixel-data-utils.d.ts +24 -0
  33. package/dist/debug/pixel-data-utils.d.ts.map +1 -0
  34. package/dist/debug/pixel-data-utils.js +39 -0
  35. package/dist/dist.dev.js +9592 -0
  36. package/dist/dist.min.js +102 -0
  37. package/dist/geometries/cone-geometry.d.ts +2 -2
  38. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  39. package/dist/geometries/cone-geometry.js +13 -18
  40. package/dist/geometries/cube-geometry.d.ts +2 -2
  41. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  42. package/dist/geometries/cube-geometry.js +192 -57
  43. package/dist/geometries/cylinder-geometry.d.ts +2 -2
  44. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  45. package/dist/geometries/cylinder-geometry.js +11 -15
  46. package/dist/geometries/ico-sphere-geometry.d.ts +2 -2
  47. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  48. package/dist/geometries/ico-sphere-geometry.js +143 -171
  49. package/dist/geometries/plane-geometry.d.ts +2 -2
  50. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  51. package/dist/geometries/plane-geometry.js +95 -122
  52. package/dist/geometries/sphere-geometry.d.ts +2 -2
  53. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  54. package/dist/geometries/sphere-geometry.js +78 -101
  55. package/dist/geometries/truncated-cone-geometry.d.ts +2 -4
  56. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  57. package/dist/geometries/truncated-cone-geometry.js +100 -134
  58. package/dist/geometry/geometry-table.d.ts +2 -2
  59. package/dist/geometry/geometry-table.d.ts.map +1 -1
  60. package/dist/geometry/geometry-table.js +3 -1
  61. package/dist/geometry/geometry-utils.d.ts.map +1 -1
  62. package/dist/geometry/geometry-utils.js +35 -41
  63. package/dist/geometry/geometry.d.ts +43 -43
  64. package/dist/geometry/geometry.d.ts.map +1 -1
  65. package/dist/geometry/geometry.js +82 -139
  66. package/dist/geometry/gpu-geometry.d.ts +37 -0
  67. package/dist/geometry/gpu-geometry.d.ts.map +1 -0
  68. package/dist/geometry/gpu-geometry.js +90 -0
  69. package/dist/geometry/gpu-table.d.ts +1 -0
  70. package/dist/geometry/gpu-table.d.ts.map +1 -0
  71. package/dist/geometry/gpu-table.js +42 -0
  72. package/dist/index.cjs +3444 -0
  73. package/dist/index.cjs.map +7 -0
  74. package/dist/index.d.ts +43 -24
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +29 -15
  77. package/dist/lib/clip-space.d.ts +8 -0
  78. package/dist/lib/clip-space.d.ts.map +1 -1
  79. package/dist/lib/clip-space.js +43 -2
  80. package/dist/lib/pipeline-factory.d.ts +17 -51
  81. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  82. package/dist/lib/pipeline-factory.js +84 -209
  83. package/dist/lib/shader-factory.d.ts +17 -0
  84. package/dist/lib/shader-factory.d.ts.map +1 -0
  85. package/dist/lib/shader-factory.js +46 -0
  86. package/dist/model/model.d.ts +219 -0
  87. package/dist/model/model.d.ts.map +1 -0
  88. package/dist/model/model.js +659 -0
  89. package/dist/scenegraph/group-node.d.ts +21 -0
  90. package/dist/scenegraph/group-node.d.ts.map +1 -0
  91. package/dist/scenegraph/group-node.js +84 -0
  92. package/dist/scenegraph/model-node.d.ts +18 -0
  93. package/dist/scenegraph/model-node.d.ts.map +1 -0
  94. package/dist/scenegraph/model-node.js +35 -0
  95. package/dist/scenegraph/scenegraph-node.d.ts +56 -0
  96. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -0
  97. package/dist/scenegraph/scenegraph-node.js +153 -0
  98. package/dist/shader-inputs.d.ts +63 -0
  99. package/dist/shader-inputs.d.ts.map +1 -0
  100. package/dist/shader-inputs.js +107 -0
  101. package/dist/transform/buffer-transform.d.ts +35 -0
  102. package/dist/transform/buffer-transform.d.ts.map +1 -0
  103. package/dist/transform/buffer-transform.js +70 -0
  104. package/dist/transform/texture-transform.d.ts +57 -0
  105. package/dist/transform/texture-transform.d.ts.map +1 -0
  106. package/dist/transform/texture-transform.js +117 -0
  107. package/dist.min.js +25 -0
  108. package/package.json +24 -14
  109. package/src/animation/timeline.ts +35 -34
  110. package/src/animation-loop/animation-loop-template.ts +25 -0
  111. package/src/{lib → animation-loop}/animation-loop.ts +114 -93
  112. package/src/{lib → animation-loop}/animation-props.ts +2 -2
  113. package/src/animation-loop/make-animation-loop.ts +53 -0
  114. package/src/computation.ts +346 -0
  115. package/src/debug/copy-texture-to-image.ts +70 -0
  116. package/src/debug/debug-framebuffer.ts +70 -0
  117. package/src/debug/debug-shader-layout.ts +38 -0
  118. package/src/debug/pixel-data-utils.ts +54 -0
  119. package/src/geometries/cone-geometry.ts +1 -1
  120. package/src/geometries/cube-geometry.ts +62 -56
  121. package/src/geometries/cylinder-geometry.ts +2 -2
  122. package/src/geometries/ico-sphere-geometry.ts +6 -5
  123. package/src/geometries/plane-geometry.ts +5 -4
  124. package/src/geometries/sphere-geometry.ts +4 -3
  125. package/src/geometries/truncated-cone-geometry.ts +6 -14
  126. package/src/geometry/geometry-table.ts +10 -7
  127. package/src/geometry/geometry-utils.ts +19 -3
  128. package/src/geometry/geometry.ts +68 -110
  129. package/src/geometry/gpu-geometry.ts +132 -0
  130. package/src/geometry/gpu-table.ts +41 -0
  131. package/src/index.ts +37 -10
  132. package/src/lib/clip-space.ts +32 -34
  133. package/src/lib/pipeline-factory.ts +83 -193
  134. package/src/lib/shader-factory.ts +57 -0
  135. package/src/model/model.ts +835 -0
  136. package/src/scenegraph/group-node.ts +107 -0
  137. package/src/scenegraph/model-node.ts +50 -0
  138. package/src/scenegraph/scenegraph-node.ts +204 -0
  139. package/src/shader-inputs.ts +157 -0
  140. package/src/transform/buffer-transform.ts +102 -0
  141. package/src/transform/texture-transform.ts +168 -0
  142. package/dist/animation/key-frames.js.map +0 -1
  143. package/dist/animation/timeline.js.map +0 -1
  144. package/dist/bundle.d.ts +0 -2
  145. package/dist/bundle.d.ts.map +0 -1
  146. package/dist/bundle.js +0 -5
  147. package/dist/bundle.js.map +0 -1
  148. package/dist/geometries/cone-geometry.js.map +0 -1
  149. package/dist/geometries/cube-geometry.js.map +0 -1
  150. package/dist/geometries/cylinder-geometry.js.map +0 -1
  151. package/dist/geometries/ico-sphere-geometry.js.map +0 -1
  152. package/dist/geometries/plane-geometry.js.map +0 -1
  153. package/dist/geometries/sphere-geometry.js.map +0 -1
  154. package/dist/geometries/truncated-cone-geometry.js.map +0 -1
  155. package/dist/geometry/geometry-table.js.map +0 -1
  156. package/dist/geometry/geometry-utils.js.map +0 -1
  157. package/dist/geometry/geometry.js.map +0 -1
  158. package/dist/geometry/primitive-utils.d.ts +0 -1
  159. package/dist/geometry/primitive-utils.d.ts.map +0 -1
  160. package/dist/geometry/primitive-utils.js +0 -2
  161. package/dist/geometry/primitive-utils.js.map +0 -1
  162. package/dist/index.js.map +0 -1
  163. package/dist/lib/animation-loop.d.ts.map +0 -1
  164. package/dist/lib/animation-loop.js +0 -480
  165. package/dist/lib/animation-loop.js.map +0 -1
  166. package/dist/lib/animation-props.d.ts.map +0 -1
  167. package/dist/lib/animation-props.js +0 -2
  168. package/dist/lib/animation-props.js.map +0 -1
  169. package/dist/lib/clip-space.js.map +0 -1
  170. package/dist/lib/model-utils.d.ts +0 -5
  171. package/dist/lib/model-utils.d.ts.map +0 -1
  172. package/dist/lib/model-utils.js +0 -45
  173. package/dist/lib/model-utils.js.map +0 -1
  174. package/dist/lib/model.d.ts +0 -41
  175. package/dist/lib/model.d.ts.map +0 -1
  176. package/dist/lib/model.js +0 -182
  177. package/dist/lib/model.js.map +0 -1
  178. package/dist/lib/pipeline-factory.js.map +0 -1
  179. package/dist/lib/render-loop.d.ts +0 -14
  180. package/dist/lib/render-loop.d.ts.map +0 -1
  181. package/dist/lib/render-loop.js +0 -49
  182. package/dist/lib/render-loop.js.map +0 -1
  183. package/src/bundle.ts +0 -4
  184. package/src/geometry/primitive-utils.ts +0 -30
  185. package/src/lib/model-utils.ts +0 -124
  186. package/src/lib/model.ts +0 -183
  187. package/src/lib/render-loop.ts +0 -58
@@ -0,0 +1,248 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { Buffer, ComputePipeline, UniformStore } from '@luma.gl/core';
5
+ import { log, uid, isNumberArray } from '@luma.gl/core';
6
+ import { getTypedArrayFromDataType } from '@luma.gl/core';
7
+ import { ShaderAssembler, getShaderLayoutFromWGSL } from '@luma.gl/shadertools';
8
+ import { ShaderInputs } from "./shader-inputs.js";
9
+ import { PipelineFactory } from "./lib/pipeline-factory.js";
10
+ import { ShaderFactory } from "./lib/shader-factory.js";
11
+ // import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
12
+ const LOG_DRAW_PRIORITY = 2;
13
+ const LOG_DRAW_TIMEOUT = 10000;
14
+ /**
15
+ * v9 Model API
16
+ * A model
17
+ * - automatically reuses pipelines (programs) when possible
18
+ * - automatically rebuilds pipelines if necessary to accommodate changed settings
19
+ * shadertools integration
20
+ * - accepts modules and performs shader transpilation
21
+ */
22
+ export class Computation {
23
+ static defaultProps = {
24
+ ...ComputePipeline.defaultProps,
25
+ id: 'unnamed',
26
+ handle: undefined,
27
+ userData: {},
28
+ source: '',
29
+ modules: [],
30
+ defines: {},
31
+ bindings: undefined,
32
+ shaderInputs: undefined,
33
+ pipelineFactory: undefined,
34
+ shaderFactory: undefined,
35
+ shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(),
36
+ debugShaders: undefined
37
+ };
38
+ device;
39
+ id;
40
+ pipelineFactory;
41
+ shaderFactory;
42
+ userData = {};
43
+ /** Bindings (textures, samplers, uniform buffers) */
44
+ bindings = {};
45
+ /** The underlying GPU "program". @note May be recreated if parameters change */
46
+ pipeline;
47
+ /** the underlying compiled compute shader */
48
+ shader;
49
+ source;
50
+ /** ShaderInputs instance */
51
+ shaderInputs;
52
+ _uniformStore;
53
+ _pipelineNeedsUpdate = 'newly created';
54
+ _getModuleUniforms;
55
+ props;
56
+ _destroyed = false;
57
+ constructor(device, props) {
58
+ if (device.type !== 'webgpu') {
59
+ throw new Error('Computation is only supported in WebGPU');
60
+ }
61
+ this.props = { ...Computation.defaultProps, ...props };
62
+ props = this.props;
63
+ this.id = props.id || uid('model');
64
+ this.device = device;
65
+ Object.assign(this.userData, props.userData);
66
+ // Setup shader module inputs
67
+ const moduleMap = Object.fromEntries(this.props.modules?.map(module => [module.name, module]) || []);
68
+ this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
69
+ // Support WGSL shader layout introspection
70
+ // TODO - Don't modify props!!
71
+ this.props.shaderLayout ||= getShaderLayoutFromWGSL(this.props.source);
72
+ // Setup shader assembler
73
+ const platformInfo = getPlatformInfo(device);
74
+ // Extract modules from shader inputs if not supplied
75
+ const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
76
+ this.pipelineFactory =
77
+ props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
78
+ this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
79
+ const { source, getUniforms } = this.props.shaderAssembler.assembleShader({
80
+ platformInfo,
81
+ ...this.props,
82
+ modules
83
+ });
84
+ this.source = source;
85
+ this._getModuleUniforms = getUniforms;
86
+ // Create the pipeline
87
+ // @note order is important
88
+ this.pipeline = this._updatePipeline();
89
+ // Apply any dynamic settings that will not trigger pipeline change
90
+ if (props.bindings) {
91
+ this.setBindings(props.bindings);
92
+ }
93
+ // Catch any access to non-standard props
94
+ Object.seal(this);
95
+ }
96
+ destroy() {
97
+ if (this._destroyed)
98
+ return;
99
+ this.pipelineFactory.release(this.pipeline);
100
+ this.shaderFactory.release(this.shader);
101
+ this._uniformStore.destroy();
102
+ this._destroyed = true;
103
+ }
104
+ // Draw call
105
+ predraw() {
106
+ // Update uniform buffers if needed
107
+ this.updateShaderInputs();
108
+ }
109
+ dispatch(computePass, x, y, z) {
110
+ try {
111
+ this._logDrawCallStart();
112
+ // Check if the pipeline is invalidated
113
+ // TODO - this is likely the worst place to do this from performance perspective. Perhaps add a predraw()?
114
+ this.pipeline = this._updatePipeline();
115
+ // Set pipeline state, we may be sharing a pipeline so we need to set all state on every draw
116
+ // Any caching needs to be done inside the pipeline functions
117
+ this.pipeline.setBindings(this.bindings);
118
+ computePass.setPipeline(this.pipeline);
119
+ // @ts-expect-error
120
+ computePass.setBindings([]);
121
+ computePass.dispatch(x, y, z);
122
+ }
123
+ finally {
124
+ this._logDrawCallEnd();
125
+ }
126
+ }
127
+ // Update fixed fields (can trigger pipeline rebuild)
128
+ // Update dynamic fields
129
+ /**
130
+ * Updates the vertex count (used in draw calls)
131
+ * @note Any attributes with stepMode=vertex need to be at least this big
132
+ */
133
+ setVertexCount(vertexCount) {
134
+ // this.vertexCount = vertexCount;
135
+ }
136
+ /**
137
+ * Updates the instance count (used in draw calls)
138
+ * @note Any attributes with stepMode=instance need to be at least this big
139
+ */
140
+ setInstanceCount(instanceCount) {
141
+ // this.instanceCount = instanceCount;
142
+ }
143
+ setShaderInputs(shaderInputs) {
144
+ this.shaderInputs = shaderInputs;
145
+ this._uniformStore = new UniformStore(this.shaderInputs.modules);
146
+ // Create uniform buffer bindings for all modules
147
+ for (const moduleName of Object.keys(this.shaderInputs.modules)) {
148
+ const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
149
+ this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
150
+ }
151
+ }
152
+ /**
153
+ * Updates shader module settings (which results in uniforms being set)
154
+ */
155
+ setShaderModuleProps(props) {
156
+ const uniforms = this._getModuleUniforms(props);
157
+ // Extract textures & framebuffers set by the modules
158
+ // TODO better way to extract bindings
159
+ const keys = Object.keys(uniforms).filter(k => {
160
+ const uniform = uniforms[k];
161
+ return !isNumberArray(uniform) && typeof uniform !== 'number' && typeof uniform !== 'boolean';
162
+ });
163
+ const bindings = {};
164
+ for (const k of keys) {
165
+ bindings[k] = uniforms[k];
166
+ delete uniforms[k];
167
+ }
168
+ }
169
+ updateShaderInputs() {
170
+ this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
171
+ }
172
+ /**
173
+ * Sets bindings (textures, samplers, uniform buffers)
174
+ */
175
+ setBindings(bindings) {
176
+ Object.assign(this.bindings, bindings);
177
+ }
178
+ _setPipelineNeedsUpdate(reason) {
179
+ this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
180
+ }
181
+ _updatePipeline() {
182
+ if (this._pipelineNeedsUpdate) {
183
+ let prevShader = null;
184
+ if (this.pipeline) {
185
+ log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
186
+ prevShader = this.shader;
187
+ }
188
+ this._pipelineNeedsUpdate = false;
189
+ this.shader = this.shaderFactory.createShader({
190
+ id: `${this.id}-fragment`,
191
+ stage: 'compute',
192
+ source: this.source,
193
+ debug: this.props.debugShaders
194
+ });
195
+ this.pipeline = this.pipelineFactory.createComputePipeline({
196
+ ...this.props,
197
+ shader: this.shader
198
+ });
199
+ if (prevShader) {
200
+ this.shaderFactory.release(prevShader);
201
+ }
202
+ }
203
+ return this.pipeline;
204
+ }
205
+ /** Throttle draw call logging */
206
+ _lastLogTime = 0;
207
+ _logOpen = false;
208
+ _logDrawCallStart() {
209
+ // IF level is 4 or higher, log every frame.
210
+ const logDrawTimeout = log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
211
+ if (log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
212
+ return;
213
+ }
214
+ this._lastLogTime = Date.now();
215
+ this._logOpen = true;
216
+ log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: log.level <= 2 })();
217
+ }
218
+ _logDrawCallEnd() {
219
+ if (this._logOpen) {
220
+ // const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.props.shaderLayout, this.id);
221
+ // log.table(logLevel, attributeTable)();
222
+ // log.table(logLevel, uniformTable)();
223
+ // log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
224
+ const uniformTable = this.shaderInputs.getDebugTable();
225
+ log.table(LOG_DRAW_PRIORITY, uniformTable)();
226
+ log.groupEnd(LOG_DRAW_PRIORITY)();
227
+ this._logOpen = false;
228
+ }
229
+ }
230
+ _drawCount = 0;
231
+ // TODO - fix typing of luma data types
232
+ _getBufferOrConstantValues(attribute, dataType) {
233
+ const TypedArrayConstructor = getTypedArrayFromDataType(dataType);
234
+ const typedArray = attribute instanceof Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
235
+ return typedArray.toString();
236
+ }
237
+ }
238
+ /** Create a shadertools platform info from the Device */
239
+ export function getPlatformInfo(device) {
240
+ return {
241
+ type: device.type,
242
+ shaderLanguage: device.info.shadingLanguage,
243
+ shaderLanguageVersion: device.info.shadingLanguageVersion,
244
+ gpu: device.info.gpu,
245
+ // HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
246
+ features: device.features
247
+ };
248
+ }
@@ -0,0 +1,26 @@
1
+ import { Texture, Framebuffer } from '@luma.gl/core';
2
+ /**
3
+ * Options for copying texture pixels to image
4
+ * @todo - support gl.readBuffer
5
+ */
6
+ export type CopyTextureToImageOptions = {
7
+ sourceAttachment?: number;
8
+ targetMaxHeight?: number;
9
+ targetImage?: HTMLImageElement;
10
+ };
11
+ /**
12
+ * Reads pixels from a Framebuffer or Texture object into an HTML Image
13
+ * @todo - can we move this to @luma.gl/core?
14
+ * @param source
15
+ * @param options options passed to copyToDataUrl
16
+ * @returns
17
+ */
18
+ export declare function copyTextureToImage(source: Texture | Framebuffer, options?: CopyTextureToImageOptions): HTMLImageElement;
19
+ /**
20
+ * Reads pixels from a Framebuffer or Texture object to a dataUrl
21
+ * @todo - can we move this to @luma.gl/core?
22
+ * @param source texture or framebuffer to read from
23
+ * @param options
24
+ */
25
+ export declare function copyTextureToDataUrl(source: Texture | Framebuffer, options?: CopyTextureToImageOptions): string;
26
+ //# sourceMappingURL=copy-texture-to-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-texture-to-image.d.ts","sourceRoot":"","sources":["../../src/debug/copy-texture-to-image.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AAGnD;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,GAAG,WAAW,EAC7B,OAAO,CAAC,EAAE,yBAAyB,GAClC,gBAAgB,CAMlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,GAAG,WAAW,EAC7B,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAyBR"}
@@ -0,0 +1,43 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { flipRows, scalePixels } from "./pixel-data-utils.js";
5
+ /**
6
+ * Reads pixels from a Framebuffer or Texture object into an HTML Image
7
+ * @todo - can we move this to @luma.gl/core?
8
+ * @param source
9
+ * @param options options passed to copyToDataUrl
10
+ * @returns
11
+ */
12
+ export function copyTextureToImage(source, options) {
13
+ const dataUrl = copyTextureToDataUrl(source, options);
14
+ const targetImage = options?.targetImage || new Image();
15
+ targetImage.src = dataUrl;
16
+ return targetImage;
17
+ }
18
+ /**
19
+ * Reads pixels from a Framebuffer or Texture object to a dataUrl
20
+ * @todo - can we move this to @luma.gl/core?
21
+ * @param source texture or framebuffer to read from
22
+ * @param options
23
+ */
24
+ export function copyTextureToDataUrl(source, options = {}) {
25
+ const { sourceAttachment, targetMaxHeight = Number.MAX_SAFE_INTEGER } = options;
26
+ let data = source.device.readPixelsToArrayWebGL(source, { sourceAttachment });
27
+ // Scale down
28
+ let { width, height } = source;
29
+ while (height > targetMaxHeight) {
30
+ ({ data, width, height } = scalePixels({ data, width, height }));
31
+ }
32
+ // Flip to top down coordinate system
33
+ flipRows({ data, width, height });
34
+ const canvas = document.createElement('canvas');
35
+ canvas.width = width;
36
+ canvas.height = height;
37
+ const context = canvas.getContext('2d');
38
+ // Copy the pixels to a 2D canvas
39
+ const imageData = context.createImageData(width, height);
40
+ imageData.data.set(data);
41
+ context.putImageData(imageData, 0, 0);
42
+ return canvas.toDataURL('image/png');
43
+ }
@@ -0,0 +1,11 @@
1
+ import type { Framebuffer, Texture } from '@luma.gl/core';
2
+ /** Debug utility to draw FBO contents onto screen */
3
+ export declare function debugFramebuffer(fbo: Framebuffer | Texture, { id, minimap, opaque, top, left, rgbaScale }: {
4
+ id: string;
5
+ minimap?: boolean;
6
+ opaque?: boolean;
7
+ top?: string;
8
+ left?: string;
9
+ rgbaScale?: number;
10
+ }): void;
11
+ //# sourceMappingURL=debug-framebuffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-framebuffer.d.ts","sourceRoot":"","sources":["../../src/debug/debug-framebuffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,OAAO,EAAC,MAAM,eAAe,CAAC;AAQxD,qDAAqD;AAErD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,WAAW,GAAG,OAAO,EAC1B,EACE,EAAE,EACF,OAAO,EACP,MAAM,EACN,GAAS,EACT,IAAU,EACV,SAAa,EACd,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,QA2CF"}
@@ -0,0 +1,46 @@
1
+ // import {copyTextureToImage} from '../debug/copy-texture-to-image';
2
+ /** Only works with 1st device? */
3
+ let canvas = null;
4
+ let ctx = null;
5
+ // let targetImage: HTMLImageElement | null = null;
6
+ /** Debug utility to draw FBO contents onto screen */
7
+ // eslint-disable-next-line
8
+ export function debugFramebuffer(fbo, { id, minimap, opaque, top = '0', left = '0', rgbaScale = 1 }) {
9
+ if (!canvas) {
10
+ canvas = document.createElement('canvas');
11
+ canvas.id = id;
12
+ canvas.title = id;
13
+ canvas.style.zIndex = '100';
14
+ canvas.style.position = 'absolute';
15
+ canvas.style.top = top; // ⚠️
16
+ canvas.style.left = left; // ⚠️
17
+ canvas.style.border = 'blue 1px solid';
18
+ canvas.style.transform = 'scaleY(-1)';
19
+ document.body.appendChild(canvas);
20
+ ctx = canvas.getContext('2d');
21
+ // targetImage = new Image();
22
+ }
23
+ // const canvasHeight = (minimap ? 2 : 1) * fbo.height;
24
+ if (canvas.width !== fbo.width || canvas.height !== fbo.height) {
25
+ canvas.width = fbo.width / 2;
26
+ canvas.height = fbo.height / 2;
27
+ canvas.style.width = '400px';
28
+ canvas.style.height = '400px';
29
+ }
30
+ // const image = copyTextureToImage(fbo, {targetMaxHeight: 100, targetImage});
31
+ // ctx.drawImage(image, 0, 0);
32
+ const color = fbo.device.readPixelsToArrayWebGL(fbo);
33
+ const imageData = ctx.createImageData(fbo.width, fbo.height);
34
+ // Full map
35
+ const offset = 0;
36
+ // if (color.some((v) => v > 0)) {
37
+ // console.error('THERE IS NON-ZERO DATA IN THE FBO!');
38
+ // }
39
+ for (let i = 0; i < color.length; i += 4) {
40
+ imageData.data[offset + i + 0] = color[i + 0] * rgbaScale;
41
+ imageData.data[offset + i + 1] = color[i + 1] * rgbaScale;
42
+ imageData.data[offset + i + 2] = color[i + 2] * rgbaScale;
43
+ imageData.data[offset + i + 3] = opaque ? 255 : color[i + 3] * rgbaScale;
44
+ }
45
+ ctx.putImageData(imageData, 0, 0);
46
+ }
@@ -0,0 +1,9 @@
1
+ import type { ShaderLayout } from '@luma.gl/core';
2
+ /**
3
+ * Extracts a table suitable for `console.table()` from a shader layout to assist in debugging.
4
+ * @param layout shader layout
5
+ * @param name app should provide the most meaningful name, usually the model or pipeline name / id.
6
+ * @returns
7
+ */
8
+ export declare function getDebugTableForShaderLayout(layout: ShaderLayout, name: string): Record<string, Record<string, string>>;
9
+ //# sourceMappingURL=debug-shader-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-shader-layout.d.ts","sourceRoot":"","sources":["../../src/debug/debug-shader-layout.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAEhD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsBxC"}
@@ -0,0 +1,27 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ /**
5
+ * Extracts a table suitable for `console.table()` from a shader layout to assist in debugging.
6
+ * @param layout shader layout
7
+ * @param name app should provide the most meaningful name, usually the model or pipeline name / id.
8
+ * @returns
9
+ */
10
+ export function getDebugTableForShaderLayout(layout, name) {
11
+ const table = {};
12
+ const header = 'Values'; // '`Shader Layout for ${name}`;
13
+ if (layout.attributes.length === 0 && !layout.varyings?.length) {
14
+ return { 'No attributes or varyings': { [header]: 'N/A' } };
15
+ }
16
+ for (const attributeDeclaration of layout.attributes) {
17
+ if (attributeDeclaration) {
18
+ const glslDeclaration = `${attributeDeclaration.location} ${attributeDeclaration.name}: ${attributeDeclaration.type}`;
19
+ table[`in ${glslDeclaration}`] = { [header]: attributeDeclaration.stepMode || 'vertex' };
20
+ }
21
+ }
22
+ for (const varyingDeclaration of layout.varyings || []) {
23
+ const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`;
24
+ table[`out ${glslDeclaration}`] = { [header]: JSON.stringify(varyingDeclaration.accessor) };
25
+ }
26
+ return table;
27
+ }
@@ -0,0 +1,24 @@
1
+ import { TypedArray } from '@luma.gl/core';
2
+ /**
3
+ * Flip rows (can be used on arrays returned from `Framebuffer.readPixels`)
4
+ * https: *stackoverflow.com/questions/41969562/
5
+ * how-can-i-flip-the-result-of-webglrenderingcontext-readpixels
6
+ * @param param0
7
+ */
8
+ export declare function flipRows(options: {
9
+ data: TypedArray;
10
+ width: number;
11
+ height: number;
12
+ bytesPerPixel?: number;
13
+ temp?: Uint8Array;
14
+ }): void;
15
+ export declare function scalePixels(options: {
16
+ data: TypedArray;
17
+ width: number;
18
+ height: number;
19
+ }): {
20
+ data: Uint8Array;
21
+ width: number;
22
+ height: number;
23
+ };
24
+ //# sourceMappingURL=pixel-data-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-data-utils.d.ts","sourceRoot":"","sources":["../../src/debug/pixel-data-utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,GAAG,IAAI,CAgBP;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GAAG;IACvF,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAaA"}
@@ -0,0 +1,39 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ /**
5
+ * Flip rows (can be used on arrays returned from `Framebuffer.readPixels`)
6
+ * https: *stackoverflow.com/questions/41969562/
7
+ * how-can-i-flip-the-result-of-webglrenderingcontext-readpixels
8
+ * @param param0
9
+ */
10
+ export function flipRows(options) {
11
+ const { data, width, height, bytesPerPixel = 4, temp } = options;
12
+ const bytesPerRow = width * bytesPerPixel;
13
+ // make a temp buffer to hold one row
14
+ const tempBuffer = temp || new Uint8Array(bytesPerRow);
15
+ for (let y = 0; y < height / 2; ++y) {
16
+ const topOffset = y * bytesPerRow;
17
+ const bottomOffset = (height - y - 1) * bytesPerRow;
18
+ // make copy of a row on the top half
19
+ tempBuffer.set(data.subarray(topOffset, topOffset + bytesPerRow));
20
+ // copy a row from the bottom half to the top
21
+ data.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
22
+ // copy the copy of the top half row to the bottom half
23
+ data.set(tempBuffer, bottomOffset);
24
+ }
25
+ }
26
+ export function scalePixels(options) {
27
+ const { data, width, height } = options;
28
+ const newWidth = Math.round(width / 2);
29
+ const newHeight = Math.round(height / 2);
30
+ const newData = new Uint8Array(newWidth * newHeight * 4);
31
+ for (let y = 0; y < newHeight; y++) {
32
+ for (let x = 0; x < newWidth; x++) {
33
+ for (let c = 0; c < 4; c++) {
34
+ newData[(y * newWidth + x) * 4 + c] = data[(y * 2 * width + x * 2) * 4 + c];
35
+ }
36
+ }
37
+ }
38
+ return { data: newData, width: newWidth, height: newHeight };
39
+ }