@luma.gl/engine 9.0.0-beta.5 → 9.0.0-beta.6
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/timeline.d.ts.map +1 -1
- package/dist/animation/timeline.js +3 -3
- package/dist/animation-loop/animation-loop-template.d.ts +1 -1
- package/dist/animation-loop/animation-loop-template.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop-template.js +3 -1
- package/dist/animation-loop/animation-loop.d.ts +2 -2
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +14 -6
- package/dist/animation-loop/animation-props.d.ts +2 -2
- package/dist/animation-loop/animation-props.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.d.ts +2 -2
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +4 -2
- package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
- package/dist/debug/copy-texture-to-image.js +4 -1
- package/dist/debug/debug-framebuffer.d.ts.map +1 -1
- package/dist/debug/debug-framebuffer.js +0 -1
- package/dist/debug/pixel-data-utils.d.ts.map +1 -1
- package/dist/debug/pixel-data-utils.js +2 -1
- package/dist/dist.dev.js +210 -121
- package/dist/geometries/cone-geometry.d.ts +1 -1
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js +1 -1
- package/dist/geometries/cube-geometry.d.ts +1 -1
- package/dist/geometries/cube-geometry.d.ts.map +1 -1
- package/dist/geometries/cube-geometry.js +16 -14
- package/dist/geometries/cylinder-geometry.d.ts +1 -1
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js +1 -1
- package/dist/geometries/ico-sphere-geometry.d.ts +1 -1
- package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/ico-sphere-geometry.js +1 -1
- package/dist/geometries/plane-geometry.d.ts +1 -1
- package/dist/geometries/plane-geometry.d.ts.map +1 -1
- package/dist/geometries/plane-geometry.js +2 -2
- package/dist/geometries/sphere-geometry.d.ts +1 -1
- package/dist/geometries/sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/sphere-geometry.js +1 -1
- package/dist/geometries/truncated-cone-geometry.d.ts +1 -1
- package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +1 -1
- package/dist/geometry/geometry-table.d.ts.map +1 -1
- package/dist/geometry/geometry-table.js +3 -0
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +3 -0
- package/dist/geometry/gpu-geometry.d.ts +1 -1
- package/dist/geometry/gpu-geometry.d.ts.map +1 -1
- package/dist/index.cjs +171 -89
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +41 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -23
- package/dist/lib/clip-space.d.ts +1 -1
- package/dist/lib/clip-space.d.ts.map +1 -1
- package/dist/lib/clip-space.js +3 -3
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +3 -0
- package/dist/lib/shader-factory.d.ts +17 -0
- package/dist/lib/shader-factory.d.ts.map +1 -0
- package/dist/lib/shader-factory.js +44 -0
- package/dist/model/model.d.ts +20 -8
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +52 -26
- package/dist/scenegraph/group-node.d.ts +1 -1
- package/dist/scenegraph/group-node.d.ts.map +1 -1
- package/dist/scenegraph/group-node.js +10 -5
- package/dist/scenegraph/model-node.d.ts +2 -2
- package/dist/scenegraph/model-node.d.ts.map +1 -1
- package/dist/scenegraph/model-node.js +2 -2
- package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +3 -0
- package/dist/transform/buffer-transform.d.ts +1 -1
- package/dist/transform/buffer-transform.d.ts.map +1 -1
- package/dist/transform/buffer-transform.js +7 -6
- package/dist/transform/texture-transform.d.ts +1 -1
- package/dist/transform/texture-transform.d.ts.map +1 -1
- package/dist/transform/texture-transform.js +10 -8
- package/dist.min.js +2 -2
- package/package.json +2 -2
- package/src/animation/timeline.ts +20 -20
- package/src/animation-loop/animation-loop-template.ts +10 -8
- package/src/animation-loop/animation-loop.ts +20 -10
- package/src/animation-loop/animation-props.ts +1 -1
- package/src/animation-loop/make-animation-loop.ts +17 -8
- package/src/debug/copy-texture-to-image.ts +8 -6
- package/src/debug/debug-framebuffer.ts +16 -3
- package/src/debug/debug-shader-layout.ts +1 -1
- package/src/debug/pixel-data-utils.ts +3 -6
- package/src/geometries/cube-geometry.ts +17 -13
- package/src/geometries/ico-sphere-geometry.ts +1 -1
- package/src/geometries/plane-geometry.ts +1 -1
- package/src/geometries/sphere-geometry.ts +1 -1
- package/src/geometries/truncated-cone-geometry.ts +2 -1
- package/src/geometry/geometry-table.ts +9 -6
- package/src/geometry/geometry-utils.ts +1 -1
- package/src/geometry/geometry.ts +9 -6
- package/src/geometry/gpu-geometry.ts +14 -6
- package/src/index.ts +1 -0
- package/src/lib/clip-space.ts +14 -18
- package/src/lib/pipeline-factory.ts +4 -1
- package/src/lib/shader-factory.ts +55 -0
- package/src/model/model.ts +70 -38
- package/src/scenegraph/group-node.ts +14 -10
- package/src/scenegraph/model-node.ts +2 -2
- package/src/scenegraph/scenegraph-node.ts +2 -2
- package/src/shader-inputs.ts +19 -12
- package/src/transform/buffer-transform.ts +15 -7
- package/src/transform/texture-transform.ts +14 -13
package/src/model/model.ts
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
2
3
|
// Copyright (c) vis.gl contributors
|
|
3
4
|
|
|
4
|
-
import type {TypedArray
|
|
5
|
-
import type {
|
|
5
|
+
import type {TypedArray} from '@luma.gl/core';
|
|
6
|
+
import type {DeviceFeature, RenderPipelineProps, RenderPipelineParameters} from '@luma.gl/core';
|
|
7
|
+
import type {Shader, BufferLayout, VertexArray, TransformFeedback} from '@luma.gl/core';
|
|
6
8
|
import type {AttributeInfo, Binding, UniformValue, PrimitiveTopology} from '@luma.gl/core';
|
|
7
|
-
import {
|
|
8
|
-
Device,
|
|
9
|
-
Buffer,
|
|
10
|
-
RenderPipeline,
|
|
11
|
-
RenderPass,
|
|
12
|
-
UniformStore,
|
|
13
|
-
getTypedArrayFromDataType
|
|
14
|
-
} from '@luma.gl/core';
|
|
9
|
+
import {Device, Buffer, RenderPipeline, RenderPass, UniformStore} from '@luma.gl/core';
|
|
15
10
|
import {log, uid, deepEqual, splitUniformsAndBindings, isNumberArray} from '@luma.gl/core';
|
|
16
|
-
import {getAttributeInfosFromLayouts} from '@luma.gl/core';
|
|
11
|
+
import {getTypedArrayFromDataType, getAttributeInfosFromLayouts} from '@luma.gl/core';
|
|
17
12
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
18
13
|
import {ShaderAssembler, getShaderLayoutFromWGSL} from '@luma.gl/shadertools';
|
|
19
14
|
import {ShaderInputs} from '../shader-inputs';
|
|
20
15
|
import type {Geometry} from '../geometry/geometry';
|
|
21
16
|
import {GPUGeometry, makeGPUGeometry} from '../geometry/gpu-geometry';
|
|
22
17
|
import {PipelineFactory} from '../lib/pipeline-factory';
|
|
18
|
+
import {ShaderFactory} from '../lib/shader-factory';
|
|
23
19
|
import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
|
|
24
20
|
import {debugFramebuffer} from '../debug/debug-framebuffer';
|
|
25
21
|
|
|
@@ -30,6 +26,7 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
30
26
|
source?: string;
|
|
31
27
|
vs: {glsl?: string; wgsl?: string} | string | null;
|
|
32
28
|
fs: {glsl?: string; wgsl?: string} | string | null;
|
|
29
|
+
|
|
33
30
|
/** shadertool shader modules (added to shader code) */
|
|
34
31
|
modules?: ShaderModule[];
|
|
35
32
|
/** Shadertool module defines (configures shader code)*/
|
|
@@ -38,8 +35,10 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
38
35
|
|
|
39
36
|
/** Shader inputs, used to generated uniform buffers and bindings */
|
|
40
37
|
shaderInputs?: ShaderInputs;
|
|
41
|
-
/**
|
|
38
|
+
/** Factory used to create a {@link RenderPipeline}. Defaults to {@link Device} default factory. */
|
|
42
39
|
pipelineFactory?: PipelineFactory;
|
|
40
|
+
/** Factory used to create a {@link Shader}. Defaults to {@link Device} default factory. */
|
|
41
|
+
shaderFactory?: ShaderFactory;
|
|
43
42
|
/** Shader assembler. Defaults to the ShaderAssembler.getShaderAssembler() */
|
|
44
43
|
shaderAssembler?: ShaderAssembler;
|
|
45
44
|
|
|
@@ -59,6 +58,8 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
59
58
|
attributes?: Record<string, Buffer>;
|
|
60
59
|
/** */
|
|
61
60
|
constantAttributes?: Record<string, TypedArray>;
|
|
61
|
+
/** Some applications intentionally supply unused attributes */
|
|
62
|
+
ignoreUnknownAttributes?: boolean;
|
|
62
63
|
|
|
63
64
|
/** @internal For use with {@link TransformFeedback}, WebGL only. */
|
|
64
65
|
varyings?: string[];
|
|
@@ -67,6 +68,9 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
67
68
|
|
|
68
69
|
/** Mapped uniforms for shadertool modules */
|
|
69
70
|
moduleSettings?: Record<string, Record<string, any>>;
|
|
71
|
+
|
|
72
|
+
/** Show shader source in browser? */
|
|
73
|
+
debugShaders?: 'never' | 'errors' | 'warnings' | 'always';
|
|
70
74
|
};
|
|
71
75
|
|
|
72
76
|
/**
|
|
@@ -97,8 +101,12 @@ export class Model {
|
|
|
97
101
|
|
|
98
102
|
shaderInputs: undefined!,
|
|
99
103
|
pipelineFactory: undefined!,
|
|
104
|
+
shaderFactory: undefined!,
|
|
100
105
|
transformFeedback: undefined,
|
|
101
|
-
shaderAssembler: ShaderAssembler.getDefaultShaderAssembler()
|
|
106
|
+
shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(),
|
|
107
|
+
|
|
108
|
+
debugShaders: undefined,
|
|
109
|
+
ignoreUnknownAttributes: undefined
|
|
102
110
|
};
|
|
103
111
|
|
|
104
112
|
readonly device: Device;
|
|
@@ -106,6 +114,7 @@ export class Model {
|
|
|
106
114
|
readonly vs: string;
|
|
107
115
|
readonly fs: string;
|
|
108
116
|
readonly pipelineFactory: PipelineFactory;
|
|
117
|
+
readonly shaderFactory: ShaderFactory;
|
|
109
118
|
userData: {[key: string]: any} = {};
|
|
110
119
|
|
|
111
120
|
// Fixed properties (change can trigger pipeline rebuild)
|
|
@@ -160,6 +169,8 @@ export class Model {
|
|
|
160
169
|
private _getModuleUniforms: (props?: Record<string, Record<string, any>>) => Record<string, any>;
|
|
161
170
|
private props: Required<ModelProps>;
|
|
162
171
|
|
|
172
|
+
private _destroyed = false;
|
|
173
|
+
|
|
163
174
|
constructor(device: Device, props: ModelProps) {
|
|
164
175
|
this.props = {...Model.defaultProps, ...props};
|
|
165
176
|
props = this.props;
|
|
@@ -221,6 +232,7 @@ export class Model {
|
|
|
221
232
|
|
|
222
233
|
this.pipelineFactory =
|
|
223
234
|
props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
235
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
224
236
|
|
|
225
237
|
// Create the pipeline
|
|
226
238
|
// @note order is important
|
|
@@ -250,7 +262,9 @@ export class Model {
|
|
|
250
262
|
this.setIndexBuffer(props.indexBuffer);
|
|
251
263
|
}
|
|
252
264
|
if (props.attributes) {
|
|
253
|
-
this.setAttributes(props.attributes
|
|
265
|
+
this.setAttributes(props.attributes, {
|
|
266
|
+
ignoreUnknownAttributes: props.ignoreUnknownAttributes
|
|
267
|
+
});
|
|
254
268
|
}
|
|
255
269
|
if (props.constantAttributes) {
|
|
256
270
|
this.setConstantAttributes(props.constantAttributes);
|
|
@@ -269,16 +283,17 @@ export class Model {
|
|
|
269
283
|
this.transformFeedback = props.transformFeedback;
|
|
270
284
|
}
|
|
271
285
|
|
|
272
|
-
// TODO - restore?
|
|
273
|
-
// this.setUniforms(this._getModuleUniforms()); // Get all default module uniforms
|
|
274
|
-
|
|
275
286
|
// Catch any access to non-standard props
|
|
276
287
|
Object.seal(this);
|
|
277
288
|
}
|
|
278
289
|
|
|
279
290
|
destroy(): void {
|
|
291
|
+
if (this._destroyed) return;
|
|
280
292
|
this.pipelineFactory.release(this.pipeline);
|
|
293
|
+
this.shaderFactory.release(this.pipeline.vs);
|
|
294
|
+
this.shaderFactory.release(this.pipeline.fs);
|
|
281
295
|
this._uniformStore.destroy();
|
|
296
|
+
this._destroyed = true;
|
|
282
297
|
}
|
|
283
298
|
|
|
284
299
|
// Draw call
|
|
@@ -301,11 +316,13 @@ export class Model {
|
|
|
301
316
|
// Set pipeline state, we may be sharing a pipeline so we need to set all state on every draw
|
|
302
317
|
// Any caching needs to be done inside the pipeline functions
|
|
303
318
|
this.pipeline.setBindings(this.bindings);
|
|
304
|
-
this.pipeline.
|
|
319
|
+
this.pipeline.setUniformsWebGL(this.uniforms);
|
|
305
320
|
|
|
306
321
|
const {indexBuffer} = this.vertexArray;
|
|
307
|
-
const indexCount = indexBuffer
|
|
308
|
-
|
|
322
|
+
const indexCount = indexBuffer
|
|
323
|
+
? indexBuffer.byteLength / (indexBuffer.indexType === 'uint32' ? 4 : 2)
|
|
324
|
+
: undefined;
|
|
325
|
+
|
|
309
326
|
this.pipeline.draw({
|
|
310
327
|
renderPass,
|
|
311
328
|
vertexArray: this.vertexArray,
|
|
@@ -357,8 +374,8 @@ export class Model {
|
|
|
357
374
|
// TODO - delete previous geometry?
|
|
358
375
|
this.vertexCount = gpuGeometry.vertexCount;
|
|
359
376
|
this.setIndexBuffer(gpuGeometry.indices);
|
|
360
|
-
this.setAttributes(gpuGeometry.attributes,
|
|
361
|
-
this.setAttributes(attributes);
|
|
377
|
+
this.setAttributes(gpuGeometry.attributes, {ignoreUnknownAttributes: true});
|
|
378
|
+
this.setAttributes(attributes, {ignoreUnknownAttributes: this.props.ignoreUnknownAttributes});
|
|
362
379
|
}
|
|
363
380
|
|
|
364
381
|
/**
|
|
@@ -374,7 +391,7 @@ export class Model {
|
|
|
374
391
|
|
|
375
392
|
/**
|
|
376
393
|
* Updates the buffer layout.
|
|
377
|
-
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
394
|
+
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
378
395
|
*/
|
|
379
396
|
setBufferLayout(bufferLayout: BufferLayout[]): void {
|
|
380
397
|
this.bufferLayout = this._gpuGeometry
|
|
@@ -484,7 +501,7 @@ export class Model {
|
|
|
484
501
|
* @returns self for chaining
|
|
485
502
|
*/
|
|
486
503
|
setUniforms(uniforms: Record<string, UniformValue>): void {
|
|
487
|
-
this.pipeline.
|
|
504
|
+
this.pipeline.setUniformsWebGL(uniforms);
|
|
488
505
|
Object.assign(this.uniforms, uniforms);
|
|
489
506
|
}
|
|
490
507
|
|
|
@@ -507,14 +524,19 @@ export class Model {
|
|
|
507
524
|
* Sets attributes (buffers)
|
|
508
525
|
* @note Overrides any attributes previously set with the same name
|
|
509
526
|
*/
|
|
510
|
-
setAttributes(
|
|
527
|
+
setAttributes(
|
|
528
|
+
buffers: Record<string, Buffer>,
|
|
529
|
+
options?: {ignoreUnknownAttributes?: boolean}
|
|
530
|
+
): void {
|
|
511
531
|
if (buffers.indices) {
|
|
512
532
|
log.warn(
|
|
513
533
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
514
534
|
)();
|
|
515
535
|
}
|
|
516
536
|
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
517
|
-
const bufferLayout = this.bufferLayout.find(layout =>
|
|
537
|
+
const bufferLayout = this.bufferLayout.find(layout =>
|
|
538
|
+
getAttributeNames(layout).includes(bufferName)
|
|
539
|
+
);
|
|
518
540
|
if (!bufferLayout) {
|
|
519
541
|
log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
520
542
|
continue; // eslint-disable-line no-continue
|
|
@@ -530,7 +552,7 @@ export class Model {
|
|
|
530
552
|
set = true;
|
|
531
553
|
}
|
|
532
554
|
}
|
|
533
|
-
if (!set &&
|
|
555
|
+
if (!set && (options?.ignoreUnknownAttributes || this.props.ignoreUnknownAttributes)) {
|
|
534
556
|
log.warn(
|
|
535
557
|
`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
|
|
536
558
|
)();
|
|
@@ -550,7 +572,7 @@ export class Model {
|
|
|
550
572
|
for (const [attributeName, value] of Object.entries(attributes)) {
|
|
551
573
|
const attributeInfo = this._attributeInfos[attributeName];
|
|
552
574
|
if (attributeInfo) {
|
|
553
|
-
this.vertexArray.
|
|
575
|
+
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
554
576
|
} else {
|
|
555
577
|
log.warn(
|
|
556
578
|
`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`
|
|
@@ -565,27 +587,33 @@ export class Model {
|
|
|
565
587
|
|
|
566
588
|
_updatePipeline(): RenderPipeline {
|
|
567
589
|
if (this._pipelineNeedsUpdate) {
|
|
590
|
+
let prevShaderVs: Shader | null = null;
|
|
591
|
+
let prevShaderFs: Shader | null = null;
|
|
568
592
|
if (this.pipeline) {
|
|
569
593
|
log.log(
|
|
570
594
|
1,
|
|
571
595
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
572
596
|
)();
|
|
597
|
+
prevShaderVs = this.pipeline.vs;
|
|
598
|
+
prevShaderFs = this.pipeline.fs;
|
|
573
599
|
}
|
|
574
600
|
|
|
575
601
|
this._pipelineNeedsUpdate = false;
|
|
576
602
|
|
|
577
|
-
const vs = this.
|
|
603
|
+
const vs = this.shaderFactory.createShader({
|
|
578
604
|
id: `${this.id}-vertex`,
|
|
579
605
|
stage: 'vertex',
|
|
580
|
-
source: this.vs
|
|
606
|
+
source: this.vs,
|
|
607
|
+
debug: this.props.debugShaders
|
|
581
608
|
});
|
|
582
609
|
|
|
583
610
|
const fs = this.fs
|
|
584
|
-
? this.
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
611
|
+
? this.shaderFactory.createShader({
|
|
612
|
+
id: `${this.id}-fragment`,
|
|
613
|
+
stage: 'fragment',
|
|
614
|
+
source: this.fs,
|
|
615
|
+
debug: this.props.debugShaders
|
|
616
|
+
})
|
|
589
617
|
: null;
|
|
590
618
|
|
|
591
619
|
this.pipeline = this.pipelineFactory.createRenderPipeline({
|
|
@@ -601,6 +629,9 @@ export class Model {
|
|
|
601
629
|
this.pipeline.shaderLayout,
|
|
602
630
|
this.bufferLayout
|
|
603
631
|
);
|
|
632
|
+
|
|
633
|
+
if (prevShaderVs) this.shaderFactory.release(prevShaderVs);
|
|
634
|
+
if (prevShaderFs) this.shaderFactory.release(prevShaderFs);
|
|
604
635
|
}
|
|
605
636
|
return this.pipeline;
|
|
606
637
|
}
|
|
@@ -651,7 +682,7 @@ export class Model {
|
|
|
651
682
|
const debugFramebuffers = log.get('framebuffer');
|
|
652
683
|
this._drawCount++;
|
|
653
684
|
// Update first 3 frames and then every 60 frames
|
|
654
|
-
if (!debugFramebuffers || (
|
|
685
|
+
if (!debugFramebuffers || (this._drawCount++ > 3 && this._drawCount % 60)) {
|
|
655
686
|
return;
|
|
656
687
|
}
|
|
657
688
|
// TODO - display framebuffer output in debug window
|
|
@@ -721,7 +752,8 @@ export function getPlatformInfo(device: Device): PlatformInfo {
|
|
|
721
752
|
shaderLanguage: device.info.shadingLanguage,
|
|
722
753
|
shaderLanguageVersion: device.info.shadingLanguageVersion as 100 | 300,
|
|
723
754
|
gpu: device.info.gpu,
|
|
724
|
-
|
|
755
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
756
|
+
features: device.features as unknown as Set<DeviceFeature>
|
|
725
757
|
};
|
|
726
758
|
}
|
|
727
759
|
|
|
@@ -4,7 +4,7 @@ import {ScenegraphNode, ScenegraphNodeProps} from './scenegraph-node';
|
|
|
4
4
|
|
|
5
5
|
export type GroupNodeProps = ScenegraphNodeProps & {
|
|
6
6
|
children?: ScenegraphNode[];
|
|
7
|
-
}
|
|
7
|
+
};
|
|
8
8
|
|
|
9
9
|
export class GroupNode extends ScenegraphNode {
|
|
10
10
|
children: ScenegraphNode[];
|
|
@@ -16,7 +16,7 @@ export class GroupNode extends ScenegraphNode {
|
|
|
16
16
|
props = Array.isArray(props) ? {children: props} : props;
|
|
17
17
|
const {children = []} = props;
|
|
18
18
|
log.assert(
|
|
19
|
-
children.every(
|
|
19
|
+
children.every(child => child instanceof ScenegraphNode),
|
|
20
20
|
'every child must an instance of ScenegraphNode'
|
|
21
21
|
);
|
|
22
22
|
super(props);
|
|
@@ -24,7 +24,10 @@ export class GroupNode extends ScenegraphNode {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
override getBounds(): [number[], number[]] | null {
|
|
27
|
-
const result: [number[], number[]] = [
|
|
27
|
+
const result: [number[], number[]] = [
|
|
28
|
+
[Infinity, Infinity, Infinity],
|
|
29
|
+
[-Infinity, -Infinity, -Infinity]
|
|
30
|
+
];
|
|
28
31
|
|
|
29
32
|
this.traverse((node, {worldMatrix}) => {
|
|
30
33
|
const bounds = node.getBounds();
|
|
@@ -39,11 +42,9 @@ export class GroupNode extends ScenegraphNode {
|
|
|
39
42
|
|
|
40
43
|
for (let v = 0; v < 8; v++) {
|
|
41
44
|
// Test all 8 corners of the box
|
|
42
|
-
const position = new Vector3(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
v & 0b100 ? -1 : 1
|
|
46
|
-
).multiply(halfSize).add(center);
|
|
45
|
+
const position = new Vector3(v & 0b001 ? -1 : 1, v & 0b010 ? -1 : 1, v & 0b100 ? -1 : 1)
|
|
46
|
+
.multiply(halfSize)
|
|
47
|
+
.add(center);
|
|
47
48
|
|
|
48
49
|
for (let i = 0; i < 3; i++) {
|
|
49
50
|
result[0][i] = Math.min(result[0][i], position[i]);
|
|
@@ -58,7 +59,7 @@ export class GroupNode extends ScenegraphNode {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
override destroy(): void {
|
|
61
|
-
this.children.forEach(
|
|
62
|
+
this.children.forEach(child => child.destroy());
|
|
62
63
|
this.removeAll();
|
|
63
64
|
super.destroy();
|
|
64
65
|
}
|
|
@@ -89,7 +90,10 @@ export class GroupNode extends ScenegraphNode {
|
|
|
89
90
|
return this;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
traverse(
|
|
93
|
+
traverse(
|
|
94
|
+
visitor: (node: ScenegraphNode, context: {worldMatrix: Matrix4}) => void,
|
|
95
|
+
{worldMatrix = new Matrix4()} = {}
|
|
96
|
+
) {
|
|
93
97
|
const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
94
98
|
|
|
95
99
|
for (const child of this.children) {
|
|
@@ -6,7 +6,7 @@ export type ModelNodeProps = ScenegraphNodeProps & {
|
|
|
6
6
|
model: Model;
|
|
7
7
|
managedResources?: any[];
|
|
8
8
|
bounds?: [number[], number[]];
|
|
9
|
-
}
|
|
9
|
+
};
|
|
10
10
|
|
|
11
11
|
export class ModelNode extends ScenegraphNode {
|
|
12
12
|
readonly model: Model;
|
|
@@ -38,7 +38,7 @@ export class ModelNode extends ScenegraphNode {
|
|
|
38
38
|
// @ts-expect-error
|
|
39
39
|
this.model = null;
|
|
40
40
|
}
|
|
41
|
-
this.managedResources.forEach(
|
|
41
|
+
this.managedResources.forEach(resource => resource.destroy());
|
|
42
42
|
this.managedResources = [];
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -10,14 +10,14 @@ export type ScenegraphNodeProps = {
|
|
|
10
10
|
position?: NumberArray;
|
|
11
11
|
rotation?: NumberArray;
|
|
12
12
|
scale?: NumberArray;
|
|
13
|
-
update?: boolean
|
|
13
|
+
update?: boolean;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export class ScenegraphNode {
|
|
17
17
|
readonly id: string;
|
|
18
18
|
matrix: Matrix4 = new Matrix4();
|
|
19
19
|
|
|
20
|
-
display = true;
|
|
20
|
+
display = true;
|
|
21
21
|
position = new Vector3();
|
|
22
22
|
rotation = new Vector3();
|
|
23
23
|
scale = new Vector3(1, 1, 1);
|
package/src/shader-inputs.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import type {UniformValue, Texture, Sampler} from '@luma.gl/core';
|
|
3
6
|
import {log} from '@luma.gl/core';
|
|
4
7
|
// import type {ShaderUniformType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core';
|
|
5
|
-
import {_resolveModules, ShaderModuleInstance} from '@luma.gl/shadertools'
|
|
6
|
-
|
|
8
|
+
import {_resolveModules, ShaderModuleInstance} from '@luma.gl/shadertools';
|
|
7
9
|
|
|
8
10
|
/** Minimal ShaderModule subset, we don't need shader code etc */
|
|
9
11
|
export type ShaderModuleInputs<
|
|
@@ -40,8 +42,8 @@ export class ShaderInputs<
|
|
|
40
42
|
Record<string, Record<string, unknown>>
|
|
41
43
|
>
|
|
42
44
|
> {
|
|
43
|
-
/**
|
|
44
|
-
* The map of modules
|
|
45
|
+
/**
|
|
46
|
+
* The map of modules
|
|
45
47
|
* @todo should should this include the resolved dependencies?
|
|
46
48
|
*/
|
|
47
49
|
modules: Readonly<{[P in keyof ShaderPropsT]: ShaderModuleInputs<ShaderPropsT[P]>}>;
|
|
@@ -59,8 +61,12 @@ export class ShaderInputs<
|
|
|
59
61
|
*/
|
|
60
62
|
constructor(modules: {[P in keyof ShaderPropsT]: ShaderModuleInputs<ShaderPropsT[P]>}) {
|
|
61
63
|
// TODO - get all dependencies from modules
|
|
62
|
-
const allModules =_resolveModules(Object.values(modules));
|
|
63
|
-
log.log(
|
|
64
|
+
const allModules = _resolveModules(Object.values(modules));
|
|
65
|
+
log.log(
|
|
66
|
+
1,
|
|
67
|
+
'Creating ShaderInputs with modules',
|
|
68
|
+
allModules.map(m => m.name)
|
|
69
|
+
)();
|
|
64
70
|
|
|
65
71
|
// Store the module definitions and create storage for uniform values and binding values, per module
|
|
66
72
|
this.modules = modules;
|
|
@@ -94,8 +100,9 @@ export class ShaderInputs<
|
|
|
94
100
|
continue; // eslint-disable-line no-continue
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
const oldUniforms = this.moduleUniforms[moduleName];
|
|
98
|
-
const uniforms =
|
|
103
|
+
const oldUniforms = this.moduleUniforms[moduleName];
|
|
104
|
+
const uniforms =
|
|
105
|
+
module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || (moduleProps as any);
|
|
99
106
|
// console.error(uniforms)
|
|
100
107
|
this.moduleUniforms[moduleName] = {...oldUniforms, ...uniforms};
|
|
101
108
|
// this.moduleUniformsChanged ||= moduleName;
|
|
@@ -113,8 +120,8 @@ export class ShaderInputs<
|
|
|
113
120
|
// return this.moduleUniforms;
|
|
114
121
|
// }
|
|
115
122
|
|
|
116
|
-
/**
|
|
117
|
-
* Return the map of modules
|
|
123
|
+
/**
|
|
124
|
+
* Return the map of modules
|
|
118
125
|
* @todo should should this include the resolved dependencies?
|
|
119
126
|
*/
|
|
120
127
|
getModules(): ShaderModuleInstance[] {
|
|
@@ -136,7 +143,7 @@ export class ShaderInputs<
|
|
|
136
143
|
}
|
|
137
144
|
|
|
138
145
|
getDebugTable(): Record<string, Record<string, unknown>> {
|
|
139
|
-
const table: Record<string,Record<string, unknown>> = {};
|
|
146
|
+
const table: Record<string, Record<string, unknown>> = {};
|
|
140
147
|
for (const [moduleName, module] of Object.entries(this.moduleUniforms)) {
|
|
141
148
|
for (const [key, value] of Object.entries(module)) {
|
|
142
149
|
table[`${moduleName}.${key}`] = {
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
2
3
|
// Copyright (c) vis.gl contributors
|
|
3
4
|
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
Device,
|
|
7
|
+
Buffer,
|
|
8
|
+
BufferRange,
|
|
9
|
+
TransformFeedback,
|
|
10
|
+
assert,
|
|
11
|
+
RenderPassProps
|
|
12
|
+
} from '@luma.gl/core';
|
|
5
13
|
import {getPassthroughFS} from '@luma.gl/shadertools';
|
|
6
14
|
import {Model} from '../model/model';
|
|
7
|
-
import type {
|
|
15
|
+
import type {ModelProps} from '..';
|
|
8
16
|
|
|
9
17
|
/**
|
|
10
18
|
* Properties for creating a {@link BufferTransform}
|
|
@@ -26,11 +34,11 @@ export class BufferTransform {
|
|
|
26
34
|
|
|
27
35
|
/** @deprecated Use device feature test. */
|
|
28
36
|
static isSupported(device: Device): boolean {
|
|
29
|
-
return device
|
|
37
|
+
return device?.info?.type === 'webgl';
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
constructor(device: Device, props: BufferTransformProps = Model.defaultProps) {
|
|
33
|
-
assert(
|
|
41
|
+
assert(BufferTransform.isSupported(device), 'BufferTransform not yet implemented on WebGPU');
|
|
34
42
|
|
|
35
43
|
this.device = device;
|
|
36
44
|
|
|
@@ -38,12 +46,12 @@ export class BufferTransform {
|
|
|
38
46
|
id: props.id || 'buffer-transform-model',
|
|
39
47
|
fs: props.fs || getPassthroughFS(),
|
|
40
48
|
topology: props.topology || 'point-list',
|
|
41
|
-
...props
|
|
49
|
+
...props
|
|
42
50
|
});
|
|
43
51
|
|
|
44
52
|
this.transformFeedback = this.device.createTransformFeedback({
|
|
45
53
|
layout: this.model.pipeline.shaderLayout,
|
|
46
|
-
buffers: props.feedbackBuffers
|
|
54
|
+
buffers: props.feedbackBuffers
|
|
47
55
|
});
|
|
48
56
|
|
|
49
57
|
this.model.setTransformFeedback(this.transformFeedback);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
// luma.gl
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
2
3
|
// Copyright (c) vis.gl contributors
|
|
3
4
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import {Buffer, Device, Framebuffer, RenderPassProps, Sampler, Texture} from '@luma.gl/core';
|
|
6
|
+
import {Model, ModelProps} from '../model/model';
|
|
7
|
+
import {getPassthroughFS} from '@luma.gl/shadertools';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Properties for creating a {@link TextureTransform}
|
|
@@ -24,7 +25,6 @@ export type TextureTransformProps = Omit<ModelProps, 'fs'> & {
|
|
|
24
25
|
targetTextureVarying: string;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
|
|
28
28
|
type TextureBinding = {
|
|
29
29
|
sourceBuffers: Record<string, Buffer>;
|
|
30
30
|
sourceTextures: Record<string, Texture>;
|
|
@@ -42,7 +42,7 @@ export class TextureTransform {
|
|
|
42
42
|
readonly device: Device;
|
|
43
43
|
readonly model: Model;
|
|
44
44
|
readonly sampler: Sampler;
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
currentIndex = 0;
|
|
47
47
|
samplerTextureMap: Record<string, any> | null = null;
|
|
48
48
|
bindings: TextureBinding[] = []; // each element is an object : {sourceTextures, targetTexture, framebuffer}
|
|
@@ -57,16 +57,18 @@ export class TextureTransform {
|
|
|
57
57
|
addressModeV: 'clamp-to-edge',
|
|
58
58
|
minFilter: 'nearest',
|
|
59
59
|
magFilter: 'nearest',
|
|
60
|
-
mipmapFilter: 'nearest'
|
|
60
|
+
mipmapFilter: 'nearest'
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
this.model = new Model(this.device, {
|
|
64
64
|
id: props.id || 'texture-transform-model',
|
|
65
|
-
fs:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
fs:
|
|
66
|
+
props.fs ||
|
|
67
|
+
getPassthroughFS({
|
|
68
|
+
input: props.targetTextureVarying,
|
|
69
|
+
inputChannels: props.targetTextureChannels,
|
|
70
|
+
output: FS_OUTPUT_VARIABLE
|
|
71
|
+
}),
|
|
70
72
|
vertexCount: props.vertexCount, // TODO(donmccurdy): Naming?
|
|
71
73
|
...props
|
|
72
74
|
});
|
|
@@ -109,7 +111,6 @@ export class TextureTransform {
|
|
|
109
111
|
return targetTexture;
|
|
110
112
|
}
|
|
111
113
|
|
|
112
|
-
|
|
113
114
|
getFramebuffer(): Framebuffer {
|
|
114
115
|
const currentResources = this.bindings[this.currentIndex];
|
|
115
116
|
return currentResources.framebuffer;
|