@luma.gl/engine 9.0.0-beta.5 → 9.0.0-beta.7
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/computation.d.ts +95 -0
- package/dist/computation.d.ts.map +1 -0
- package/dist/computation.js +248 -0
- package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
- package/dist/debug/copy-texture-to-image.js +5 -2
- 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 +713 -329
- 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/geometry/gpu-geometry.js +4 -5
- package/dist/index.cjs +661 -291
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +43 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -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 +8 -10
- package/dist/lib/pipeline-factory.d.ts +10 -6
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +47 -22
- 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 +46 -0
- package/dist/model/model.d.ts +58 -45
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +213 -120
- 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 +3 -3
- 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/computation.ts +346 -0
- 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 +18 -11
- package/src/index.ts +3 -0
- package/src/lib/clip-space.ts +14 -18
- package/src/lib/pipeline-factory.ts +62 -28
- package/src/lib/shader-factory.ts +57 -0
- package/src/model/model.ts +249 -146
- 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/dist/dist.dev.js
CHANGED
|
@@ -63,6 +63,7 @@ var __exports__ = (() => {
|
|
|
63
63
|
AnimationLoopTemplate: () => AnimationLoopTemplate,
|
|
64
64
|
BufferTransform: () => BufferTransform,
|
|
65
65
|
ClipSpace: () => ClipSpace,
|
|
66
|
+
Computation: () => Computation,
|
|
66
67
|
ConeGeometry: () => ConeGeometry,
|
|
67
68
|
CubeGeometry: () => CubeGeometry,
|
|
68
69
|
CylinderGeometry: () => CylinderGeometry,
|
|
@@ -76,6 +77,7 @@ var __exports__ = (() => {
|
|
|
76
77
|
PipelineFactory: () => PipelineFactory,
|
|
77
78
|
PlaneGeometry: () => PlaneGeometry,
|
|
78
79
|
ScenegraphNode: () => ScenegraphNode,
|
|
80
|
+
ShaderFactory: () => ShaderFactory,
|
|
79
81
|
SphereGeometry: () => SphereGeometry,
|
|
80
82
|
TextureTransform: () => TextureTransform,
|
|
81
83
|
Timeline: () => Timeline,
|
|
@@ -276,8 +278,6 @@ var __exports__ = (() => {
|
|
|
276
278
|
// ../../node_modules/@probe.gl/stats/dist/lib/stat.js
|
|
277
279
|
var Stat = class {
|
|
278
280
|
constructor(name, type) {
|
|
279
|
-
this.name = void 0;
|
|
280
|
-
this.type = void 0;
|
|
281
281
|
this.sampleSize = 1;
|
|
282
282
|
this.time = 0;
|
|
283
283
|
this.count = 0;
|
|
@@ -312,26 +312,31 @@ var __exports__ = (() => {
|
|
|
312
312
|
this.sampleSize = samples;
|
|
313
313
|
return this;
|
|
314
314
|
}
|
|
315
|
+
/** Call to increment count (+1) */
|
|
315
316
|
incrementCount() {
|
|
316
317
|
this.addCount(1);
|
|
317
318
|
return this;
|
|
318
319
|
}
|
|
320
|
+
/** Call to decrement count (-1) */
|
|
319
321
|
decrementCount() {
|
|
320
322
|
this.subtractCount(1);
|
|
321
323
|
return this;
|
|
322
324
|
}
|
|
325
|
+
/** Increase count */
|
|
323
326
|
addCount(value) {
|
|
324
327
|
this._count += value;
|
|
325
328
|
this._samples++;
|
|
326
329
|
this._checkSampling();
|
|
327
330
|
return this;
|
|
328
331
|
}
|
|
332
|
+
/** Decrease count */
|
|
329
333
|
subtractCount(value) {
|
|
330
334
|
this._count -= value;
|
|
331
335
|
this._samples++;
|
|
332
336
|
this._checkSampling();
|
|
333
337
|
return this;
|
|
334
338
|
}
|
|
339
|
+
/** Add an arbitrary timing and bump the count */
|
|
335
340
|
addTime(time) {
|
|
336
341
|
this._time += time;
|
|
337
342
|
this.lastTiming = time;
|
|
@@ -339,11 +344,13 @@ var __exports__ = (() => {
|
|
|
339
344
|
this._checkSampling();
|
|
340
345
|
return this;
|
|
341
346
|
}
|
|
347
|
+
/** Start a timer */
|
|
342
348
|
timeStart() {
|
|
343
349
|
this._startTime = getHiResTimestamp();
|
|
344
350
|
this._timerPending = true;
|
|
345
351
|
return this;
|
|
346
352
|
}
|
|
353
|
+
/** End a timer. Adds to time and bumps the timing count. */
|
|
347
354
|
timeEnd() {
|
|
348
355
|
if (!this._timerPending) {
|
|
349
356
|
return this;
|
|
@@ -356,18 +363,22 @@ var __exports__ = (() => {
|
|
|
356
363
|
getSampleAverageCount() {
|
|
357
364
|
return this.sampleSize > 0 ? this.lastSampleCount / this.sampleSize : 0;
|
|
358
365
|
}
|
|
366
|
+
/** Calculate average time / count for the previous window */
|
|
359
367
|
getSampleAverageTime() {
|
|
360
368
|
return this.sampleSize > 0 ? this.lastSampleTime / this.sampleSize : 0;
|
|
361
369
|
}
|
|
370
|
+
/** Calculate counts per second for the previous window */
|
|
362
371
|
getSampleHz() {
|
|
363
372
|
return this.lastSampleTime > 0 ? this.sampleSize / (this.lastSampleTime / 1e3) : 0;
|
|
364
373
|
}
|
|
365
374
|
getAverageCount() {
|
|
366
375
|
return this.samples > 0 ? this.count / this.samples : 0;
|
|
367
376
|
}
|
|
377
|
+
/** Calculate average time / count */
|
|
368
378
|
getAverageTime() {
|
|
369
379
|
return this.samples > 0 ? this.time / this.samples : 0;
|
|
370
380
|
}
|
|
381
|
+
/** Calculate counts per second */
|
|
371
382
|
getHz() {
|
|
372
383
|
return this.time > 0 ? this.samples / (this.time / 1e3) : 0;
|
|
373
384
|
}
|
|
@@ -388,23 +399,20 @@ var __exports__ = (() => {
|
|
|
388
399
|
// ../../node_modules/@probe.gl/stats/dist/lib/stats.js
|
|
389
400
|
var Stats = class {
|
|
390
401
|
constructor(options) {
|
|
391
|
-
this.id = void 0;
|
|
392
402
|
this.stats = {};
|
|
393
403
|
this.id = options.id;
|
|
394
404
|
this.stats = {};
|
|
395
405
|
this._initializeStats(options.stats);
|
|
396
406
|
Object.seal(this);
|
|
397
407
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return this._getOrCreate({
|
|
401
|
-
name,
|
|
402
|
-
type
|
|
403
|
-
});
|
|
408
|
+
/** Acquire a stat. Create if it doesn't exist. */
|
|
409
|
+
get(name, type = "count") {
|
|
410
|
+
return this._getOrCreate({ name, type });
|
|
404
411
|
}
|
|
405
412
|
get size() {
|
|
406
413
|
return Object.keys(this.stats).length;
|
|
407
414
|
}
|
|
415
|
+
/** Reset all stats */
|
|
408
416
|
reset() {
|
|
409
417
|
for (const stat of Object.values(this.stats)) {
|
|
410
418
|
stat.reset();
|
|
@@ -428,15 +436,11 @@ var __exports__ = (() => {
|
|
|
428
436
|
});
|
|
429
437
|
return table;
|
|
430
438
|
}
|
|
431
|
-
_initializeStats() {
|
|
432
|
-
let stats = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
|
|
439
|
+
_initializeStats(stats = []) {
|
|
433
440
|
stats.forEach((stat) => this._getOrCreate(stat));
|
|
434
441
|
}
|
|
435
442
|
_getOrCreate(stat) {
|
|
436
|
-
const {
|
|
437
|
-
name,
|
|
438
|
-
type
|
|
439
|
-
} = stat;
|
|
443
|
+
const { name, type } = stat;
|
|
440
444
|
let result = this.stats[name];
|
|
441
445
|
if (!result) {
|
|
442
446
|
if (stat instanceof Stat) {
|
|
@@ -785,7 +789,14 @@ var __exports__ = (() => {
|
|
|
785
789
|
/** Default viewport setup */
|
|
786
790
|
_resizeViewport() {
|
|
787
791
|
if (this.props.autoResizeViewport && this.device.gl) {
|
|
788
|
-
this.device.gl.viewport(
|
|
792
|
+
this.device.gl.viewport(
|
|
793
|
+
0,
|
|
794
|
+
0,
|
|
795
|
+
// @ts-expect-error Expose canvasContext
|
|
796
|
+
this.device.gl.drawingBufferWidth,
|
|
797
|
+
// @ts-expect-error Expose canvasContext
|
|
798
|
+
this.device.gl.drawingBufferHeight
|
|
799
|
+
);
|
|
789
800
|
}
|
|
790
801
|
}
|
|
791
802
|
/**
|
|
@@ -844,101 +855,14 @@ var __exports__ = (() => {
|
|
|
844
855
|
}
|
|
845
856
|
|
|
846
857
|
// src/model/model.ts
|
|
847
|
-
var import_core7 = __toESM(require_core(), 1);
|
|
848
858
|
var import_core8 = __toESM(require_core(), 1);
|
|
849
859
|
var import_core9 = __toESM(require_core(), 1);
|
|
860
|
+
var import_core10 = __toESM(require_core(), 1);
|
|
861
|
+
var import_core11 = __toESM(require_core(), 1);
|
|
850
862
|
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
851
863
|
|
|
852
|
-
// src/shader-inputs.ts
|
|
853
|
-
var import_core4 = __toESM(require_core(), 1);
|
|
854
|
-
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
855
|
-
var ShaderInputs = class {
|
|
856
|
-
/**
|
|
857
|
-
* The map of modules
|
|
858
|
-
* @todo should should this include the resolved dependencies?
|
|
859
|
-
*/
|
|
860
|
-
modules;
|
|
861
|
-
/** Stores the uniform values for each module */
|
|
862
|
-
moduleUniforms;
|
|
863
|
-
/** Stores the uniform bindings for each module */
|
|
864
|
-
moduleBindings;
|
|
865
|
-
/** Tracks if uniforms have changed */
|
|
866
|
-
moduleUniformsChanged;
|
|
867
|
-
/**
|
|
868
|
-
* Create a new UniformStore instance
|
|
869
|
-
* @param modules
|
|
870
|
-
*/
|
|
871
|
-
constructor(modules) {
|
|
872
|
-
const allModules = (0, import_shadertools._resolveModules)(Object.values(modules));
|
|
873
|
-
import_core4.log.log(1, "Creating ShaderInputs with modules", allModules.map((m) => m.name))();
|
|
874
|
-
this.modules = modules;
|
|
875
|
-
this.moduleUniforms = {};
|
|
876
|
-
this.moduleBindings = {};
|
|
877
|
-
for (const [name, module] of Object.entries(modules)) {
|
|
878
|
-
const moduleName = name;
|
|
879
|
-
this.moduleUniforms[moduleName] = module.defaultUniforms || {};
|
|
880
|
-
this.moduleBindings[moduleName] = {};
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
/** Destroy */
|
|
884
|
-
destroy() {
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Set module props
|
|
888
|
-
*/
|
|
889
|
-
setProps(props) {
|
|
890
|
-
for (const name of Object.keys(props)) {
|
|
891
|
-
const moduleName = name;
|
|
892
|
-
const moduleProps = props[moduleName];
|
|
893
|
-
const module = this.modules[moduleName];
|
|
894
|
-
if (!module) {
|
|
895
|
-
import_core4.log.warn(`Module ${name} not found`)();
|
|
896
|
-
continue;
|
|
897
|
-
}
|
|
898
|
-
const oldUniforms = this.moduleUniforms[moduleName];
|
|
899
|
-
const uniforms = module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || moduleProps;
|
|
900
|
-
this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms };
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
/** Merges all bindings for the shader (from the various modules) */
|
|
904
|
-
// getUniformBlocks(): Record<string, Texture | Sampler> {
|
|
905
|
-
// return this.moduleUniforms;
|
|
906
|
-
// }
|
|
907
|
-
/**
|
|
908
|
-
* Return the map of modules
|
|
909
|
-
* @todo should should this include the resolved dependencies?
|
|
910
|
-
*/
|
|
911
|
-
getModules() {
|
|
912
|
-
return Object.values(this.modules);
|
|
913
|
-
}
|
|
914
|
-
/** Get all uniform values for all modules */
|
|
915
|
-
getUniformValues() {
|
|
916
|
-
return this.moduleUniforms;
|
|
917
|
-
}
|
|
918
|
-
/** Merges all bindings for the shader (from the various modules) */
|
|
919
|
-
getBindings() {
|
|
920
|
-
const bindings = {};
|
|
921
|
-
for (const moduleBindings of Object.values(this.moduleBindings)) {
|
|
922
|
-
Object.assign(bindings, moduleBindings);
|
|
923
|
-
}
|
|
924
|
-
return bindings;
|
|
925
|
-
}
|
|
926
|
-
getDebugTable() {
|
|
927
|
-
const table = {};
|
|
928
|
-
for (const [moduleName, module] of Object.entries(this.moduleUniforms)) {
|
|
929
|
-
for (const [key, value] of Object.entries(module)) {
|
|
930
|
-
table[`${moduleName}.${key}`] = {
|
|
931
|
-
type: this.modules[moduleName].uniformTypes?.[key],
|
|
932
|
-
value: String(value)
|
|
933
|
-
};
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
return table;
|
|
937
|
-
}
|
|
938
|
-
};
|
|
939
|
-
|
|
940
864
|
// src/geometry/gpu-geometry.ts
|
|
941
|
-
var
|
|
865
|
+
var import_core4 = __toESM(require_core(), 1);
|
|
942
866
|
var GPUGeometry = class {
|
|
943
867
|
id;
|
|
944
868
|
userData = {};
|
|
@@ -949,22 +873,21 @@ var __exports__ = (() => {
|
|
|
949
873
|
indices;
|
|
950
874
|
attributes;
|
|
951
875
|
constructor(props) {
|
|
952
|
-
this.id = props.id || (0,
|
|
876
|
+
this.id = props.id || (0, import_core4.uid)("geometry");
|
|
953
877
|
this.topology = props.topology;
|
|
954
878
|
this.indices = props.indices || null;
|
|
955
879
|
this.attributes = props.attributes;
|
|
956
880
|
this.vertexCount = props.vertexCount;
|
|
957
881
|
this.bufferLayout = props.bufferLayout || [];
|
|
958
882
|
if (this.indices) {
|
|
959
|
-
(0,
|
|
883
|
+
(0, import_core4.assert)(this.indices.usage === import_core4.Buffer.INDEX);
|
|
960
884
|
}
|
|
961
885
|
}
|
|
962
886
|
destroy() {
|
|
963
|
-
this.indices
|
|
964
|
-
this.attributes
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
this.attributes.colors?.destroy();
|
|
887
|
+
this.indices?.destroy();
|
|
888
|
+
for (const attribute of Object.values(this.attributes)) {
|
|
889
|
+
attribute.destroy();
|
|
890
|
+
}
|
|
968
891
|
}
|
|
969
892
|
getVertexCount() {
|
|
970
893
|
return this.vertexCount;
|
|
@@ -999,7 +922,7 @@ var __exports__ = (() => {
|
|
|
999
922
|
return void 0;
|
|
1000
923
|
}
|
|
1001
924
|
const data = geometry.indices.value;
|
|
1002
|
-
return device.createBuffer({ usage:
|
|
925
|
+
return device.createBuffer({ usage: import_core4.Buffer.INDEX, data });
|
|
1003
926
|
}
|
|
1004
927
|
function getAttributeBuffersFromGeometry(device, geometry) {
|
|
1005
928
|
const bufferLayout = [];
|
|
@@ -1022,20 +945,113 @@ var __exports__ = (() => {
|
|
|
1022
945
|
}
|
|
1023
946
|
attributes[name] = device.createBuffer({ data: attribute.value, id: `${attributeName}-buffer` });
|
|
1024
947
|
const { value, size, normalized } = attribute;
|
|
1025
|
-
bufferLayout.push({ name, format: (0,
|
|
948
|
+
bufferLayout.push({ name, format: (0, import_core4.getVertexFormatFromAttribute)(value, size, normalized) });
|
|
1026
949
|
}
|
|
1027
950
|
const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices);
|
|
1028
951
|
return { attributes, bufferLayout, vertexCount };
|
|
1029
952
|
}
|
|
1030
953
|
|
|
954
|
+
// src/shader-inputs.ts
|
|
955
|
+
var import_core5 = __toESM(require_core(), 1);
|
|
956
|
+
var import_shadertools = __toESM(require_shadertools(), 1);
|
|
957
|
+
var ShaderInputs = class {
|
|
958
|
+
/**
|
|
959
|
+
* The map of modules
|
|
960
|
+
* @todo should should this include the resolved dependencies?
|
|
961
|
+
*/
|
|
962
|
+
modules;
|
|
963
|
+
/** Stores the uniform values for each module */
|
|
964
|
+
moduleUniforms;
|
|
965
|
+
/** Stores the uniform bindings for each module */
|
|
966
|
+
moduleBindings;
|
|
967
|
+
/** Tracks if uniforms have changed */
|
|
968
|
+
moduleUniformsChanged;
|
|
969
|
+
/**
|
|
970
|
+
* Create a new UniformStore instance
|
|
971
|
+
* @param modules
|
|
972
|
+
*/
|
|
973
|
+
constructor(modules) {
|
|
974
|
+
const allModules = (0, import_shadertools._resolveModules)(Object.values(modules));
|
|
975
|
+
import_core5.log.log(
|
|
976
|
+
1,
|
|
977
|
+
"Creating ShaderInputs with modules",
|
|
978
|
+
allModules.map((m) => m.name)
|
|
979
|
+
)();
|
|
980
|
+
this.modules = modules;
|
|
981
|
+
this.moduleUniforms = {};
|
|
982
|
+
this.moduleBindings = {};
|
|
983
|
+
for (const [name, module] of Object.entries(modules)) {
|
|
984
|
+
const moduleName = name;
|
|
985
|
+
this.moduleUniforms[moduleName] = module.defaultUniforms || {};
|
|
986
|
+
this.moduleBindings[moduleName] = {};
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
/** Destroy */
|
|
990
|
+
destroy() {
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Set module props
|
|
994
|
+
*/
|
|
995
|
+
setProps(props) {
|
|
996
|
+
for (const name of Object.keys(props)) {
|
|
997
|
+
const moduleName = name;
|
|
998
|
+
const moduleProps = props[moduleName];
|
|
999
|
+
const module = this.modules[moduleName];
|
|
1000
|
+
if (!module) {
|
|
1001
|
+
import_core5.log.warn(`Module ${name} not found`)();
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
const oldUniforms = this.moduleUniforms[moduleName];
|
|
1005
|
+
const uniforms = module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || moduleProps;
|
|
1006
|
+
this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms };
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
/** Merges all bindings for the shader (from the various modules) */
|
|
1010
|
+
// getUniformBlocks(): Record<string, Texture | Sampler> {
|
|
1011
|
+
// return this.moduleUniforms;
|
|
1012
|
+
// }
|
|
1013
|
+
/**
|
|
1014
|
+
* Return the map of modules
|
|
1015
|
+
* @todo should should this include the resolved dependencies?
|
|
1016
|
+
*/
|
|
1017
|
+
getModules() {
|
|
1018
|
+
return Object.values(this.modules);
|
|
1019
|
+
}
|
|
1020
|
+
/** Get all uniform values for all modules */
|
|
1021
|
+
getUniformValues() {
|
|
1022
|
+
return this.moduleUniforms;
|
|
1023
|
+
}
|
|
1024
|
+
/** Merges all bindings for the shader (from the various modules) */
|
|
1025
|
+
getBindings() {
|
|
1026
|
+
const bindings = {};
|
|
1027
|
+
for (const moduleBindings of Object.values(this.moduleBindings)) {
|
|
1028
|
+
Object.assign(bindings, moduleBindings);
|
|
1029
|
+
}
|
|
1030
|
+
return bindings;
|
|
1031
|
+
}
|
|
1032
|
+
getDebugTable() {
|
|
1033
|
+
const table = {};
|
|
1034
|
+
for (const [moduleName, module] of Object.entries(this.moduleUniforms)) {
|
|
1035
|
+
for (const [key, value] of Object.entries(module)) {
|
|
1036
|
+
table[`${moduleName}.${key}`] = {
|
|
1037
|
+
type: this.modules[moduleName].uniformTypes?.[key],
|
|
1038
|
+
value: String(value)
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return table;
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1031
1046
|
// src/lib/pipeline-factory.ts
|
|
1032
1047
|
var import_core6 = __toESM(require_core(), 1);
|
|
1033
1048
|
var _PipelineFactory = class {
|
|
1034
1049
|
device;
|
|
1035
1050
|
_hashCounter = 0;
|
|
1036
1051
|
_hashes = {};
|
|
1037
|
-
|
|
1038
|
-
|
|
1052
|
+
_renderPipelineCache = {};
|
|
1053
|
+
_computePipelineCache = {};
|
|
1054
|
+
/** Get the singleton default pipeline factory for the specified device */
|
|
1039
1055
|
static getDefaultPipelineFactory(device) {
|
|
1040
1056
|
device._lumaData.defaultPipelineFactory = device._lumaData.defaultPipelineFactory || new _PipelineFactory(device);
|
|
1041
1057
|
return device._lumaData.defaultPipelineFactory;
|
|
@@ -1043,40 +1059,59 @@ var __exports__ = (() => {
|
|
|
1043
1059
|
constructor(device) {
|
|
1044
1060
|
this.device = device;
|
|
1045
1061
|
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1062
|
+
/** Return a RenderPipeline matching props. Reuses a similar pipeline if already created. */
|
|
1063
|
+
createRenderPipeline(props) {
|
|
1064
|
+
const allProps = { ...import_core6.RenderPipeline.defaultProps, ...props };
|
|
1065
|
+
const hash = this._hashRenderPipeline(allProps);
|
|
1066
|
+
if (!this._renderPipelineCache[hash]) {
|
|
1067
|
+
const pipeline = this.device.createRenderPipeline({
|
|
1068
|
+
...allProps,
|
|
1069
|
+
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
1070
|
+
});
|
|
1071
|
+
pipeline.hash = hash;
|
|
1072
|
+
this._renderPipelineCache[hash] = { pipeline, useCount: 0 };
|
|
1073
|
+
}
|
|
1074
|
+
this._renderPipelineCache[hash].useCount++;
|
|
1075
|
+
return this._renderPipelineCache[hash].pipeline;
|
|
1076
|
+
}
|
|
1077
|
+
createComputePipeline(props) {
|
|
1078
|
+
const allProps = { ...import_core6.ComputePipeline.defaultProps, ...props };
|
|
1079
|
+
const hash = this._hashComputePipeline(allProps);
|
|
1080
|
+
if (!this._computePipelineCache[hash]) {
|
|
1081
|
+
const pipeline = this.device.createComputePipeline({
|
|
1082
|
+
...allProps,
|
|
1083
|
+
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
1084
|
+
});
|
|
1051
1085
|
pipeline.hash = hash;
|
|
1052
|
-
this.
|
|
1053
|
-
this._useCounts[hash] = 0;
|
|
1086
|
+
this._computePipelineCache[hash] = { pipeline, useCount: 0 };
|
|
1054
1087
|
}
|
|
1055
|
-
this.
|
|
1056
|
-
return this.
|
|
1088
|
+
this._computePipelineCache[hash].useCount++;
|
|
1089
|
+
return this._computePipelineCache[hash].pipeline;
|
|
1057
1090
|
}
|
|
1058
1091
|
release(pipeline) {
|
|
1059
1092
|
const hash = pipeline.hash;
|
|
1060
|
-
this.
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
delete
|
|
1093
|
+
const cache = pipeline instanceof import_core6.ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
|
|
1094
|
+
cache[hash].useCount--;
|
|
1095
|
+
if (cache[hash].useCount === 0) {
|
|
1096
|
+
cache[hash].pipeline.destroy();
|
|
1097
|
+
delete cache[hash];
|
|
1065
1098
|
}
|
|
1066
1099
|
}
|
|
1067
1100
|
// PRIVATE
|
|
1101
|
+
_hashComputePipeline(props) {
|
|
1102
|
+
const shaderHash = this._getHash(props.shader.source);
|
|
1103
|
+
return `${shaderHash}`;
|
|
1104
|
+
}
|
|
1068
1105
|
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
1069
1106
|
_hashRenderPipeline(props) {
|
|
1070
1107
|
const vsHash = this._getHash(props.vs.source);
|
|
1071
1108
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
1072
1109
|
const varyingHash = "-";
|
|
1073
1110
|
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
1074
|
-
switch (this.device.
|
|
1075
|
-
|
|
1111
|
+
switch (this.device.type) {
|
|
1112
|
+
default:
|
|
1076
1113
|
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
1077
1114
|
return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
|
|
1078
|
-
default:
|
|
1079
|
-
return `${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
|
|
1080
1115
|
}
|
|
1081
1116
|
}
|
|
1082
1117
|
_getHash(key) {
|
|
@@ -1089,6 +1124,54 @@ var __exports__ = (() => {
|
|
|
1089
1124
|
var PipelineFactory = _PipelineFactory;
|
|
1090
1125
|
__publicField(PipelineFactory, "defaultProps", { ...import_core6.RenderPipeline.defaultProps });
|
|
1091
1126
|
|
|
1127
|
+
// src/lib/shader-factory.ts
|
|
1128
|
+
var import_core7 = __toESM(require_core(), 1);
|
|
1129
|
+
var _ShaderFactory = class {
|
|
1130
|
+
device;
|
|
1131
|
+
_cache = {};
|
|
1132
|
+
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
1133
|
+
static getDefaultShaderFactory(device) {
|
|
1134
|
+
device._lumaData.defaultShaderFactory ||= new _ShaderFactory(device);
|
|
1135
|
+
return device._lumaData.defaultShaderFactory;
|
|
1136
|
+
}
|
|
1137
|
+
/** @internal */
|
|
1138
|
+
constructor(device) {
|
|
1139
|
+
this.device = device;
|
|
1140
|
+
}
|
|
1141
|
+
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
1142
|
+
createShader(props) {
|
|
1143
|
+
const key = this._hashShader(props);
|
|
1144
|
+
let cacheEntry = this._cache[key];
|
|
1145
|
+
if (!cacheEntry) {
|
|
1146
|
+
const shader = this.device.createShader({
|
|
1147
|
+
...props,
|
|
1148
|
+
id: props.id ? `${props.id}-cached` : void 0
|
|
1149
|
+
});
|
|
1150
|
+
this._cache[key] = cacheEntry = { shader, useCount: 0 };
|
|
1151
|
+
}
|
|
1152
|
+
cacheEntry.useCount++;
|
|
1153
|
+
return cacheEntry.shader;
|
|
1154
|
+
}
|
|
1155
|
+
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
1156
|
+
release(shader) {
|
|
1157
|
+
const key = this._hashShader(shader);
|
|
1158
|
+
const cacheEntry = this._cache[key];
|
|
1159
|
+
if (cacheEntry) {
|
|
1160
|
+
cacheEntry.useCount--;
|
|
1161
|
+
if (cacheEntry.useCount === 0) {
|
|
1162
|
+
delete this._cache[key];
|
|
1163
|
+
cacheEntry.shader.destroy();
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
// PRIVATE
|
|
1168
|
+
_hashShader(value) {
|
|
1169
|
+
return `${value.stage}:${value.source}`;
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
var ShaderFactory = _ShaderFactory;
|
|
1173
|
+
__publicField(ShaderFactory, "defaultProps", { ...import_core7.Shader.defaultProps });
|
|
1174
|
+
|
|
1092
1175
|
// src/debug/debug-shader-layout.ts
|
|
1093
1176
|
function getDebugTableForShaderLayout(layout, name) {
|
|
1094
1177
|
const table = {};
|
|
@@ -1112,7 +1195,14 @@ var __exports__ = (() => {
|
|
|
1112
1195
|
// src/debug/debug-framebuffer.ts
|
|
1113
1196
|
var canvas = null;
|
|
1114
1197
|
var ctx = null;
|
|
1115
|
-
function debugFramebuffer(fbo, {
|
|
1198
|
+
function debugFramebuffer(fbo, {
|
|
1199
|
+
id,
|
|
1200
|
+
minimap,
|
|
1201
|
+
opaque,
|
|
1202
|
+
top = "0",
|
|
1203
|
+
left = "0",
|
|
1204
|
+
rgbaScale = 1
|
|
1205
|
+
}) {
|
|
1116
1206
|
if (!canvas) {
|
|
1117
1207
|
canvas = document.createElement("canvas");
|
|
1118
1208
|
canvas.id = id;
|
|
@@ -1150,9 +1240,11 @@ var __exports__ = (() => {
|
|
|
1150
1240
|
var _Model = class {
|
|
1151
1241
|
device;
|
|
1152
1242
|
id;
|
|
1243
|
+
source;
|
|
1153
1244
|
vs;
|
|
1154
1245
|
fs;
|
|
1155
1246
|
pipelineFactory;
|
|
1247
|
+
shaderFactory;
|
|
1156
1248
|
userData = {};
|
|
1157
1249
|
// Fixed properties (change can trigger pipeline rebuild)
|
|
1158
1250
|
/** The render pipeline GPU parameters, depth testing etc */
|
|
@@ -1189,51 +1281,57 @@ var __exports__ = (() => {
|
|
|
1189
1281
|
/** ShaderInputs instance */
|
|
1190
1282
|
shaderInputs;
|
|
1191
1283
|
_uniformStore;
|
|
1192
|
-
_pipelineNeedsUpdate = "newly created";
|
|
1193
1284
|
_attributeInfos = {};
|
|
1194
1285
|
_gpuGeometry = null;
|
|
1195
1286
|
_getModuleUniforms;
|
|
1196
1287
|
props;
|
|
1288
|
+
_pipelineNeedsUpdate = "newly created";
|
|
1289
|
+
_needsRedraw = "initializing";
|
|
1290
|
+
_destroyed = false;
|
|
1291
|
+
/** "Time" of last draw. Monotonically increasing timestamp */
|
|
1292
|
+
_lastDrawTimestamp = -1;
|
|
1197
1293
|
constructor(device, props) {
|
|
1198
1294
|
this.props = { ..._Model.defaultProps, ...props };
|
|
1199
1295
|
props = this.props;
|
|
1200
|
-
this.id = props.id || (0,
|
|
1296
|
+
this.id = props.id || (0, import_core10.uid)("model");
|
|
1201
1297
|
this.device = device;
|
|
1202
1298
|
Object.assign(this.userData, props.userData);
|
|
1203
1299
|
const moduleMap = Object.fromEntries(
|
|
1204
1300
|
this.props.modules?.map((module) => [module.name, module]) || []
|
|
1205
1301
|
);
|
|
1206
1302
|
this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
|
|
1207
|
-
const isWebGPU = this.device.info.type === "webgpu";
|
|
1208
|
-
if (this.props.source) {
|
|
1209
|
-
if (isWebGPU) {
|
|
1210
|
-
this.props.shaderLayout ||= (0, import_shadertools2.getShaderLayoutFromWGSL)(this.props.source);
|
|
1211
|
-
}
|
|
1212
|
-
this.props.fs = this.props.source;
|
|
1213
|
-
this.props.vs = this.props.source;
|
|
1214
|
-
}
|
|
1215
|
-
if (isWebGPU && typeof this.props.vs !== "string") {
|
|
1216
|
-
this.props.shaderLayout ||= (0, import_shadertools2.getShaderLayoutFromWGSL)(this.props.vs.wgsl);
|
|
1217
|
-
}
|
|
1218
1303
|
const platformInfo = getPlatformInfo(device);
|
|
1219
1304
|
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
1220
|
-
const
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1305
|
+
const isWebGPU = this.device.type === "webgpu";
|
|
1306
|
+
if (isWebGPU && this.props.source) {
|
|
1307
|
+
this.props.shaderLayout ||= (0, import_shadertools2.getShaderLayoutFromWGSL)(this.props.source);
|
|
1308
|
+
const { source, getUniforms } = this.props.shaderAssembler.assembleShader({
|
|
1309
|
+
platformInfo,
|
|
1310
|
+
...this.props,
|
|
1311
|
+
modules
|
|
1312
|
+
});
|
|
1313
|
+
this.source = source;
|
|
1314
|
+
this._getModuleUniforms = getUniforms;
|
|
1315
|
+
} else {
|
|
1316
|
+
const { vs, fs, getUniforms } = this.props.shaderAssembler.assembleShaderPair({
|
|
1317
|
+
platformInfo,
|
|
1318
|
+
...this.props,
|
|
1319
|
+
modules
|
|
1320
|
+
});
|
|
1321
|
+
this.vs = vs;
|
|
1322
|
+
this.fs = fs;
|
|
1323
|
+
this._getModuleUniforms = getUniforms;
|
|
1324
|
+
}
|
|
1228
1325
|
this.vertexCount = this.props.vertexCount;
|
|
1229
1326
|
this.instanceCount = this.props.instanceCount;
|
|
1230
1327
|
this.topology = this.props.topology;
|
|
1231
1328
|
this.bufferLayout = this.props.bufferLayout;
|
|
1232
1329
|
this.parameters = this.props.parameters;
|
|
1233
1330
|
if (props.geometry) {
|
|
1234
|
-
this.
|
|
1331
|
+
this.setGeometry(props.geometry);
|
|
1235
1332
|
}
|
|
1236
1333
|
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
1334
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1237
1335
|
this.pipeline = this._updatePipeline();
|
|
1238
1336
|
this.vertexArray = device.createVertexArray({
|
|
1239
1337
|
renderPipeline: this.pipeline
|
|
@@ -1254,7 +1352,9 @@ var __exports__ = (() => {
|
|
|
1254
1352
|
this.setIndexBuffer(props.indexBuffer);
|
|
1255
1353
|
}
|
|
1256
1354
|
if (props.attributes) {
|
|
1257
|
-
this.setAttributes(props.attributes
|
|
1355
|
+
this.setAttributes(props.attributes, {
|
|
1356
|
+
ignoreUnknownAttributes: props.ignoreUnknownAttributes
|
|
1357
|
+
});
|
|
1258
1358
|
}
|
|
1259
1359
|
if (props.constantAttributes) {
|
|
1260
1360
|
this.setConstantAttributes(props.constantAttributes);
|
|
@@ -1266,7 +1366,7 @@ var __exports__ = (() => {
|
|
|
1266
1366
|
this.setUniforms(props.uniforms);
|
|
1267
1367
|
}
|
|
1268
1368
|
if (props.moduleSettings) {
|
|
1269
|
-
|
|
1369
|
+
import_core10.log.warn("Model.props.moduleSettings is deprecated. Use Model.shaderInputs.setProps()")();
|
|
1270
1370
|
this.updateModuleSettings(props.moduleSettings);
|
|
1271
1371
|
}
|
|
1272
1372
|
if (props.transformFeedback) {
|
|
@@ -1275,23 +1375,48 @@ var __exports__ = (() => {
|
|
|
1275
1375
|
Object.seal(this);
|
|
1276
1376
|
}
|
|
1277
1377
|
destroy() {
|
|
1378
|
+
if (this._destroyed)
|
|
1379
|
+
return;
|
|
1278
1380
|
this.pipelineFactory.release(this.pipeline);
|
|
1381
|
+
this.shaderFactory.release(this.pipeline.vs);
|
|
1382
|
+
if (this.pipeline.fs) {
|
|
1383
|
+
this.shaderFactory.release(this.pipeline.fs);
|
|
1384
|
+
}
|
|
1279
1385
|
this._uniformStore.destroy();
|
|
1386
|
+
this._gpuGeometry?.destroy();
|
|
1387
|
+
this._destroyed = true;
|
|
1280
1388
|
}
|
|
1281
1389
|
// Draw call
|
|
1390
|
+
/** Query redraw status. Clears the status. */
|
|
1391
|
+
needsRedraw() {
|
|
1392
|
+
if (this._getBindingsUpdateTimestamp() > this._lastDrawTimestamp) {
|
|
1393
|
+
this.setNeedsRedraw("contents of bound textures or buffers updated");
|
|
1394
|
+
}
|
|
1395
|
+
const needsRedraw = this._needsRedraw;
|
|
1396
|
+
this._needsRedraw = false;
|
|
1397
|
+
return needsRedraw;
|
|
1398
|
+
}
|
|
1399
|
+
/** Mark the model as needing a redraw */
|
|
1400
|
+
setNeedsRedraw(reason) {
|
|
1401
|
+
this._needsRedraw ||= reason;
|
|
1402
|
+
}
|
|
1282
1403
|
predraw() {
|
|
1283
1404
|
this.updateShaderInputs();
|
|
1405
|
+
this.pipeline = this._updatePipeline();
|
|
1284
1406
|
}
|
|
1285
1407
|
draw(renderPass) {
|
|
1286
1408
|
this.predraw();
|
|
1409
|
+
let drawSuccess;
|
|
1287
1410
|
try {
|
|
1288
1411
|
this._logDrawCallStart();
|
|
1289
1412
|
this.pipeline = this._updatePipeline();
|
|
1290
1413
|
this.pipeline.setBindings(this.bindings);
|
|
1291
|
-
|
|
1414
|
+
if (!(0, import_core10.isObjectEmpty)(this.uniforms)) {
|
|
1415
|
+
this.pipeline.setUniformsWebGL(this.uniforms);
|
|
1416
|
+
}
|
|
1292
1417
|
const { indexBuffer } = this.vertexArray;
|
|
1293
1418
|
const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
|
|
1294
|
-
this.pipeline.draw({
|
|
1419
|
+
drawSuccess = this.pipeline.draw({
|
|
1295
1420
|
renderPass,
|
|
1296
1421
|
vertexArray: this.vertexArray,
|
|
1297
1422
|
vertexCount: this.vertexCount,
|
|
@@ -1303,6 +1428,13 @@ var __exports__ = (() => {
|
|
|
1303
1428
|
this._logDrawCallEnd();
|
|
1304
1429
|
}
|
|
1305
1430
|
this._logFramebuffer(renderPass);
|
|
1431
|
+
if (drawSuccess) {
|
|
1432
|
+
this._lastDrawTimestamp = this.device.timestamp;
|
|
1433
|
+
this._needsRedraw = false;
|
|
1434
|
+
} else {
|
|
1435
|
+
this._needsRedraw = "waiting for resource initialization";
|
|
1436
|
+
}
|
|
1437
|
+
return drawSuccess;
|
|
1306
1438
|
}
|
|
1307
1439
|
// Update fixed fields (can trigger pipeline rebuild)
|
|
1308
1440
|
/**
|
|
@@ -1311,30 +1443,16 @@ var __exports__ = (() => {
|
|
|
1311
1443
|
* @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
1312
1444
|
*/
|
|
1313
1445
|
setGeometry(geometry) {
|
|
1446
|
+
this._gpuGeometry?.destroy();
|
|
1314
1447
|
const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
this.
|
|
1319
|
-
|
|
1320
|
-
return gpuGeometry;
|
|
1321
|
-
}
|
|
1322
|
-
/**
|
|
1323
|
-
* Updates the optional geometry attributes
|
|
1324
|
-
* Geometry, sets several attributes, indexBuffer, and also vertex count
|
|
1325
|
-
* @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
1326
|
-
*/
|
|
1327
|
-
_setGeometryAttributes(gpuGeometry) {
|
|
1328
|
-
const attributes = { ...gpuGeometry.attributes };
|
|
1329
|
-
for (const [attributeName] of Object.entries(attributes)) {
|
|
1330
|
-
if (!this.pipeline.shaderLayout.attributes.find((layout) => layout.name === attributeName) && attributeName !== "positions") {
|
|
1331
|
-
delete attributes[attributeName];
|
|
1448
|
+
if (gpuGeometry) {
|
|
1449
|
+
this.setTopology(gpuGeometry.topology || "triangle-list");
|
|
1450
|
+
this.bufferLayout = mergeBufferLayouts(gpuGeometry.bufferLayout, this.bufferLayout);
|
|
1451
|
+
if (this.vertexArray) {
|
|
1452
|
+
this._setGeometryAttributes(gpuGeometry);
|
|
1332
1453
|
}
|
|
1333
1454
|
}
|
|
1334
|
-
this.
|
|
1335
|
-
this.setIndexBuffer(gpuGeometry.indices);
|
|
1336
|
-
this.setAttributes(gpuGeometry.attributes, "ignore-unknown");
|
|
1337
|
-
this.setAttributes(attributes);
|
|
1455
|
+
this._gpuGeometry = gpuGeometry;
|
|
1338
1456
|
}
|
|
1339
1457
|
/**
|
|
1340
1458
|
* Updates the primitive topology ('triangle-list', 'triangle-strip' etc).
|
|
@@ -1348,11 +1466,10 @@ var __exports__ = (() => {
|
|
|
1348
1466
|
}
|
|
1349
1467
|
/**
|
|
1350
1468
|
* Updates the buffer layout.
|
|
1351
|
-
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
1469
|
+
* @note Triggers a pipeline rebuild / pipeline cache fetch
|
|
1352
1470
|
*/
|
|
1353
1471
|
setBufferLayout(bufferLayout) {
|
|
1354
1472
|
this.bufferLayout = this._gpuGeometry ? mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout;
|
|
1355
|
-
this._setPipelineNeedsUpdate("bufferLayout");
|
|
1356
1473
|
this.pipeline = this._updatePipeline();
|
|
1357
1474
|
this.vertexArray = this.device.createVertexArray({
|
|
1358
1475
|
renderPipeline: this.pipeline
|
|
@@ -1360,6 +1477,7 @@ var __exports__ = (() => {
|
|
|
1360
1477
|
if (this._gpuGeometry) {
|
|
1361
1478
|
this._setGeometryAttributes(this._gpuGeometry);
|
|
1362
1479
|
}
|
|
1480
|
+
this._setPipelineNeedsUpdate("bufferLayout");
|
|
1363
1481
|
}
|
|
1364
1482
|
/**
|
|
1365
1483
|
* Set GPU parameters.
|
|
@@ -1367,7 +1485,7 @@ var __exports__ = (() => {
|
|
|
1367
1485
|
* @param parameters
|
|
1368
1486
|
*/
|
|
1369
1487
|
setParameters(parameters) {
|
|
1370
|
-
if (!(0,
|
|
1488
|
+
if (!(0, import_core10.deepEqual)(parameters, this.parameters, 2)) {
|
|
1371
1489
|
this.parameters = parameters;
|
|
1372
1490
|
this._setPipelineNeedsUpdate("parameters");
|
|
1373
1491
|
}
|
|
@@ -1379,6 +1497,7 @@ var __exports__ = (() => {
|
|
|
1379
1497
|
*/
|
|
1380
1498
|
setVertexCount(vertexCount) {
|
|
1381
1499
|
this.vertexCount = vertexCount;
|
|
1500
|
+
this.setNeedsRedraw("vertexCount");
|
|
1382
1501
|
}
|
|
1383
1502
|
/**
|
|
1384
1503
|
* Updates the instance count (used in draw calls)
|
|
@@ -1386,57 +1505,34 @@ var __exports__ = (() => {
|
|
|
1386
1505
|
*/
|
|
1387
1506
|
setInstanceCount(instanceCount) {
|
|
1388
1507
|
this.instanceCount = instanceCount;
|
|
1508
|
+
this.setNeedsRedraw("instanceCount");
|
|
1389
1509
|
}
|
|
1390
1510
|
setShaderInputs(shaderInputs) {
|
|
1391
1511
|
this.shaderInputs = shaderInputs;
|
|
1392
|
-
this._uniformStore = new
|
|
1512
|
+
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1393
1513
|
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
1394
1514
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1395
1515
|
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1396
1516
|
}
|
|
1397
|
-
|
|
1398
|
-
/**
|
|
1399
|
-
* Updates shader module settings (which results in uniforms being set)
|
|
1400
|
-
*/
|
|
1401
|
-
setShaderModuleProps(props) {
|
|
1402
|
-
const uniforms = this._getModuleUniforms(props);
|
|
1403
|
-
const keys = Object.keys(uniforms).filter((k) => {
|
|
1404
|
-
const uniform = uniforms[k];
|
|
1405
|
-
return !(0, import_core8.isNumberArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
1406
|
-
});
|
|
1407
|
-
const bindings = {};
|
|
1408
|
-
for (const k of keys) {
|
|
1409
|
-
bindings[k] = uniforms[k];
|
|
1410
|
-
delete uniforms[k];
|
|
1411
|
-
}
|
|
1517
|
+
this.setNeedsRedraw("shaderInputs");
|
|
1412
1518
|
}
|
|
1413
1519
|
updateShaderInputs() {
|
|
1414
1520
|
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1415
|
-
|
|
1416
|
-
/**
|
|
1417
|
-
* @deprecated Updates shader module settings (which results in uniforms being set)
|
|
1418
|
-
*/
|
|
1419
|
-
updateModuleSettings(props) {
|
|
1420
|
-
import_core8.log.warn("Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()")();
|
|
1421
|
-
const { bindings, uniforms } = (0, import_core8.splitUniformsAndBindings)(this._getModuleUniforms(props));
|
|
1422
|
-
Object.assign(this.bindings, bindings);
|
|
1423
|
-
Object.assign(this.uniforms, uniforms);
|
|
1521
|
+
this.setNeedsRedraw("shaderInputs");
|
|
1424
1522
|
}
|
|
1425
1523
|
/**
|
|
1426
1524
|
* Sets bindings (textures, samplers, uniform buffers)
|
|
1427
1525
|
*/
|
|
1428
1526
|
setBindings(bindings) {
|
|
1429
1527
|
Object.assign(this.bindings, bindings);
|
|
1528
|
+
this.setNeedsRedraw("bindings");
|
|
1430
1529
|
}
|
|
1431
1530
|
/**
|
|
1432
|
-
*
|
|
1433
|
-
* @deprecated WebGL only, use uniform buffers for portability
|
|
1434
|
-
* @param uniforms
|
|
1435
|
-
* @returns self for chaining
|
|
1531
|
+
* Updates optional transform feedback. WebGL only.
|
|
1436
1532
|
*/
|
|
1437
|
-
|
|
1438
|
-
this.
|
|
1439
|
-
|
|
1533
|
+
setTransformFeedback(transformFeedback) {
|
|
1534
|
+
this.transformFeedback = transformFeedback;
|
|
1535
|
+
this.setNeedsRedraw("transformFeedback");
|
|
1440
1536
|
}
|
|
1441
1537
|
/**
|
|
1442
1538
|
* Sets the index buffer
|
|
@@ -1444,27 +1540,24 @@ var __exports__ = (() => {
|
|
|
1444
1540
|
*/
|
|
1445
1541
|
setIndexBuffer(indexBuffer) {
|
|
1446
1542
|
this.vertexArray.setIndexBuffer(indexBuffer);
|
|
1447
|
-
|
|
1448
|
-
/**
|
|
1449
|
-
* Updates optional transform feedback. WebGL only.
|
|
1450
|
-
*/
|
|
1451
|
-
setTransformFeedback(transformFeedback) {
|
|
1452
|
-
this.transformFeedback = transformFeedback;
|
|
1543
|
+
this.setNeedsRedraw("indexBuffer");
|
|
1453
1544
|
}
|
|
1454
1545
|
/**
|
|
1455
1546
|
* Sets attributes (buffers)
|
|
1456
1547
|
* @note Overrides any attributes previously set with the same name
|
|
1457
1548
|
*/
|
|
1458
|
-
setAttributes(buffers,
|
|
1549
|
+
setAttributes(buffers, options) {
|
|
1459
1550
|
if (buffers.indices) {
|
|
1460
|
-
|
|
1551
|
+
import_core10.log.warn(
|
|
1461
1552
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
1462
1553
|
)();
|
|
1463
1554
|
}
|
|
1464
1555
|
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
1465
|
-
const bufferLayout = this.bufferLayout.find(
|
|
1556
|
+
const bufferLayout = this.bufferLayout.find(
|
|
1557
|
+
(layout) => getAttributeNames(layout).includes(bufferName)
|
|
1558
|
+
);
|
|
1466
1559
|
if (!bufferLayout) {
|
|
1467
|
-
|
|
1560
|
+
import_core10.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
1468
1561
|
continue;
|
|
1469
1562
|
}
|
|
1470
1563
|
const attributeNames = getAttributeNames(bufferLayout);
|
|
@@ -1476,12 +1569,13 @@ var __exports__ = (() => {
|
|
|
1476
1569
|
set = true;
|
|
1477
1570
|
}
|
|
1478
1571
|
}
|
|
1479
|
-
if (!set &&
|
|
1480
|
-
|
|
1572
|
+
if (!set && (options?.ignoreUnknownAttributes || this.props.ignoreUnknownAttributes)) {
|
|
1573
|
+
import_core10.log.warn(
|
|
1481
1574
|
`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
|
|
1482
1575
|
)();
|
|
1483
1576
|
}
|
|
1484
1577
|
}
|
|
1578
|
+
this.setNeedsRedraw("attributes");
|
|
1485
1579
|
}
|
|
1486
1580
|
/**
|
|
1487
1581
|
* Sets constant attributes
|
|
@@ -1495,36 +1589,107 @@ var __exports__ = (() => {
|
|
|
1495
1589
|
for (const [attributeName, value] of Object.entries(attributes)) {
|
|
1496
1590
|
const attributeInfo = this._attributeInfos[attributeName];
|
|
1497
1591
|
if (attributeInfo) {
|
|
1498
|
-
this.vertexArray.
|
|
1592
|
+
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
1499
1593
|
} else {
|
|
1500
|
-
|
|
1594
|
+
import_core10.log.warn(
|
|
1501
1595
|
`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`
|
|
1502
1596
|
)();
|
|
1503
1597
|
}
|
|
1504
1598
|
}
|
|
1599
|
+
this.setNeedsRedraw("constants");
|
|
1600
|
+
}
|
|
1601
|
+
// DEPRECATED METHODS
|
|
1602
|
+
/**
|
|
1603
|
+
* Sets individual uniforms
|
|
1604
|
+
* @deprecated WebGL only, use uniform buffers for portability
|
|
1605
|
+
* @param uniforms
|
|
1606
|
+
*/
|
|
1607
|
+
setUniforms(uniforms) {
|
|
1608
|
+
if (!(0, import_core10.isObjectEmpty)(uniforms)) {
|
|
1609
|
+
this.pipeline.setUniformsWebGL(uniforms);
|
|
1610
|
+
Object.assign(this.uniforms, uniforms);
|
|
1611
|
+
}
|
|
1612
|
+
this.setNeedsRedraw("uniforms");
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* @deprecated Updates shader module settings (which results in uniforms being set)
|
|
1616
|
+
*/
|
|
1617
|
+
updateModuleSettings(props) {
|
|
1618
|
+
import_core10.log.warn("Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()")();
|
|
1619
|
+
const { bindings, uniforms } = (0, import_core10.splitUniformsAndBindings)(this._getModuleUniforms(props));
|
|
1620
|
+
Object.assign(this.bindings, bindings);
|
|
1621
|
+
Object.assign(this.uniforms, uniforms);
|
|
1622
|
+
this.setNeedsRedraw("moduleSettings");
|
|
1623
|
+
}
|
|
1624
|
+
// Internal methods
|
|
1625
|
+
/** Get the timestamp of the latest updated bound GPU memory resource (buffer/texture). */
|
|
1626
|
+
_getBindingsUpdateTimestamp() {
|
|
1627
|
+
let timestamp = 0;
|
|
1628
|
+
for (const binding of Object.values(this.bindings)) {
|
|
1629
|
+
if (binding instanceof import_core8.TextureView) {
|
|
1630
|
+
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
1631
|
+
} else if (binding instanceof import_core8.Buffer || binding instanceof import_core8.Texture) {
|
|
1632
|
+
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
1633
|
+
} else if (!(binding instanceof import_core8.Sampler)) {
|
|
1634
|
+
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
return timestamp;
|
|
1505
1638
|
}
|
|
1639
|
+
/**
|
|
1640
|
+
* Updates the optional geometry attributes
|
|
1641
|
+
* Geometry, sets several attributes, indexBuffer, and also vertex count
|
|
1642
|
+
* @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
1643
|
+
*/
|
|
1644
|
+
_setGeometryAttributes(gpuGeometry) {
|
|
1645
|
+
const attributes = { ...gpuGeometry.attributes };
|
|
1646
|
+
for (const [attributeName] of Object.entries(attributes)) {
|
|
1647
|
+
if (!this.pipeline.shaderLayout.attributes.find((layout) => layout.name === attributeName) && attributeName !== "positions") {
|
|
1648
|
+
delete attributes[attributeName];
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
this.vertexCount = gpuGeometry.vertexCount;
|
|
1652
|
+
this.setIndexBuffer(gpuGeometry.indices);
|
|
1653
|
+
this.setAttributes(gpuGeometry.attributes, { ignoreUnknownAttributes: true });
|
|
1654
|
+
this.setAttributes(attributes, { ignoreUnknownAttributes: this.props.ignoreUnknownAttributes });
|
|
1655
|
+
this.setNeedsRedraw("geometry attributes");
|
|
1656
|
+
}
|
|
1657
|
+
/** Mark pipeline as needing update */
|
|
1506
1658
|
_setPipelineNeedsUpdate(reason) {
|
|
1507
|
-
this._pipelineNeedsUpdate
|
|
1659
|
+
this._pipelineNeedsUpdate ||= reason;
|
|
1660
|
+
this.setNeedsRedraw(reason);
|
|
1508
1661
|
}
|
|
1662
|
+
/** Update pipeline if needed */
|
|
1509
1663
|
_updatePipeline() {
|
|
1510
1664
|
if (this._pipelineNeedsUpdate) {
|
|
1665
|
+
let prevShaderVs = null;
|
|
1666
|
+
let prevShaderFs = null;
|
|
1511
1667
|
if (this.pipeline) {
|
|
1512
|
-
|
|
1668
|
+
import_core10.log.log(
|
|
1513
1669
|
1,
|
|
1514
1670
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
1515
1671
|
)();
|
|
1672
|
+
prevShaderVs = this.pipeline.vs;
|
|
1673
|
+
prevShaderFs = this.pipeline.fs;
|
|
1516
1674
|
}
|
|
1517
1675
|
this._pipelineNeedsUpdate = false;
|
|
1518
|
-
const vs = this.
|
|
1676
|
+
const vs = this.shaderFactory.createShader({
|
|
1519
1677
|
id: `${this.id}-vertex`,
|
|
1520
1678
|
stage: "vertex",
|
|
1521
|
-
source: this.vs
|
|
1679
|
+
source: this.source || this.vs,
|
|
1680
|
+
debug: this.props.debugShaders
|
|
1522
1681
|
});
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1682
|
+
let fs = null;
|
|
1683
|
+
if (this.source) {
|
|
1684
|
+
fs = vs;
|
|
1685
|
+
} else if (this.fs) {
|
|
1686
|
+
fs = this.shaderFactory.createShader({
|
|
1687
|
+
id: `${this.id}-fragment`,
|
|
1688
|
+
stage: "fragment",
|
|
1689
|
+
source: this.source || this.fs,
|
|
1690
|
+
debug: this.props.debugShaders
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1528
1693
|
this.pipeline = this.pipelineFactory.createRenderPipeline({
|
|
1529
1694
|
...this.props,
|
|
1530
1695
|
bufferLayout: this.bufferLayout,
|
|
@@ -1533,10 +1698,14 @@ var __exports__ = (() => {
|
|
|
1533
1698
|
vs,
|
|
1534
1699
|
fs
|
|
1535
1700
|
});
|
|
1536
|
-
this._attributeInfos = (0,
|
|
1701
|
+
this._attributeInfos = (0, import_core11.getAttributeInfosFromLayouts)(
|
|
1537
1702
|
this.pipeline.shaderLayout,
|
|
1538
1703
|
this.bufferLayout
|
|
1539
1704
|
);
|
|
1705
|
+
if (prevShaderVs)
|
|
1706
|
+
this.shaderFactory.release(prevShaderVs);
|
|
1707
|
+
if (prevShaderFs)
|
|
1708
|
+
this.shaderFactory.release(prevShaderFs);
|
|
1540
1709
|
}
|
|
1541
1710
|
return this.pipeline;
|
|
1542
1711
|
}
|
|
@@ -1544,33 +1713,33 @@ var __exports__ = (() => {
|
|
|
1544
1713
|
_lastLogTime = 0;
|
|
1545
1714
|
_logOpen = false;
|
|
1546
1715
|
_logDrawCallStart() {
|
|
1547
|
-
const logDrawTimeout =
|
|
1548
|
-
if (
|
|
1716
|
+
const logDrawTimeout = import_core10.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1717
|
+
if (import_core10.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1549
1718
|
return;
|
|
1550
1719
|
}
|
|
1551
1720
|
this._lastLogTime = Date.now();
|
|
1552
1721
|
this._logOpen = true;
|
|
1553
|
-
|
|
1722
|
+
import_core10.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core10.log.level <= 2 })();
|
|
1554
1723
|
}
|
|
1555
1724
|
_logDrawCallEnd() {
|
|
1556
1725
|
if (this._logOpen) {
|
|
1557
1726
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
1558
|
-
|
|
1727
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
|
|
1559
1728
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1560
1729
|
for (const [name, value] of Object.entries(this.uniforms)) {
|
|
1561
1730
|
uniformTable[name] = { value };
|
|
1562
1731
|
}
|
|
1563
|
-
|
|
1732
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1564
1733
|
const attributeTable = this._getAttributeDebugTable();
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1734
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
|
|
1735
|
+
import_core10.log.table(LOG_DRAW_PRIORITY, attributeTable)();
|
|
1736
|
+
import_core10.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1568
1737
|
this._logOpen = false;
|
|
1569
1738
|
}
|
|
1570
1739
|
}
|
|
1571
1740
|
_drawCount = 0;
|
|
1572
1741
|
_logFramebuffer(renderPass) {
|
|
1573
|
-
const debugFramebuffers =
|
|
1742
|
+
const debugFramebuffers = import_core10.log.get("framebuffer");
|
|
1574
1743
|
this._drawCount++;
|
|
1575
1744
|
if (!debugFramebuffers || this._drawCount++ > 3 && this._drawCount % 60) {
|
|
1576
1745
|
return;
|
|
@@ -1605,14 +1774,14 @@ var __exports__ = (() => {
|
|
|
1605
1774
|
}
|
|
1606
1775
|
// TODO - fix typing of luma data types
|
|
1607
1776
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
1608
|
-
const TypedArrayConstructor = (0,
|
|
1609
|
-
const typedArray = attribute instanceof
|
|
1777
|
+
const TypedArrayConstructor = (0, import_core11.getTypedArrayFromDataType)(dataType);
|
|
1778
|
+
const typedArray = attribute instanceof import_core8.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1610
1779
|
return typedArray.toString();
|
|
1611
1780
|
}
|
|
1612
1781
|
};
|
|
1613
1782
|
var Model = _Model;
|
|
1614
1783
|
__publicField(Model, "defaultProps", {
|
|
1615
|
-
...
|
|
1784
|
+
...import_core9.RenderPipeline.defaultProps,
|
|
1616
1785
|
source: null,
|
|
1617
1786
|
vs: null,
|
|
1618
1787
|
fs: null,
|
|
@@ -1629,8 +1798,11 @@ var __exports__ = (() => {
|
|
|
1629
1798
|
varyings: [],
|
|
1630
1799
|
shaderInputs: void 0,
|
|
1631
1800
|
pipelineFactory: void 0,
|
|
1801
|
+
shaderFactory: void 0,
|
|
1632
1802
|
transformFeedback: void 0,
|
|
1633
|
-
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler()
|
|
1803
|
+
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
1804
|
+
debugShaders: void 0,
|
|
1805
|
+
ignoreUnknownAttributes: void 0
|
|
1634
1806
|
});
|
|
1635
1807
|
function mergeBufferLayouts(layouts1, layouts2) {
|
|
1636
1808
|
const layouts = [...layouts1];
|
|
@@ -1646,10 +1818,11 @@ var __exports__ = (() => {
|
|
|
1646
1818
|
}
|
|
1647
1819
|
function getPlatformInfo(device) {
|
|
1648
1820
|
return {
|
|
1649
|
-
type: device.
|
|
1821
|
+
type: device.type,
|
|
1650
1822
|
shaderLanguage: device.info.shadingLanguage,
|
|
1651
1823
|
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
1652
1824
|
gpu: device.info.gpu,
|
|
1825
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
1653
1826
|
features: device.features
|
|
1654
1827
|
};
|
|
1655
1828
|
}
|
|
@@ -1658,7 +1831,7 @@ var __exports__ = (() => {
|
|
|
1658
1831
|
}
|
|
1659
1832
|
|
|
1660
1833
|
// src/transform/buffer-transform.ts
|
|
1661
|
-
var
|
|
1834
|
+
var import_core12 = __toESM(require_core(), 1);
|
|
1662
1835
|
var import_shadertools3 = __toESM(require_shadertools(), 1);
|
|
1663
1836
|
var BufferTransform = class {
|
|
1664
1837
|
device;
|
|
@@ -1666,10 +1839,10 @@ var __exports__ = (() => {
|
|
|
1666
1839
|
transformFeedback;
|
|
1667
1840
|
/** @deprecated Use device feature test. */
|
|
1668
1841
|
static isSupported(device) {
|
|
1669
|
-
return device
|
|
1842
|
+
return device?.info?.type === "webgl";
|
|
1670
1843
|
}
|
|
1671
1844
|
constructor(device, props = Model.defaultProps) {
|
|
1672
|
-
(0,
|
|
1845
|
+
(0, import_core12.assert)(BufferTransform.isSupported(device), "BufferTransform not yet implemented on WebGPU");
|
|
1673
1846
|
this.device = device;
|
|
1674
1847
|
this.model = new Model(this.device, {
|
|
1675
1848
|
id: props.id || "buffer-transform-model",
|
|
@@ -1710,7 +1883,7 @@ var __exports__ = (() => {
|
|
|
1710
1883
|
}
|
|
1711
1884
|
readAsync(varyingName) {
|
|
1712
1885
|
const result = this.getBuffer(varyingName);
|
|
1713
|
-
if (result instanceof
|
|
1886
|
+
if (result instanceof import_core12.Buffer) {
|
|
1714
1887
|
return result.readAsync();
|
|
1715
1888
|
}
|
|
1716
1889
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -1826,10 +1999,10 @@ var __exports__ = (() => {
|
|
|
1826
1999
|
};
|
|
1827
2000
|
|
|
1828
2001
|
// src/lib/clip-space.ts
|
|
1829
|
-
var
|
|
2002
|
+
var import_core14 = __toESM(require_core(), 1);
|
|
1830
2003
|
|
|
1831
2004
|
// src/geometry/geometry.ts
|
|
1832
|
-
var
|
|
2005
|
+
var import_core13 = __toESM(require_core(), 1);
|
|
1833
2006
|
var Geometry = class {
|
|
1834
2007
|
id;
|
|
1835
2008
|
/** Determines how vertices are read from the 'vertex' attributes */
|
|
@@ -1840,7 +2013,7 @@ var __exports__ = (() => {
|
|
|
1840
2013
|
userData = {};
|
|
1841
2014
|
constructor(props) {
|
|
1842
2015
|
const { attributes = {}, indices = null, vertexCount = null } = props;
|
|
1843
|
-
this.id = props.id || (0,
|
|
2016
|
+
this.id = props.id || (0, import_core13.uid)("geometry");
|
|
1844
2017
|
this.topology = props.topology;
|
|
1845
2018
|
if (indices) {
|
|
1846
2019
|
this.indices = ArrayBuffer.isView(indices) ? { value: indices, size: 1 } : indices;
|
|
@@ -1848,7 +2021,7 @@ var __exports__ = (() => {
|
|
|
1848
2021
|
this.attributes = {};
|
|
1849
2022
|
for (const [attributeName, attributeValue] of Object.entries(attributes)) {
|
|
1850
2023
|
const attribute = ArrayBuffer.isView(attributeValue) ? { value: attributeValue } : attributeValue;
|
|
1851
|
-
(0,
|
|
2024
|
+
(0, import_core13.assert)(
|
|
1852
2025
|
ArrayBuffer.isView(attribute.value),
|
|
1853
2026
|
`${this._print(attributeName)}: must be typed array or object with value as typed array`
|
|
1854
2027
|
);
|
|
@@ -1856,7 +2029,7 @@ var __exports__ = (() => {
|
|
|
1856
2029
|
attribute.size = 3;
|
|
1857
2030
|
}
|
|
1858
2031
|
if (attributeName === "indices") {
|
|
1859
|
-
(0,
|
|
2032
|
+
(0, import_core13.assert)(!this.indices);
|
|
1860
2033
|
this.indices = attribute;
|
|
1861
2034
|
} else {
|
|
1862
2035
|
this.attributes[attributeName] = attribute;
|
|
@@ -1871,7 +2044,7 @@ var __exports__ = (() => {
|
|
|
1871
2044
|
getVertexCount() {
|
|
1872
2045
|
return this.vertexCount;
|
|
1873
2046
|
}
|
|
1874
|
-
/**
|
|
2047
|
+
/**
|
|
1875
2048
|
* Return an object with all attributes plus indices added as a field.
|
|
1876
2049
|
* TODO Geometry types are a mess
|
|
1877
2050
|
*/
|
|
@@ -1888,10 +2061,10 @@ var __exports__ = (() => {
|
|
|
1888
2061
|
* type: indices, vertices, uvs
|
|
1889
2062
|
* size: elements per vertex
|
|
1890
2063
|
* target: WebGL buffer type (string or constant)
|
|
1891
|
-
*
|
|
1892
|
-
* @param attributes
|
|
1893
|
-
* @param indices
|
|
1894
|
-
* @returns
|
|
2064
|
+
*
|
|
2065
|
+
* @param attributes
|
|
2066
|
+
* @param indices
|
|
2067
|
+
* @returns
|
|
1895
2068
|
*/
|
|
1896
2069
|
_setAttributes(attributes, indices) {
|
|
1897
2070
|
return this;
|
|
@@ -1907,13 +2080,13 @@ var __exports__ = (() => {
|
|
|
1907
2080
|
vertexCount = Math.min(vertexCount, value.length / size);
|
|
1908
2081
|
}
|
|
1909
2082
|
}
|
|
1910
|
-
(0,
|
|
2083
|
+
(0, import_core13.assert)(Number.isFinite(vertexCount));
|
|
1911
2084
|
return vertexCount;
|
|
1912
2085
|
}
|
|
1913
2086
|
};
|
|
1914
2087
|
|
|
1915
2088
|
// src/lib/clip-space.ts
|
|
1916
|
-
var CLIPSPACE_VERTEX_SHADER =
|
|
2089
|
+
var CLIPSPACE_VERTEX_SHADER = import_core14.glsl`\
|
|
1917
2090
|
#version 300 es
|
|
1918
2091
|
in vec2 aClipSpacePosition;
|
|
1919
2092
|
in vec2 aTexCoord;
|
|
@@ -1934,28 +2107,25 @@ void main(void) {
|
|
|
1934
2107
|
var ClipSpace = class extends Model {
|
|
1935
2108
|
constructor(device, opts) {
|
|
1936
2109
|
const TEX_COORDS = POSITIONS.map((coord) => coord === -1 ? 0 : coord);
|
|
1937
|
-
super(
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
2110
|
+
super(device, {
|
|
2111
|
+
...opts,
|
|
2112
|
+
vs: CLIPSPACE_VERTEX_SHADER,
|
|
2113
|
+
vertexCount: 4,
|
|
2114
|
+
geometry: new Geometry({
|
|
2115
|
+
topology: "triangle-strip",
|
|
1942
2116
|
vertexCount: 4,
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
}
|
|
1951
|
-
})
|
|
1952
|
-
}
|
|
1953
|
-
);
|
|
2117
|
+
attributes: {
|
|
2118
|
+
aClipSpacePosition: { size: 2, value: new Float32Array(POSITIONS) },
|
|
2119
|
+
aTexCoord: { size: 2, value: new Float32Array(TEX_COORDS) },
|
|
2120
|
+
aCoordinate: { size: 2, value: new Float32Array(TEX_COORDS) }
|
|
2121
|
+
}
|
|
2122
|
+
})
|
|
2123
|
+
});
|
|
1954
2124
|
}
|
|
1955
2125
|
};
|
|
1956
2126
|
|
|
1957
2127
|
// src/scenegraph/scenegraph-node.ts
|
|
1958
|
-
var
|
|
2128
|
+
var import_core15 = __toESM(require_core(), 1);
|
|
1959
2129
|
|
|
1960
2130
|
// ../../node_modules/@math.gl/core/dist/lib/common.js
|
|
1961
2131
|
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
|
|
@@ -3858,7 +4028,7 @@ void main(void) {
|
|
|
3858
4028
|
props = {};
|
|
3859
4029
|
constructor(props = {}) {
|
|
3860
4030
|
const { id } = props;
|
|
3861
|
-
this.id = id || (0,
|
|
4031
|
+
this.id = id || (0, import_core15.uid)(this.constructor.name);
|
|
3862
4032
|
this._setScenegraphNodeProps(props);
|
|
3863
4033
|
}
|
|
3864
4034
|
getBounds() {
|
|
@@ -3878,17 +4048,17 @@ void main(void) {
|
|
|
3878
4048
|
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
3879
4049
|
}
|
|
3880
4050
|
setPosition(position) {
|
|
3881
|
-
(0,
|
|
4051
|
+
(0, import_core15.assert)(position.length === 3, "setPosition requires vector argument");
|
|
3882
4052
|
this.position = position;
|
|
3883
4053
|
return this;
|
|
3884
4054
|
}
|
|
3885
4055
|
setRotation(rotation) {
|
|
3886
|
-
(0,
|
|
4056
|
+
(0, import_core15.assert)(rotation.length === 3, "setRotation requires vector argument");
|
|
3887
4057
|
this.rotation = rotation;
|
|
3888
4058
|
return this;
|
|
3889
4059
|
}
|
|
3890
4060
|
setScale(scale2) {
|
|
3891
|
-
(0,
|
|
4061
|
+
(0, import_core15.assert)(scale2.length === 3, "setScale requires vector argument");
|
|
3892
4062
|
this.scale = scale2;
|
|
3893
4063
|
return this;
|
|
3894
4064
|
}
|
|
@@ -3940,7 +4110,7 @@ void main(void) {
|
|
|
3940
4110
|
return this;
|
|
3941
4111
|
}
|
|
3942
4112
|
getCoordinateUniforms(viewMatrix, modelMatrix) {
|
|
3943
|
-
(0,
|
|
4113
|
+
(0, import_core15.assert)(viewMatrix);
|
|
3944
4114
|
modelMatrix = modelMatrix || this.matrix;
|
|
3945
4115
|
const worldMatrix = new Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
3946
4116
|
const worldInverse = worldMatrix.invert();
|
|
@@ -3997,13 +4167,13 @@ void main(void) {
|
|
|
3997
4167
|
};
|
|
3998
4168
|
|
|
3999
4169
|
// src/scenegraph/group-node.ts
|
|
4000
|
-
var
|
|
4170
|
+
var import_core18 = __toESM(require_core(), 1);
|
|
4001
4171
|
var GroupNode = class extends ScenegraphNode {
|
|
4002
4172
|
children;
|
|
4003
4173
|
constructor(props = {}) {
|
|
4004
4174
|
props = Array.isArray(props) ? { children: props } : props;
|
|
4005
4175
|
const { children = [] } = props;
|
|
4006
|
-
|
|
4176
|
+
import_core18.log.assert(
|
|
4007
4177
|
children.every((child) => child instanceof ScenegraphNode),
|
|
4008
4178
|
"every child must an instance of ScenegraphNode"
|
|
4009
4179
|
);
|
|
@@ -4011,7 +4181,10 @@ void main(void) {
|
|
|
4011
4181
|
this.children = children;
|
|
4012
4182
|
}
|
|
4013
4183
|
getBounds() {
|
|
4014
|
-
const result = [
|
|
4184
|
+
const result = [
|
|
4185
|
+
[Infinity, Infinity, Infinity],
|
|
4186
|
+
[-Infinity, -Infinity, -Infinity]
|
|
4187
|
+
];
|
|
4015
4188
|
this.traverse((node, { worldMatrix }) => {
|
|
4016
4189
|
const bounds = node.getBounds();
|
|
4017
4190
|
if (!bounds) {
|
|
@@ -4023,11 +4196,7 @@ void main(void) {
|
|
|
4023
4196
|
const halfSize = new Vector3(max).subtract(min).divide([2, 2, 2]);
|
|
4024
4197
|
worldMatrix.transformAsVector(halfSize, halfSize);
|
|
4025
4198
|
for (let v = 0; v < 8; v++) {
|
|
4026
|
-
const position = new Vector3(
|
|
4027
|
-
v & 1 ? -1 : 1,
|
|
4028
|
-
v & 2 ? -1 : 1,
|
|
4029
|
-
v & 4 ? -1 : 1
|
|
4030
|
-
).multiply(halfSize).add(center);
|
|
4199
|
+
const position = new Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
|
|
4031
4200
|
for (let i = 0; i < 3; i++) {
|
|
4032
4201
|
result[0][i] = Math.min(result[0][i], position[i]);
|
|
4033
4202
|
result[1][i] = Math.max(result[1][i], position[i]);
|
|
@@ -4113,10 +4282,10 @@ void main(void) {
|
|
|
4113
4282
|
};
|
|
4114
4283
|
|
|
4115
4284
|
// src/geometries/cone-geometry.ts
|
|
4116
|
-
var
|
|
4285
|
+
var import_core20 = __toESM(require_core(), 1);
|
|
4117
4286
|
|
|
4118
4287
|
// src/geometries/truncated-cone-geometry.ts
|
|
4119
|
-
var
|
|
4288
|
+
var import_core19 = __toESM(require_core(), 1);
|
|
4120
4289
|
var INDEX_OFFSETS = {
|
|
4121
4290
|
x: [2, 0, 1],
|
|
4122
4291
|
y: [0, 1, 2],
|
|
@@ -4124,7 +4293,7 @@ void main(void) {
|
|
|
4124
4293
|
};
|
|
4125
4294
|
var TruncatedConeGeometry = class extends Geometry {
|
|
4126
4295
|
constructor(props = {}) {
|
|
4127
|
-
const { id = (0,
|
|
4296
|
+
const { id = (0, import_core19.uid)("truncated-code-geometry") } = props;
|
|
4128
4297
|
const { indices, attributes } = tesselateTruncatedCone(props);
|
|
4129
4298
|
super({
|
|
4130
4299
|
...props,
|
|
@@ -4228,7 +4397,7 @@ void main(void) {
|
|
|
4228
4397
|
// src/geometries/cone-geometry.ts
|
|
4229
4398
|
var ConeGeometry = class extends TruncatedConeGeometry {
|
|
4230
4399
|
constructor(props = {}) {
|
|
4231
|
-
const { id = (0,
|
|
4400
|
+
const { id = (0, import_core20.uid)("cone-geometry"), radius = 1, cap = true } = props;
|
|
4232
4401
|
super({
|
|
4233
4402
|
...props,
|
|
4234
4403
|
id,
|
|
@@ -4241,23 +4410,25 @@ void main(void) {
|
|
|
4241
4410
|
};
|
|
4242
4411
|
|
|
4243
4412
|
// src/geometries/cube-geometry.ts
|
|
4244
|
-
var
|
|
4413
|
+
var import_core21 = __toESM(require_core(), 1);
|
|
4245
4414
|
var CubeGeometry = class extends Geometry {
|
|
4246
4415
|
constructor(props = {}) {
|
|
4247
|
-
const { id = (0,
|
|
4248
|
-
super(
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4416
|
+
const { id = (0, import_core21.uid)("cube-geometry"), indices = true } = props;
|
|
4417
|
+
super(
|
|
4418
|
+
indices ? {
|
|
4419
|
+
...props,
|
|
4420
|
+
id,
|
|
4421
|
+
topology: "triangle-list",
|
|
4422
|
+
indices: { size: 1, value: CUBE_INDICES },
|
|
4423
|
+
attributes: { ...ATTRIBUTES, ...props.attributes }
|
|
4424
|
+
} : {
|
|
4425
|
+
...props,
|
|
4426
|
+
id,
|
|
4427
|
+
topology: "triangle-list",
|
|
4428
|
+
indices: void 0,
|
|
4429
|
+
attributes: { ...NON_INDEXED_ATTRIBUTES, ...props.attributes }
|
|
4430
|
+
}
|
|
4431
|
+
);
|
|
4261
4432
|
}
|
|
4262
4433
|
};
|
|
4263
4434
|
var CUBE_INDICES = new Uint16Array([
|
|
@@ -4851,10 +5022,10 @@ void main(void) {
|
|
|
4851
5022
|
};
|
|
4852
5023
|
|
|
4853
5024
|
// src/geometries/cylinder-geometry.ts
|
|
4854
|
-
var
|
|
5025
|
+
var import_core22 = __toESM(require_core(), 1);
|
|
4855
5026
|
var CylinderGeometry = class extends TruncatedConeGeometry {
|
|
4856
5027
|
constructor(props = {}) {
|
|
4857
|
-
const { id = (0,
|
|
5028
|
+
const { id = (0, import_core22.uid)("cylinder-geometry"), radius = 1 } = props;
|
|
4858
5029
|
super({
|
|
4859
5030
|
...props,
|
|
4860
5031
|
id,
|
|
@@ -4865,12 +5036,12 @@ void main(void) {
|
|
|
4865
5036
|
};
|
|
4866
5037
|
|
|
4867
5038
|
// src/geometries/ico-sphere-geometry.ts
|
|
4868
|
-
var
|
|
5039
|
+
var import_core23 = __toESM(require_core(), 1);
|
|
4869
5040
|
var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
|
|
4870
5041
|
var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
|
|
4871
5042
|
var IcoSphereGeometry = class extends Geometry {
|
|
4872
5043
|
constructor(props = {}) {
|
|
4873
|
-
const { id = (0,
|
|
5044
|
+
const { id = (0, import_core23.uid)("ico-sphere-geometry") } = props;
|
|
4874
5045
|
const { indices, attributes } = tesselateIcosaHedron(props);
|
|
4875
5046
|
super({
|
|
4876
5047
|
...props,
|
|
@@ -5012,7 +5183,7 @@ void main(void) {
|
|
|
5012
5183
|
}
|
|
5013
5184
|
|
|
5014
5185
|
// src/geometries/plane-geometry.ts
|
|
5015
|
-
var
|
|
5186
|
+
var import_core25 = __toESM(require_core(), 1);
|
|
5016
5187
|
|
|
5017
5188
|
// src/geometry/geometry-utils.ts
|
|
5018
5189
|
function unpackIndexedGeometry(geometry) {
|
|
@@ -5045,7 +5216,7 @@ void main(void) {
|
|
|
5045
5216
|
// src/geometries/plane-geometry.ts
|
|
5046
5217
|
var PlaneGeometry = class extends Geometry {
|
|
5047
5218
|
constructor(props = {}) {
|
|
5048
|
-
const { id = (0,
|
|
5219
|
+
const { id = (0, import_core25.uid)("plane-geometry") } = props;
|
|
5049
5220
|
const { indices, attributes } = tesselatePlane(props);
|
|
5050
5221
|
super({
|
|
5051
5222
|
...props,
|
|
@@ -5135,10 +5306,10 @@ void main(void) {
|
|
|
5135
5306
|
}
|
|
5136
5307
|
|
|
5137
5308
|
// src/geometries/sphere-geometry.ts
|
|
5138
|
-
var
|
|
5309
|
+
var import_core26 = __toESM(require_core(), 1);
|
|
5139
5310
|
var SphereGeometry = class extends Geometry {
|
|
5140
5311
|
constructor(props = {}) {
|
|
5141
|
-
const { id = (0,
|
|
5312
|
+
const { id = (0, import_core26.uid)("sphere-geometry") } = props;
|
|
5142
5313
|
const { indices, attributes } = tesselateSphere(props);
|
|
5143
5314
|
super({
|
|
5144
5315
|
...props,
|
|
@@ -5212,6 +5383,219 @@ void main(void) {
|
|
|
5212
5383
|
}
|
|
5213
5384
|
};
|
|
5214
5385
|
}
|
|
5386
|
+
|
|
5387
|
+
// src/computation.ts
|
|
5388
|
+
var import_core27 = __toESM(require_core(), 1);
|
|
5389
|
+
var import_core28 = __toESM(require_core(), 1);
|
|
5390
|
+
var import_core29 = __toESM(require_core(), 1);
|
|
5391
|
+
var import_shadertools5 = __toESM(require_shadertools(), 1);
|
|
5392
|
+
var LOG_DRAW_PRIORITY2 = 2;
|
|
5393
|
+
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
5394
|
+
var _Computation = class {
|
|
5395
|
+
device;
|
|
5396
|
+
id;
|
|
5397
|
+
pipelineFactory;
|
|
5398
|
+
shaderFactory;
|
|
5399
|
+
userData = {};
|
|
5400
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
5401
|
+
bindings = {};
|
|
5402
|
+
/** The underlying GPU "program". @note May be recreated if parameters change */
|
|
5403
|
+
pipeline;
|
|
5404
|
+
/** the underlying compiled compute shader */
|
|
5405
|
+
shader;
|
|
5406
|
+
source;
|
|
5407
|
+
/** ShaderInputs instance */
|
|
5408
|
+
shaderInputs;
|
|
5409
|
+
_uniformStore;
|
|
5410
|
+
_pipelineNeedsUpdate = "newly created";
|
|
5411
|
+
_getModuleUniforms;
|
|
5412
|
+
props;
|
|
5413
|
+
_destroyed = false;
|
|
5414
|
+
constructor(device, props) {
|
|
5415
|
+
if (device.type !== "webgpu") {
|
|
5416
|
+
throw new Error("Computation is only supported in WebGPU");
|
|
5417
|
+
}
|
|
5418
|
+
this.props = { ..._Computation.defaultProps, ...props };
|
|
5419
|
+
props = this.props;
|
|
5420
|
+
this.id = props.id || (0, import_core28.uid)("model");
|
|
5421
|
+
this.device = device;
|
|
5422
|
+
Object.assign(this.userData, props.userData);
|
|
5423
|
+
const moduleMap = Object.fromEntries(
|
|
5424
|
+
this.props.modules?.map((module) => [module.name, module]) || []
|
|
5425
|
+
);
|
|
5426
|
+
this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
|
|
5427
|
+
this.props.shaderLayout ||= (0, import_shadertools5.getShaderLayoutFromWGSL)(this.props.source);
|
|
5428
|
+
const platformInfo = getPlatformInfo2(device);
|
|
5429
|
+
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
5430
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
5431
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
5432
|
+
const { source, getUniforms } = this.props.shaderAssembler.assembleShader({
|
|
5433
|
+
platformInfo,
|
|
5434
|
+
...this.props,
|
|
5435
|
+
modules
|
|
5436
|
+
});
|
|
5437
|
+
this.source = source;
|
|
5438
|
+
this._getModuleUniforms = getUniforms;
|
|
5439
|
+
this.pipeline = this._updatePipeline();
|
|
5440
|
+
if (props.bindings) {
|
|
5441
|
+
this.setBindings(props.bindings);
|
|
5442
|
+
}
|
|
5443
|
+
Object.seal(this);
|
|
5444
|
+
}
|
|
5445
|
+
destroy() {
|
|
5446
|
+
if (this._destroyed)
|
|
5447
|
+
return;
|
|
5448
|
+
this.pipelineFactory.release(this.pipeline);
|
|
5449
|
+
this.shaderFactory.release(this.shader);
|
|
5450
|
+
this._uniformStore.destroy();
|
|
5451
|
+
this._destroyed = true;
|
|
5452
|
+
}
|
|
5453
|
+
// Draw call
|
|
5454
|
+
predraw() {
|
|
5455
|
+
this.updateShaderInputs();
|
|
5456
|
+
}
|
|
5457
|
+
dispatch(computePass, x, y, z) {
|
|
5458
|
+
try {
|
|
5459
|
+
this._logDrawCallStart();
|
|
5460
|
+
this.pipeline = this._updatePipeline();
|
|
5461
|
+
this.pipeline.setBindings(this.bindings);
|
|
5462
|
+
computePass.setPipeline(this.pipeline);
|
|
5463
|
+
computePass.setBindings([]);
|
|
5464
|
+
computePass.dispatch(x, y, z);
|
|
5465
|
+
} finally {
|
|
5466
|
+
this._logDrawCallEnd();
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
5470
|
+
// Update dynamic fields
|
|
5471
|
+
/**
|
|
5472
|
+
* Updates the vertex count (used in draw calls)
|
|
5473
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
5474
|
+
*/
|
|
5475
|
+
setVertexCount(vertexCount) {
|
|
5476
|
+
}
|
|
5477
|
+
/**
|
|
5478
|
+
* Updates the instance count (used in draw calls)
|
|
5479
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
5480
|
+
*/
|
|
5481
|
+
setInstanceCount(instanceCount) {
|
|
5482
|
+
}
|
|
5483
|
+
setShaderInputs(shaderInputs) {
|
|
5484
|
+
this.shaderInputs = shaderInputs;
|
|
5485
|
+
this._uniformStore = new import_core27.UniformStore(this.shaderInputs.modules);
|
|
5486
|
+
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
5487
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
5488
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
/**
|
|
5492
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
5493
|
+
*/
|
|
5494
|
+
setShaderModuleProps(props) {
|
|
5495
|
+
const uniforms = this._getModuleUniforms(props);
|
|
5496
|
+
const keys = Object.keys(uniforms).filter((k) => {
|
|
5497
|
+
const uniform = uniforms[k];
|
|
5498
|
+
return !(0, import_core28.isNumberArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
5499
|
+
});
|
|
5500
|
+
const bindings = {};
|
|
5501
|
+
for (const k of keys) {
|
|
5502
|
+
bindings[k] = uniforms[k];
|
|
5503
|
+
delete uniforms[k];
|
|
5504
|
+
}
|
|
5505
|
+
}
|
|
5506
|
+
updateShaderInputs() {
|
|
5507
|
+
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
5508
|
+
}
|
|
5509
|
+
/**
|
|
5510
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
5511
|
+
*/
|
|
5512
|
+
setBindings(bindings) {
|
|
5513
|
+
Object.assign(this.bindings, bindings);
|
|
5514
|
+
}
|
|
5515
|
+
_setPipelineNeedsUpdate(reason) {
|
|
5516
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
5517
|
+
}
|
|
5518
|
+
_updatePipeline() {
|
|
5519
|
+
if (this._pipelineNeedsUpdate) {
|
|
5520
|
+
let prevShader = null;
|
|
5521
|
+
if (this.pipeline) {
|
|
5522
|
+
import_core28.log.log(
|
|
5523
|
+
1,
|
|
5524
|
+
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
5525
|
+
)();
|
|
5526
|
+
prevShader = this.shader;
|
|
5527
|
+
}
|
|
5528
|
+
this._pipelineNeedsUpdate = false;
|
|
5529
|
+
this.shader = this.shaderFactory.createShader({
|
|
5530
|
+
id: `${this.id}-fragment`,
|
|
5531
|
+
stage: "compute",
|
|
5532
|
+
source: this.source,
|
|
5533
|
+
debug: this.props.debugShaders
|
|
5534
|
+
});
|
|
5535
|
+
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
5536
|
+
...this.props,
|
|
5537
|
+
shader: this.shader
|
|
5538
|
+
});
|
|
5539
|
+
if (prevShader) {
|
|
5540
|
+
this.shaderFactory.release(prevShader);
|
|
5541
|
+
}
|
|
5542
|
+
}
|
|
5543
|
+
return this.pipeline;
|
|
5544
|
+
}
|
|
5545
|
+
/** Throttle draw call logging */
|
|
5546
|
+
_lastLogTime = 0;
|
|
5547
|
+
_logOpen = false;
|
|
5548
|
+
_logDrawCallStart() {
|
|
5549
|
+
const logDrawTimeout = import_core28.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
5550
|
+
if (import_core28.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
5551
|
+
return;
|
|
5552
|
+
}
|
|
5553
|
+
this._lastLogTime = Date.now();
|
|
5554
|
+
this._logOpen = true;
|
|
5555
|
+
import_core28.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core28.log.level <= 2 })();
|
|
5556
|
+
}
|
|
5557
|
+
_logDrawCallEnd() {
|
|
5558
|
+
if (this._logOpen) {
|
|
5559
|
+
const uniformTable = this.shaderInputs.getDebugTable();
|
|
5560
|
+
import_core28.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
5561
|
+
import_core28.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
5562
|
+
this._logOpen = false;
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5565
|
+
_drawCount = 0;
|
|
5566
|
+
// TODO - fix typing of luma data types
|
|
5567
|
+
_getBufferOrConstantValues(attribute, dataType) {
|
|
5568
|
+
const TypedArrayConstructor = (0, import_core29.getTypedArrayFromDataType)(dataType);
|
|
5569
|
+
const typedArray = attribute instanceof import_core27.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
5570
|
+
return typedArray.toString();
|
|
5571
|
+
}
|
|
5572
|
+
};
|
|
5573
|
+
var Computation = _Computation;
|
|
5574
|
+
__publicField(Computation, "defaultProps", {
|
|
5575
|
+
...import_core27.ComputePipeline.defaultProps,
|
|
5576
|
+
id: "unnamed",
|
|
5577
|
+
handle: void 0,
|
|
5578
|
+
userData: {},
|
|
5579
|
+
source: "",
|
|
5580
|
+
modules: [],
|
|
5581
|
+
defines: {},
|
|
5582
|
+
bindings: void 0,
|
|
5583
|
+
shaderInputs: void 0,
|
|
5584
|
+
pipelineFactory: void 0,
|
|
5585
|
+
shaderFactory: void 0,
|
|
5586
|
+
shaderAssembler: import_shadertools5.ShaderAssembler.getDefaultShaderAssembler(),
|
|
5587
|
+
debugShaders: void 0
|
|
5588
|
+
});
|
|
5589
|
+
function getPlatformInfo2(device) {
|
|
5590
|
+
return {
|
|
5591
|
+
type: device.type,
|
|
5592
|
+
shaderLanguage: device.info.shadingLanguage,
|
|
5593
|
+
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
5594
|
+
gpu: device.info.gpu,
|
|
5595
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
5596
|
+
features: device.features
|
|
5597
|
+
};
|
|
5598
|
+
}
|
|
5215
5599
|
return __toCommonJS(src_exports);
|
|
5216
5600
|
})();
|
|
5217
5601
|
return __exports__;
|