@luma.gl/engine 9.2.0-alpha.1 → 9.2.0-alpha.2
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-loop/animation-loop.d.ts +1 -1
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +2 -14
- package/dist/animation-loop/animation-loop.js.map +1 -1
- package/dist/animation-loop/make-animation-loop.d.ts +4 -1
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +39 -7
- package/dist/animation-loop/make-animation-loop.js.map +1 -1
- package/dist/async-texture/async-texture.js.map +1 -1
- package/dist/compute/computation.js +2 -2
- package/dist/compute/computation.js.map +1 -1
- package/dist/dist.dev.js +166 -86
- package/dist/dist.min.js +19 -19
- package/dist/factories/pipeline-factory.js +3 -3
- package/dist/factories/pipeline-factory.js.map +1 -1
- package/dist/factories/shader-factory.js +2 -2
- package/dist/factories/shader-factory.js.map +1 -1
- package/dist/geometries/cube-geometry.d.ts +3 -3
- package/dist/geometries/cube-geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +3 -2
- package/dist/geometry/geometry.js.map +1 -1
- package/dist/index.cjs +177 -101
- package/dist/index.cjs.map +4 -4
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +25 -13
- package/dist/model/model.js.map +1 -1
- package/dist/modules/picking/color-picking.d.ts +1 -1
- package/dist/modules/picking/index-picking.d.ts +1 -1
- package/dist/modules/picking/picking-manager.d.ts +1 -1
- package/dist/modules/picking/picking-manager.d.ts.map +1 -1
- package/dist/modules/picking/picking-manager.js +1 -1
- package/dist/modules/picking/picking-manager.js.map +1 -1
- package/dist/modules/picking/picking-uniforms.d.ts +1 -1
- package/dist/shader-inputs.d.ts +5 -1
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +13 -6
- package/dist/shader-inputs.js.map +1 -1
- package/dist/utils/buffer-layout-helper.d.ts +12 -0
- package/dist/utils/buffer-layout-helper.d.ts.map +1 -0
- package/dist/utils/buffer-layout-helper.js +41 -0
- package/dist/utils/buffer-layout-helper.js.map +1 -0
- package/dist/utils/buffer-layout-order.d.ts +3 -0
- package/dist/utils/buffer-layout-order.d.ts.map +1 -0
- package/dist/utils/buffer-layout-order.js +16 -0
- package/dist/utils/buffer-layout-order.js.map +1 -0
- package/package.json +4 -4
- package/src/animation-loop/animation-loop.ts +2 -14
- package/src/animation-loop/make-animation-loop.ts +41 -9
- package/src/async-texture/async-texture.ts +3 -3
- package/src/compute/computation.ts +2 -2
- package/src/factories/pipeline-factory.ts +3 -3
- package/src/factories/shader-factory.ts +2 -2
- package/src/geometry/geometry.ts +3 -2
- package/src/model/model.ts +33 -15
- package/src/modules/picking/picking-manager.ts +1 -1
- package/src/shader-inputs.ts +21 -6
- package/src/utils/buffer-layout-helper.ts +51 -0
- package/src/utils/buffer-layout-order.ts +26 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {luma, Adapter} from '@luma.gl/core';
|
|
5
|
+
import {luma, Adapter, Device} 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';
|
|
@@ -15,7 +15,10 @@ export type MakeAnimationLoopProps = Omit<
|
|
|
15
15
|
adapters?: Adapter[];
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Instantiates an animation loop and initializes it with the template.
|
|
20
|
+
* @note The application needs to call `start()` on the returned animation loop to start the rendering loop.
|
|
21
|
+
*/
|
|
19
22
|
export function makeAnimationLoop(
|
|
20
23
|
AnimationLoopTemplateCtor: typeof AnimationLoopTemplate,
|
|
21
24
|
props?: MakeAnimationLoopProps
|
|
@@ -33,10 +36,16 @@ export function makeAnimationLoop(
|
|
|
33
36
|
device,
|
|
34
37
|
|
|
35
38
|
async onInitialize(animationProps: AnimationProps): Promise<unknown> {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
clearError(animationProps.animationLoop.device!);
|
|
40
|
+
try {
|
|
41
|
+
// @ts-expect-error abstract to prevent instantiation
|
|
42
|
+
renderLoop = new AnimationLoopTemplateCtor(animationProps);
|
|
43
|
+
// Any async loading can be handled here
|
|
44
|
+
return await renderLoop?.onInitialize(animationProps);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
setError(animationProps.animationLoop.device!, error as Error);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
40
49
|
},
|
|
41
50
|
|
|
42
51
|
onRender: (animationProps: AnimationProps) => renderLoop?.onRender(animationProps),
|
|
@@ -51,8 +60,31 @@ export function makeAnimationLoop(
|
|
|
51
60
|
return this.AnimationLoopTemplateCtor.info;
|
|
52
61
|
};
|
|
53
62
|
|
|
54
|
-
// Start the loop automatically
|
|
55
|
-
// animationLoop.start();
|
|
56
|
-
|
|
57
63
|
return animationLoop;
|
|
58
64
|
}
|
|
65
|
+
|
|
66
|
+
function setError(device: Device, error: Error): void {
|
|
67
|
+
const canvas = device?.getDefaultCanvasContext().canvas;
|
|
68
|
+
if (canvas instanceof HTMLCanvasElement) {
|
|
69
|
+
canvas.style.overflow = 'visible';
|
|
70
|
+
let errorDiv = document.getElementById('animation-loop-error');
|
|
71
|
+
errorDiv?.remove();
|
|
72
|
+
errorDiv = document.createElement('h1');
|
|
73
|
+
errorDiv.id = 'animation-loop-error';
|
|
74
|
+
errorDiv.innerHTML = error.message;
|
|
75
|
+
errorDiv.style.position = 'absolute';
|
|
76
|
+
errorDiv.style.top = '10px'; // left: 50%; transform: translate(-50%, -50%);';
|
|
77
|
+
errorDiv.style.left = '10px';
|
|
78
|
+
errorDiv.style.color = 'black';
|
|
79
|
+
errorDiv.style.backgroundColor = 'red';
|
|
80
|
+
canvas.parentElement?.appendChild(errorDiv);
|
|
81
|
+
// canvas.style.position = 'absolute';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function clearError(device: Device): void {
|
|
86
|
+
const errorDiv = document.getElementById('animation-loop-error');
|
|
87
|
+
if (errorDiv) {
|
|
88
|
+
errorDiv.remove();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -212,7 +212,7 @@ export class AsyncTexture {
|
|
|
212
212
|
this._setTexture1DData(this.texture, data as Texture1DData);
|
|
213
213
|
break;
|
|
214
214
|
case '2d':
|
|
215
|
-
this._setTexture2DData(data
|
|
215
|
+
this._setTexture2DData(data);
|
|
216
216
|
break;
|
|
217
217
|
case '3d':
|
|
218
218
|
this._setTexture3DData(this.texture, data as Texture3DData);
|
|
@@ -308,8 +308,8 @@ export class AsyncTexture {
|
|
|
308
308
|
return this.device.getExternalImageSize(data);
|
|
309
309
|
}
|
|
310
310
|
if (data && typeof data === 'object' && data.constructor === Object) {
|
|
311
|
-
const textureDataArray = Object.values(data)
|
|
312
|
-
const untypedData = textureDataArray[0]
|
|
311
|
+
const textureDataArray = Object.values(data);
|
|
312
|
+
const untypedData = textureDataArray[0];
|
|
313
313
|
return {width: untypedData.width, height: untypedData.height};
|
|
314
314
|
}
|
|
315
315
|
throw new Error('texture size deduction failed');
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
ComputePass,
|
|
11
11
|
UniformStore,
|
|
12
12
|
log,
|
|
13
|
-
|
|
13
|
+
getTypedArrayConstructor
|
|
14
14
|
} from '@luma.gl/core';
|
|
15
15
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
16
16
|
import {ShaderAssembler, getShaderLayoutFromWGSL} from '@luma.gl/shadertools';
|
|
@@ -340,7 +340,7 @@ export class Computation {
|
|
|
340
340
|
|
|
341
341
|
// TODO - fix typing of luma data types
|
|
342
342
|
_getBufferOrConstantValues(attribute: Buffer | TypedArray, dataType: any): string {
|
|
343
|
-
const TypedArrayConstructor =
|
|
343
|
+
const TypedArrayConstructor = getTypedArrayConstructor(dataType);
|
|
344
344
|
const typedArray =
|
|
345
345
|
attribute instanceof Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
346
346
|
return typedArray.toString();
|
|
@@ -19,9 +19,9 @@ export class PipelineFactory {
|
|
|
19
19
|
|
|
20
20
|
/** Get the singleton default pipeline factory for the specified device */
|
|
21
21
|
static getDefaultPipelineFactory(device: Device): PipelineFactory {
|
|
22
|
-
device._lumaData
|
|
23
|
-
device._lumaData
|
|
24
|
-
return device._lumaData
|
|
22
|
+
device._lumaData['defaultPipelineFactory'] =
|
|
23
|
+
device._lumaData['defaultPipelineFactory'] || new PipelineFactory(device);
|
|
24
|
+
return device._lumaData['defaultPipelineFactory'] as PipelineFactory;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
readonly device: Device;
|
|
@@ -10,8 +10,8 @@ export class ShaderFactory {
|
|
|
10
10
|
|
|
11
11
|
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
12
12
|
static getDefaultShaderFactory(device: Device): ShaderFactory {
|
|
13
|
-
device._lumaData
|
|
14
|
-
return device._lumaData
|
|
13
|
+
device._lumaData['defaultShaderFactory'] ||= new ShaderFactory(device);
|
|
14
|
+
return device._lumaData['defaultShaderFactory'] as ShaderFactory;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
public readonly device: Device;
|
package/src/geometry/geometry.ts
CHANGED
|
@@ -86,9 +86,9 @@ export class Geometry {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if (this.indices && this.indices
|
|
89
|
+
if (this.indices && this.indices['isIndexed'] !== undefined) {
|
|
90
90
|
this.indices = Object.assign({}, this.indices);
|
|
91
|
-
delete this.indices
|
|
91
|
+
delete this.indices['isIndexed'];
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
|
|
@@ -103,6 +103,7 @@ export class Geometry {
|
|
|
103
103
|
* TODO Geometry types are a mess
|
|
104
104
|
*/
|
|
105
105
|
getAttributes(): GeometryAttributes {
|
|
106
|
+
// @ts-ignore
|
|
106
107
|
return this.indices ? {indices: this.indices, ...this.attributes} : this.attributes;
|
|
107
108
|
}
|
|
108
109
|
|
package/src/model/model.ts
CHANGED
|
@@ -26,9 +26,8 @@ import {
|
|
|
26
26
|
RenderPass,
|
|
27
27
|
UniformStore,
|
|
28
28
|
log,
|
|
29
|
-
|
|
30
|
-
getAttributeInfosFromLayouts
|
|
31
|
-
_BufferLayoutHelper
|
|
29
|
+
getTypedArrayConstructor,
|
|
30
|
+
getAttributeInfosFromLayouts
|
|
32
31
|
} from '@luma.gl/core';
|
|
33
32
|
|
|
34
33
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
@@ -41,6 +40,8 @@ import {ShaderFactory} from '../factories/shader-factory';
|
|
|
41
40
|
import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
|
|
42
41
|
import {debugFramebuffer} from '../debug/debug-framebuffer';
|
|
43
42
|
import {deepEqual} from '../utils/deep-equal';
|
|
43
|
+
import {BufferLayoutHelper} from '../utils/buffer-layout-helper';
|
|
44
|
+
import {sortedBufferLayoutByShaderSourceLocations} from '../utils/buffer-layout-order';
|
|
44
45
|
import {uid} from '../utils/uid';
|
|
45
46
|
import {ShaderInputs} from '../shader-inputs';
|
|
46
47
|
import {AsyncTexture} from '../async-texture/async-texture';
|
|
@@ -230,15 +231,19 @@ export class Model {
|
|
|
230
231
|
const moduleMap = Object.fromEntries(
|
|
231
232
|
this.props.modules?.map(module => [module.name, module]) || []
|
|
232
233
|
);
|
|
233
|
-
|
|
234
|
-
|
|
234
|
+
|
|
235
|
+
const shaderInputs =
|
|
236
|
+
props.shaderInputs ||
|
|
237
|
+
new ShaderInputs(moduleMap, {disableWarnings: this.props.disableWarnings});
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
this.setShaderInputs(shaderInputs);
|
|
235
240
|
|
|
236
241
|
// Setup shader assembler
|
|
237
242
|
const platformInfo = getPlatformInfo(device);
|
|
238
243
|
|
|
239
244
|
// Extract modules from shader inputs if not supplied
|
|
240
245
|
const modules =
|
|
241
|
-
// @ts-
|
|
246
|
+
// @ts-ignore shaderInputs is assigned in setShaderInputs above.
|
|
242
247
|
(this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
243
248
|
|
|
244
249
|
const isWebGPU = this.device.type === 'webgpu';
|
|
@@ -248,7 +253,6 @@ export class Model {
|
|
|
248
253
|
// TODO - this is wrong, compile a single shader
|
|
249
254
|
if (isWebGPU && this.props.source) {
|
|
250
255
|
// WGSL
|
|
251
|
-
this.props.shaderLayout ||= getShaderLayoutFromWGSL(this.props.source);
|
|
252
256
|
const {source, getUniforms} = this.props.shaderAssembler.assembleWGSLShader({
|
|
253
257
|
platformInfo,
|
|
254
258
|
...this.props,
|
|
@@ -257,6 +261,8 @@ export class Model {
|
|
|
257
261
|
this.source = source;
|
|
258
262
|
// @ts-expect-error
|
|
259
263
|
this._getModuleUniforms = getUniforms;
|
|
264
|
+
// Extract shader layout after modules have been added to WGSL source, to include any bindings added by modules
|
|
265
|
+
this.props.shaderLayout ||= getShaderLayoutFromWGSL(this.source);
|
|
260
266
|
} else {
|
|
261
267
|
// GLSL
|
|
262
268
|
const {vs, fs, getUniforms} = this.props.shaderAssembler.assembleGLSLShaderPair({
|
|
@@ -453,7 +459,7 @@ export class Model {
|
|
|
453
459
|
const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
|
|
454
460
|
if (gpuGeometry) {
|
|
455
461
|
this.setTopology(gpuGeometry.topology || 'triangle-list');
|
|
456
|
-
const bufferLayoutHelper = new
|
|
462
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
457
463
|
this.bufferLayout = bufferLayoutHelper.mergeBufferLayouts(
|
|
458
464
|
gpuGeometry.bufferLayout,
|
|
459
465
|
this.bufferLayout
|
|
@@ -481,7 +487,7 @@ export class Model {
|
|
|
481
487
|
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
482
488
|
*/
|
|
483
489
|
setBufferLayout(bufferLayout: BufferLayout[]): void {
|
|
484
|
-
const bufferLayoutHelper = new
|
|
490
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
485
491
|
this.bufferLayout = this._gpuGeometry
|
|
486
492
|
? bufferLayoutHelper.mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout)
|
|
487
493
|
: bufferLayout;
|
|
@@ -593,13 +599,19 @@ export class Model {
|
|
|
593
599
|
*/
|
|
594
600
|
setAttributes(buffers: Record<string, Buffer>, options?: {disableWarnings?: boolean}): void {
|
|
595
601
|
const disableWarnings = options?.disableWarnings ?? this.props.disableWarnings;
|
|
596
|
-
if (buffers
|
|
602
|
+
if (buffers['indices']) {
|
|
597
603
|
log.warn(
|
|
598
604
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
599
605
|
)();
|
|
600
606
|
}
|
|
601
607
|
|
|
602
|
-
|
|
608
|
+
// ensure bufferLayout order matches source layout so we bind
|
|
609
|
+
// the correct buffers to the correct indices in webgpu.
|
|
610
|
+
this.bufferLayout = sortedBufferLayoutByShaderSourceLocations(
|
|
611
|
+
this.pipeline.shaderLayout,
|
|
612
|
+
this.bufferLayout
|
|
613
|
+
);
|
|
614
|
+
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
603
615
|
|
|
604
616
|
// Check if all buffers have a layout
|
|
605
617
|
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
@@ -611,13 +623,19 @@ export class Model {
|
|
|
611
623
|
continue; // eslint-disable-line no-continue
|
|
612
624
|
}
|
|
613
625
|
|
|
614
|
-
//
|
|
626
|
+
// In WebGL, for an interleaved attribute we may need to set multiple attributes
|
|
627
|
+
// but in WebGPU, we set it according to the buffer's position in the vertexArray
|
|
615
628
|
const attributeNames = bufferLayoutHelper.getAttributeNamesForBuffer(bufferLayout);
|
|
616
629
|
let set = false;
|
|
617
630
|
for (const attributeName of attributeNames) {
|
|
618
631
|
const attributeInfo = this._attributeInfos[attributeName];
|
|
619
632
|
if (attributeInfo) {
|
|
620
|
-
|
|
633
|
+
const location =
|
|
634
|
+
this.device.type === 'webgpu'
|
|
635
|
+
? bufferLayoutHelper.getBufferIndex(attributeInfo.bufferName)
|
|
636
|
+
: attributeInfo.location;
|
|
637
|
+
|
|
638
|
+
this.vertexArray.setBuffer(location, buffer);
|
|
621
639
|
set = true;
|
|
622
640
|
}
|
|
623
641
|
}
|
|
@@ -867,7 +885,7 @@ export class Model {
|
|
|
867
885
|
indexBuffer.indexType === 'uint32'
|
|
868
886
|
? new Uint32Array(indexBuffer.debugData)
|
|
869
887
|
: new Uint16Array(indexBuffer.debugData);
|
|
870
|
-
table
|
|
888
|
+
table['indices'] = {
|
|
871
889
|
name: 'indices',
|
|
872
890
|
type: indexBuffer.indexType,
|
|
873
891
|
values: values.toString()
|
|
@@ -878,7 +896,7 @@ export class Model {
|
|
|
878
896
|
|
|
879
897
|
// TODO - fix typing of luma data types
|
|
880
898
|
_getBufferOrConstantValues(attribute: Buffer | TypedArray, dataType: any): string {
|
|
881
|
-
const TypedArrayConstructor =
|
|
899
|
+
const TypedArrayConstructor = getTypedArrayConstructor(dataType);
|
|
882
900
|
const typedArray =
|
|
883
901
|
attribute instanceof Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
884
902
|
return typedArray.toString();
|
|
@@ -80,7 +80,7 @@ export class PickingManager {
|
|
|
80
80
|
return pickingPass;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
async updatePickInfo(mousePosition: [number, number]): Promise<PickInfo | null> {
|
|
84
84
|
const framebuffer = this.getFramebuffer();
|
|
85
85
|
|
|
86
86
|
// use the center pixel location in device pixel range
|
package/src/shader-inputs.ts
CHANGED
|
@@ -8,6 +8,10 @@ import {log} from '@luma.gl/core';
|
|
|
8
8
|
import {getShaderModuleDependencies, ShaderModule} from '@luma.gl/shadertools';
|
|
9
9
|
import {splitUniformsAndBindings} from './model/split-uniforms-and-bindings';
|
|
10
10
|
|
|
11
|
+
export type ShaderInputsOptions = {
|
|
12
|
+
disableWarnings?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
11
15
|
/**
|
|
12
16
|
* ShaderInputs holds uniform and binding values for one or more shader modules,
|
|
13
17
|
* - It can generate binary data for any uniform buffer
|
|
@@ -20,11 +24,15 @@ export class ShaderInputs<
|
|
|
20
24
|
Record<string, Record<string, unknown>>
|
|
21
25
|
>
|
|
22
26
|
> {
|
|
27
|
+
options: Required<ShaderInputsOptions> = {
|
|
28
|
+
disableWarnings: false
|
|
29
|
+
};
|
|
30
|
+
|
|
23
31
|
/**
|
|
24
32
|
* The map of modules
|
|
25
33
|
* @todo should should this include the resolved dependencies?
|
|
26
34
|
*/
|
|
27
|
-
// @ts-
|
|
35
|
+
// @ts-ignore Fix typings
|
|
28
36
|
modules: Readonly<{[P in keyof ShaderPropsT]: ShaderModule<ShaderPropsT[P]>}>;
|
|
29
37
|
|
|
30
38
|
/** Stores the uniform values for each module */
|
|
@@ -38,8 +46,13 @@ export class ShaderInputs<
|
|
|
38
46
|
* Create a new UniformStore instance
|
|
39
47
|
* @param modules
|
|
40
48
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
constructor(
|
|
50
|
+
// @ts-ignore Fix typings
|
|
51
|
+
modules: {[P in keyof ShaderPropsT]?: ShaderModule<ShaderPropsT[P], any>},
|
|
52
|
+
options?: ShaderInputsOptions
|
|
53
|
+
) {
|
|
54
|
+
Object.assign(this.options, options);
|
|
55
|
+
|
|
43
56
|
// Extract modules with dependencies
|
|
44
57
|
const resolvedModules = getShaderModuleDependencies(
|
|
45
58
|
Object.values(modules).filter(module => module.dependencies)
|
|
@@ -52,7 +65,7 @@ export class ShaderInputs<
|
|
|
52
65
|
log.log(1, 'Creating ShaderInputs with modules', Object.keys(modules))();
|
|
53
66
|
|
|
54
67
|
// Store the module definitions and create storage for uniform values and binding values, per module
|
|
55
|
-
// @ts-
|
|
68
|
+
// @ts-ignore Fix typings
|
|
56
69
|
this.modules = modules as {[P in keyof ShaderPropsT]: ShaderModule<ShaderPropsT[P]>};
|
|
57
70
|
this.moduleUniforms = {} as Record<keyof ShaderPropsT, Record<string, UniformValue>>;
|
|
58
71
|
this.moduleBindings = {} as Record<keyof ShaderPropsT, Record<string, Binding>>;
|
|
@@ -60,7 +73,7 @@ export class ShaderInputs<
|
|
|
60
73
|
// Initialize the modules
|
|
61
74
|
for (const [name, module] of Object.entries(modules)) {
|
|
62
75
|
this._addModule(module);
|
|
63
|
-
if (module.name && name !== module.name) {
|
|
76
|
+
if (module.name && name !== module.name && !this.options.disableWarnings) {
|
|
64
77
|
log.warn(`Module name: ${name} vs ${module.name}`)();
|
|
65
78
|
}
|
|
66
79
|
}
|
|
@@ -79,7 +92,9 @@ export class ShaderInputs<
|
|
|
79
92
|
const module = this.modules[moduleName];
|
|
80
93
|
if (!module) {
|
|
81
94
|
// Ignore props for unregistered modules
|
|
82
|
-
|
|
95
|
+
if (!this.options.disableWarnings) {
|
|
96
|
+
log.warn(`Module ${name} not found`)();
|
|
97
|
+
}
|
|
83
98
|
continue; // eslint-disable-line no-continue
|
|
84
99
|
}
|
|
85
100
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {log, type BufferLayout} from '@luma.gl/core';
|
|
6
|
+
|
|
7
|
+
/** BufferLayoutHelper is a helper class that should not be used directly by applications */
|
|
8
|
+
export class BufferLayoutHelper {
|
|
9
|
+
bufferLayouts: BufferLayout[];
|
|
10
|
+
|
|
11
|
+
constructor(bufferLayouts: BufferLayout[]) {
|
|
12
|
+
this.bufferLayouts = bufferLayouts;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getBufferLayout(name: string): BufferLayout | null {
|
|
16
|
+
return this.bufferLayouts.find(layout => layout.name === name) || null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get attribute names from a BufferLayout */
|
|
20
|
+
getAttributeNamesForBuffer(bufferLayout: BufferLayout): string[] {
|
|
21
|
+
return bufferLayout.attributes
|
|
22
|
+
? bufferLayout.attributes?.map(layout => layout.attribute)
|
|
23
|
+
: [bufferLayout.name];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
mergeBufferLayouts(
|
|
27
|
+
bufferLayouts1: BufferLayout[],
|
|
28
|
+
bufferLayouts2: BufferLayout[]
|
|
29
|
+
): BufferLayout[] {
|
|
30
|
+
const mergedLayouts = [...bufferLayouts1];
|
|
31
|
+
for (const attribute of bufferLayouts2) {
|
|
32
|
+
const index = mergedLayouts.findIndex(attribute2 => attribute2.name === attribute.name);
|
|
33
|
+
if (index < 0) {
|
|
34
|
+
mergedLayouts.push(attribute);
|
|
35
|
+
} else {
|
|
36
|
+
mergedLayouts[index] = attribute;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return mergedLayouts;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getBufferIndex(bufferName: string): number {
|
|
43
|
+
const bufferIndex = this.bufferLayouts.findIndex(layout => layout.name === bufferName);
|
|
44
|
+
|
|
45
|
+
if (bufferIndex === -1) {
|
|
46
|
+
log.warn(`BufferLayout: Missing buffer for "${bufferName}".`)();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return bufferIndex;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {type BufferLayout, type ShaderLayout} from '@luma.gl/core';
|
|
6
|
+
|
|
7
|
+
export function sortedBufferLayoutByShaderSourceLocations(
|
|
8
|
+
shaderLayout: ShaderLayout,
|
|
9
|
+
bufferLayout: BufferLayout[]
|
|
10
|
+
): BufferLayout[] {
|
|
11
|
+
const shaderLayoutMap = Object.fromEntries(
|
|
12
|
+
shaderLayout.attributes.map(attr => [attr.name, attr.location])
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const sortedLayout = bufferLayout.slice();
|
|
16
|
+
sortedLayout.sort((a, b) => {
|
|
17
|
+
const attributeNamesA = a.attributes ? a.attributes.map(attr => attr.attribute) : [a.name];
|
|
18
|
+
const attributeNamesB = b.attributes ? b.attributes.map(attr => attr.attribute) : [b.name];
|
|
19
|
+
const minLocationA = Math.min(...attributeNamesA.map(name => shaderLayoutMap[name]));
|
|
20
|
+
const minLocationB = Math.min(...attributeNamesB.map(name => shaderLayoutMap[name]));
|
|
21
|
+
|
|
22
|
+
return minLocationA - minLocationB;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return sortedLayout;
|
|
26
|
+
}
|