@luma.gl/engine 9.0.0-alpha.52 → 9.0.0-alpha.54

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/engine",
3
- "version": "9.0.0-alpha.52",
3
+ "version": "9.0.0-alpha.54",
4
4
  "description": "WebGL2 Components for High Performance Rendering and Computation",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,12 +40,12 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@babel/runtime": "^7.0.0",
43
- "@luma.gl/constants": "9.0.0-alpha.52",
44
- "@luma.gl/core": "9.0.0-alpha.52",
45
- "@luma.gl/shadertools": "9.0.0-alpha.52",
43
+ "@luma.gl/constants": "9.0.0-alpha.54",
44
+ "@luma.gl/core": "9.0.0-alpha.54",
45
+ "@luma.gl/shadertools": "9.0.0-alpha.54",
46
46
  "@math.gl/core": "^4.0.0",
47
47
  "@probe.gl/log": "^4.0.2",
48
48
  "@probe.gl/stats": "^4.0.2"
49
49
  },
50
- "gitHead": "41fa29f78dc260e5ef4c6a48e657fb5d23c96e8f"
50
+ "gitHead": "6028eb651303eadbc8f25e86d135d28f118fa3cf"
51
51
  }
@@ -0,0 +1,34 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {ShaderLayout} from '@luma.gl/core';
6
+
7
+ /**
8
+ * Extracts a table suitable for `console.table()` from a shader layout to assist in debugging.
9
+ * @param layout shader layout
10
+ * @param name app should provide the most meaningful name, usually the model or pipeline name / id.
11
+ * @returns
12
+ */
13
+ export function getDebugTableForShaderLayout(
14
+ layout: ShaderLayout,
15
+ name: string = ''
16
+ ): Record<string, Record<string, string>> {
17
+ const table: Record<string, Record<string, string>> = {};
18
+
19
+ const header = `Shader Layout for ${name}`;
20
+
21
+ for (const attributeDeclaration of layout.attributes) {
22
+ if (attributeDeclaration) {
23
+ const glslDeclaration = `${attributeDeclaration.location} ${attributeDeclaration.name}: ${attributeDeclaration.type}`;
24
+ table[`in ${glslDeclaration}`] = {[header]: attributeDeclaration.stepMode || 'vertex'};
25
+ }
26
+ }
27
+
28
+ for (const varyingDeclaration of layout.varyings || []) {
29
+ const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`;
30
+ table[`out ${glslDeclaration}`] = {[header]: JSON.stringify(varyingDeclaration.accessor)};
31
+ }
32
+
33
+ return table;
34
+ }
@@ -112,6 +112,7 @@ export function getAttributeBuffersFromGeometry(
112
112
  case 'POSITION': name = 'positions'; break;
113
113
  case 'NORMAL': name = 'normals'; break;
114
114
  case 'TEXCOORD_0': name = 'texCoords'; break;
115
+ case 'COLOR_0': name = 'colors'; break;
115
116
  }
116
117
  attributes[name] = device.createBuffer({data: attribute.value, id: `${attributeName}-buffer`});
117
118
  const {value, size, normalized} = attribute;
@@ -1,18 +1,30 @@
1
1
  // luma.gl, MIT license
2
2
  // Copyright (c) vis.gl contributors
3
3
 
4
- import type {TypedArray, RenderPipelineProps, RenderPipelineParameters} from '@luma.gl/core';
4
+ import type {
5
+ TypedArray,
6
+ RenderPipelineProps,
7
+ RenderPipelineParameters
8
+ } from '@luma.gl/core';
5
9
  import type {BufferLayout, VertexArray, TransformFeedback} from '@luma.gl/core';
6
10
  import type {AttributeInfo, Binding, UniformValue, PrimitiveTopology} from '@luma.gl/core';
7
- import {Device, Buffer, RenderPipeline, RenderPass, UniformStore} from '@luma.gl/core';
11
+ import {
12
+ Device,
13
+ Buffer,
14
+ RenderPipeline,
15
+ RenderPass,
16
+ UniformStore,
17
+ getTypedArrayFromDataType
18
+ } from '@luma.gl/core';
8
19
  import {log, uid, deepEqual, splitUniformsAndBindings} from '@luma.gl/core';
9
- import {getAttributeInfosFromLayouts, getDebugTableForShaderLayout} from '@luma.gl/core';
20
+ import {getAttributeInfosFromLayouts} from '@luma.gl/core';
10
21
  import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
11
22
  import {ShaderAssembler} from '@luma.gl/shadertools';
12
23
  import {ShaderInputs} from '../shader-inputs';
13
24
  import type {Geometry} from '../geometry/geometry';
14
25
  import {GPUGeometry, makeGPUGeometry} from '../geometry/gpu-geometry';
15
26
  import {PipelineFactory} from '../lib/pipeline-factory';
27
+ import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
16
28
 
17
29
  const LOG_DRAW_PRIORITY = 2;
18
30
  const LOG_DRAW_TIMEOUT = 10000;
@@ -159,13 +171,20 @@ export class Model {
159
171
  Object.assign(this.userData, props.userData);
160
172
 
161
173
  // Setup shader module inputs
162
- const moduleMap = Object.fromEntries(this.props.modules?.map(module => [module.name, module]) || []);
174
+ const moduleMap = Object.fromEntries(
175
+ this.props.modules?.map(module => [module.name, module]) || []
176
+ );
163
177
  this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
164
178
 
165
179
  // Setup shader assembler
166
180
  const platformInfo = getPlatformInfo(device);
167
- const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
168
- const {vs, fs, getUniforms} = this.props.shaderAssembler.assembleShaders({platformInfo, ...this.props, modules});
181
+ const modules =
182
+ (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
183
+ const {vs, fs, getUniforms} = this.props.shaderAssembler.assembleShaders({
184
+ platformInfo,
185
+ ...this.props,
186
+ modules
187
+ });
169
188
 
170
189
  this.vs = vs;
171
190
  this.fs = fs;
@@ -226,8 +245,7 @@ export class Model {
226
245
  this.setUniforms(props.uniforms);
227
246
  }
228
247
  if (props.moduleSettings) {
229
- // eslint-disable-next-line no-console
230
- console.warn('Model.props.moduleSettings is deprecated. Use Model.shaderInputs.setProps()');
248
+ log.warn('Model.props.moduleSettings is deprecated. Use Model.shaderInputs.setProps()')();
231
249
  this.updateModuleSettings(props.moduleSettings);
232
250
  }
233
251
  if (props.transformFeedback) {
@@ -305,7 +323,7 @@ export class Model {
305
323
  _setGeometryAttributes(gpuGeometry: GPUGeometry): void {
306
324
  // TODO - delete previous geometry?
307
325
  this.vertexCount = gpuGeometry.vertexCount;
308
- this.setAttributes(gpuGeometry.attributes);
326
+ this.setAttributes(gpuGeometry.attributes, 'ignore-unknown');
309
327
  this.setIndexBuffer(gpuGeometry.indices);
310
328
  }
311
329
 
@@ -380,10 +398,7 @@ export class Model {
380
398
  this._uniformStore = new UniformStore(this.shaderInputs.modules);
381
399
  // Create uniform buffer bindings for all modules
382
400
  for (const moduleName of Object.keys(this.shaderInputs.modules)) {
383
- const uniformBuffer = this._uniformStore.getManagedUniformBuffer(
384
- this.device,
385
- moduleName
386
- );
401
+ const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
387
402
  this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
388
403
  }
389
404
  }
@@ -396,13 +411,12 @@ export class Model {
396
411
  * @deprecated Updates shader module settings (which results in uniforms being set)
397
412
  */
398
413
  updateModuleSettings(props: Record<string, any>): void {
399
- // eslint-disable-next-line no-console
400
- console.warn('Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()');
414
+ log.warn('Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()')();
401
415
  const {bindings, uniforms} = splitUniformsAndBindings(this._getModuleUniforms(props));
402
416
  Object.assign(this.bindings, bindings);
403
417
  Object.assign(this.uniforms, uniforms);
404
418
  }
405
-
419
+
406
420
  /**
407
421
  * Sets bindings (textures, samplers, uniform buffers)
408
422
  */
@@ -440,23 +454,21 @@ export class Model {
440
454
  * Sets attributes (buffers)
441
455
  * @note Overrides any attributes previously set with the same name
442
456
  */
443
- setAttributes(buffers: Record<string, Buffer>): void {
457
+ setAttributes(buffers: Record<string, Buffer>, _option?: 'ignore-unknown'): void {
444
458
  if (buffers.indices) {
445
459
  log.warn(
446
460
  `Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
447
- );
461
+ )();
448
462
  }
449
463
  for (const [bufferName, buffer] of Object.entries(buffers)) {
450
- const bufferLayout = this.bufferLayout.find(layout => layout.name === bufferName);
464
+ const bufferLayout = this.bufferLayout.find(layout => getAttributeNames(layout).includes(bufferName));
451
465
  if (!bufferLayout) {
452
466
  log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
453
467
  continue; // eslint-disable-line no-continue
454
468
  }
455
469
 
456
470
  // For an interleaved attribute we may need to set multiple attributes
457
- const attributeNames = bufferLayout.attributes
458
- ? bufferLayout.attributes?.map(layout => layout.attribute)
459
- : [bufferLayout.name];
471
+ const attributeNames = getAttributeNames(bufferLayout);
460
472
  let set = false;
461
473
  for (const attributeName of attributeNames) {
462
474
  const attributeInfo = this._attributeInfos[attributeName];
@@ -465,7 +477,7 @@ export class Model {
465
477
  set = true;
466
478
  }
467
479
  }
468
- if (!set) {
480
+ if (!set && _option !== 'ignore-unknown') {
469
481
  log.warn(
470
482
  `Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
471
483
  )();
@@ -554,10 +566,56 @@ export class Model {
554
566
  // log.table(logLevel, uniformTable)();
555
567
  log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
556
568
 
569
+ const uniformTable = this.shaderInputs.getDebugTable();
570
+ // Add any global uniforms
571
+ for (const [name, value] of Object.entries(this.uniforms)) {
572
+ uniformTable[name] = {value};
573
+ }
574
+ log.table(LOG_DRAW_PRIORITY, uniformTable)();
575
+
576
+ const attributeTable = this._getAttributeDebugTable();
577
+ log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
578
+ log.table(LOG_DRAW_PRIORITY, attributeTable)();
579
+
557
580
  log.groupEnd(LOG_DRAW_PRIORITY)();
558
581
  this._logOpen = false;
559
582
  }
560
583
  }
584
+
585
+ _getAttributeDebugTable(): Record<string, Record<string, unknown>> {
586
+ const table: Record<string, Record<string, unknown>> = {};
587
+ for (const [name, attributeInfo] of Object.entries(this._attributeInfos)) {
588
+ table[attributeInfo.location] = {
589
+ name,
590
+ type: attributeInfo.shaderType,
591
+ values: this._getBufferOrConstantValues(
592
+ this.vertexArray.attributes[attributeInfo.location],
593
+ attributeInfo.bufferDataType
594
+ )
595
+ };
596
+ }
597
+ if (this.vertexArray.indexBuffer) {
598
+ const {indexBuffer} = this.vertexArray;
599
+ const values =
600
+ indexBuffer.indexType === 'uint32'
601
+ ? new Uint32Array(indexBuffer.debugData)
602
+ : new Uint16Array(indexBuffer.debugData);
603
+ table.indices = {
604
+ name: 'indices',
605
+ type: indexBuffer.indexType,
606
+ values: values.toString()
607
+ };
608
+ }
609
+ return table;
610
+ }
611
+
612
+ // TODO - fix typing of luma data types
613
+ _getBufferOrConstantValues(attribute: Buffer | TypedArray, dataType: any): string {
614
+ const TypedArrayConstructor = getTypedArrayFromDataType(dataType);
615
+ const typedArray =
616
+ attribute instanceof Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
617
+ return typedArray.toString();
618
+ }
561
619
  }
562
620
 
563
621
  // HELPERS
@@ -586,3 +644,10 @@ export function getPlatformInfo(device: Device): PlatformInfo {
586
644
  features: device.features
587
645
  };
588
646
  }
647
+
648
+ /** Get attribute names from a BufferLayout */
649
+ function getAttributeNames(bufferLayout: BufferLayout): string[] {
650
+ return bufferLayout.attributes
651
+ ? bufferLayout.attributes?.map(layout => layout.attribute)
652
+ : [bufferLayout.name];
653
+ }
@@ -91,7 +91,7 @@ export class ShaderInputs<
91
91
  if (!module) {
92
92
  // Ignore props for unregistered modules
93
93
  log.warn(`Module ${name} not found`)();
94
- continue;
94
+ continue; // eslint-disable-line no-continue
95
95
  }
96
96
 
97
97
  const oldUniforms = this.moduleUniforms[moduleName];
@@ -134,4 +134,17 @@ export class ShaderInputs<
134
134
  }
135
135
  return bindings;
136
136
  }
137
+
138
+ getDebugTable(): Record<string, Record<string, unknown>> {
139
+ const table: Record<string,Record<string, unknown>> = {};
140
+ for (const [moduleName, module] of Object.entries(this.moduleUniforms)) {
141
+ for (const [key, value] of Object.entries(module)) {
142
+ table[`${moduleName}.${key}`] = {
143
+ type: this.modules[moduleName].uniformTypes?.[key],
144
+ value: String(value)
145
+ };
146
+ }
147
+ }
148
+ return table;
149
+ }
137
150
  }