@luma.gl/engine 9.2.6 → 9.3.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation-loop/animation-loop.d.ts +11 -5
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +83 -47
- package/dist/animation-loop/animation-loop.js.map +1 -1
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/make-animation-loop.js +8 -1
- package/dist/animation-loop/make-animation-loop.js.map +1 -1
- package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
- package/dist/animation-loop/request-animation-frame.js +23 -6
- package/dist/animation-loop/request-animation-frame.js.map +1 -1
- package/dist/compute/computation.d.ts +3 -7
- package/dist/compute/computation.d.ts.map +1 -1
- package/dist/compute/computation.js +16 -13
- package/dist/compute/computation.js.map +1 -1
- package/dist/compute/swap.d.ts +2 -0
- package/dist/compute/swap.d.ts.map +1 -1
- package/dist/compute/swap.js +10 -5
- package/dist/compute/swap.js.map +1 -1
- package/dist/debug/debug-framebuffer.d.ts +9 -4
- package/dist/debug/debug-framebuffer.d.ts.map +1 -1
- package/dist/debug/debug-framebuffer.js +91 -45
- package/dist/debug/debug-framebuffer.js.map +1 -1
- package/dist/dist.dev.js +2767 -1344
- package/dist/dist.min.js +326 -211
- package/dist/dynamic-texture/dynamic-texture.d.ts +102 -0
- package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -0
- package/dist/dynamic-texture/dynamic-texture.js +558 -0
- package/dist/dynamic-texture/dynamic-texture.js.map +1 -0
- package/dist/dynamic-texture/texture-data.d.ts +144 -0
- package/dist/dynamic-texture/texture-data.d.ts.map +1 -0
- package/dist/dynamic-texture/texture-data.js +208 -0
- package/dist/dynamic-texture/texture-data.js.map +1 -0
- package/dist/geometries/cone-geometry.d.ts +3 -1
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js.map +1 -1
- package/dist/geometries/cube-geometry.js +7 -7
- package/dist/geometries/cube-geometry.js.map +1 -1
- package/dist/geometries/cylinder-geometry.d.ts +2 -1
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js.map +1 -1
- package/dist/geometries/ico-sphere-geometry.js +3 -1
- package/dist/geometries/ico-sphere-geometry.js.map +1 -1
- package/dist/geometry/gpu-geometry.d.ts.map +1 -1
- package/dist/geometry/gpu-geometry.js +11 -3
- package/dist/geometry/gpu-geometry.js.map +1 -1
- package/dist/index.cjs +2620 -1267
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +20 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/material/material-factory.d.ts +73 -0
- package/dist/material/material-factory.d.ts.map +1 -0
- package/dist/material/material-factory.js +111 -0
- package/dist/material/material-factory.js.map +1 -0
- package/dist/material/material.d.ts +84 -0
- package/dist/material/material.d.ts.map +1 -0
- package/dist/material/material.js +176 -0
- package/dist/material/material.js.map +1 -0
- package/dist/model/model.d.ts +47 -16
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +148 -71
- package/dist/model/model.js.map +1 -1
- package/dist/model/split-uniforms-and-bindings.d.ts +4 -3
- package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
- package/dist/model/split-uniforms-and-bindings.js +2 -2
- package/dist/model/split-uniforms-and-bindings.js.map +1 -1
- package/dist/models/billboard-texture-model.d.ts +8 -5
- package/dist/models/billboard-texture-model.d.ts.map +1 -1
- package/dist/models/billboard-texture-model.js +79 -25
- package/dist/models/billboard-texture-model.js.map +1 -1
- package/dist/models/billboard-texture-module.d.ts +1 -1
- package/dist/models/billboard-texture-module.js +1 -1
- package/dist/models/clip-space.js +7 -7
- package/dist/models/directional-light-model.d.ts +7 -0
- package/dist/models/directional-light-model.d.ts.map +1 -0
- package/dist/models/directional-light-model.js +23 -0
- package/dist/models/directional-light-model.js.map +1 -0
- package/dist/models/light-model-utils.d.ts +69 -0
- package/dist/models/light-model-utils.d.ts.map +1 -0
- package/dist/models/light-model-utils.js +395 -0
- package/dist/models/light-model-utils.js.map +1 -0
- package/dist/models/point-light-model.d.ts +7 -0
- package/dist/models/point-light-model.d.ts.map +1 -0
- package/dist/models/point-light-model.js +22 -0
- package/dist/models/point-light-model.js.map +1 -0
- package/dist/models/spot-light-model.d.ts +7 -0
- package/dist/models/spot-light-model.d.ts.map +1 -0
- package/dist/models/spot-light-model.js +23 -0
- package/dist/models/spot-light-model.js.map +1 -0
- package/dist/modules/picking/color-picking.d.ts +5 -9
- package/dist/modules/picking/color-picking.d.ts.map +1 -1
- package/dist/modules/picking/color-picking.js +122 -115
- package/dist/modules/picking/color-picking.js.map +1 -1
- package/dist/modules/picking/index-picking.d.ts +4 -4
- package/dist/modules/picking/index-picking.d.ts.map +1 -1
- package/dist/modules/picking/index-picking.js +36 -16
- package/dist/modules/picking/index-picking.js.map +1 -1
- package/dist/modules/picking/legacy-color-picking.d.ts +26 -0
- package/dist/modules/picking/legacy-color-picking.d.ts.map +1 -0
- package/dist/modules/picking/legacy-color-picking.js +7 -0
- package/dist/modules/picking/legacy-color-picking.js.map +1 -0
- package/dist/modules/picking/picking-manager.d.ts +29 -3
- package/dist/modules/picking/picking-manager.d.ts.map +1 -1
- package/dist/modules/picking/picking-manager.js +188 -41
- package/dist/modules/picking/picking-manager.js.map +1 -1
- package/dist/modules/picking/picking-uniforms.d.ts +13 -12
- package/dist/modules/picking/picking-uniforms.d.ts.map +1 -1
- package/dist/modules/picking/picking-uniforms.js +27 -14
- package/dist/modules/picking/picking-uniforms.js.map +1 -1
- package/dist/modules/picking/picking.d.ts +25 -0
- package/dist/modules/picking/picking.d.ts.map +1 -0
- package/dist/modules/picking/picking.js +18 -0
- package/dist/modules/picking/picking.js.map +1 -0
- package/dist/passes/get-fragment-shader.js +12 -27
- package/dist/passes/get-fragment-shader.js.map +1 -1
- package/dist/passes/shader-pass-renderer.d.ts +5 -7
- package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
- package/dist/passes/shader-pass-renderer.js +16 -42
- package/dist/passes/shader-pass-renderer.js.map +1 -1
- package/dist/scenegraph/group-node.d.ts +5 -0
- package/dist/scenegraph/group-node.d.ts.map +1 -1
- package/dist/scenegraph/group-node.js +12 -0
- package/dist/scenegraph/group-node.js.map +1 -1
- 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.map +1 -1
- package/dist/scenegraph/scenegraph-node.d.ts +1 -1
- package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
- package/dist/scenegraph/scenegraph-node.js +23 -15
- package/dist/scenegraph/scenegraph-node.js.map +1 -1
- package/dist/shader-inputs.d.ts +9 -7
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +90 -13
- package/dist/shader-inputs.js.map +1 -1
- package/dist/utils/buffer-layout-order.d.ts.map +1 -1
- package/dist/utils/buffer-layout-order.js +12 -2
- package/dist/utils/buffer-layout-order.js.map +1 -1
- package/dist/utils/shader-module-utils.d.ts +7 -0
- package/dist/utils/shader-module-utils.d.ts.map +1 -0
- package/dist/utils/shader-module-utils.js +46 -0
- package/dist/utils/shader-module-utils.js.map +1 -0
- package/package.json +6 -6
- package/src/animation-loop/animation-loop.ts +89 -50
- package/src/animation-loop/make-animation-loop.ts +14 -5
- package/src/animation-loop/request-animation-frame.ts +32 -6
- package/src/compute/computation.ts +32 -17
- package/src/compute/swap.ts +13 -7
- package/src/debug/debug-framebuffer.ts +139 -61
- package/src/dynamic-texture/dynamic-texture.ts +730 -0
- package/src/dynamic-texture/texture-data.ts +336 -0
- package/src/{async-texture/texture-setters.ts.disabled → dynamic-texture/texture-data.ts.disabled} +1 -1
- package/src/geometries/cone-geometry.ts +6 -1
- package/src/geometries/cube-geometry.ts +7 -7
- package/src/geometries/cylinder-geometry.ts +5 -1
- package/src/geometries/ico-sphere-geometry.ts +3 -1
- package/src/geometry/gpu-geometry.ts +11 -3
- package/src/index.ts +38 -8
- package/src/material/material-factory.ts +157 -0
- package/src/material/material.ts +254 -0
- package/src/model/model.ts +196 -93
- package/src/model/split-uniforms-and-bindings.ts +8 -6
- package/src/models/billboard-texture-model.ts +90 -29
- package/src/models/billboard-texture-module.ts +1 -1
- package/src/models/clip-space.ts +7 -7
- package/src/models/directional-light-model.ts +32 -0
- package/src/models/light-model-utils.ts +587 -0
- package/src/models/point-light-model.ts +31 -0
- package/src/models/spot-light-model.ts +32 -0
- package/src/modules/picking/color-picking.ts +123 -122
- package/src/modules/picking/index-picking.ts +36 -16
- package/src/modules/picking/legacy-color-picking.ts +8 -0
- package/src/modules/picking/picking-manager.ts +252 -50
- package/src/modules/picking/picking-uniforms.ts +39 -24
- package/src/modules/picking/picking.ts +22 -0
- package/src/passes/get-fragment-shader.ts +12 -27
- package/src/passes/shader-pass-renderer.ts +25 -48
- package/src/scenegraph/group-node.ts +16 -0
- package/src/scenegraph/model-node.ts +2 -2
- package/src/scenegraph/scenegraph-node.ts +27 -16
- package/src/shader-inputs.ts +167 -26
- package/src/utils/buffer-layout-order.ts +18 -2
- package/src/utils/shader-module-utils.ts +65 -0
- package/dist/async-texture/async-texture.d.ts +0 -166
- package/dist/async-texture/async-texture.d.ts.map +0 -1
- package/dist/async-texture/async-texture.js +0 -386
- package/dist/async-texture/async-texture.js.map +0 -1
- package/dist/factories/pipeline-factory.d.ts +0 -37
- package/dist/factories/pipeline-factory.d.ts.map +0 -1
- package/dist/factories/pipeline-factory.js +0 -181
- package/dist/factories/pipeline-factory.js.map +0 -1
- package/dist/factories/shader-factory.d.ts +0 -22
- package/dist/factories/shader-factory.d.ts.map +0 -1
- package/dist/factories/shader-factory.js +0 -88
- package/dist/factories/shader-factory.js.map +0 -1
- package/src/async-texture/async-texture.ts +0 -551
- package/src/factories/pipeline-factory.ts +0 -224
- package/src/factories/shader-factory.ts +0 -103
|
@@ -6,7 +6,7 @@ import {Device, RenderPass, Texture} from '@luma.gl/core';
|
|
|
6
6
|
import type {ShaderPass} from '@luma.gl/shadertools';
|
|
7
7
|
import {initializeShaderModule} from '@luma.gl/shadertools';
|
|
8
8
|
import {ShaderInputs} from '../shader-inputs';
|
|
9
|
-
import {
|
|
9
|
+
import {DynamicTexture} from '../dynamic-texture/dynamic-texture';
|
|
10
10
|
import {ClipSpace} from '../models/clip-space';
|
|
11
11
|
import {SwapFramebuffers} from '../compute/swap';
|
|
12
12
|
import {BackgroundTextureModel} from '../models/billboard-texture-model';
|
|
@@ -20,7 +20,7 @@ export type ShaderPassRendererProps = {
|
|
|
20
20
|
/** List of ShaderPasses to apply to the sourceTexture */
|
|
21
21
|
shaderPasses: ShaderPass[];
|
|
22
22
|
/** Optional typed ShaderInputs object for setting uniforms */
|
|
23
|
-
shaderInputs
|
|
23
|
+
shaderInputs?: ShaderInputs;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/** A pass that renders a given texture into screen space */
|
|
@@ -29,8 +29,6 @@ export class ShaderPassRenderer {
|
|
|
29
29
|
shaderInputs: ShaderInputs;
|
|
30
30
|
passRenderers: PassRenderer[];
|
|
31
31
|
swapFramebuffers: SwapFramebuffers;
|
|
32
|
-
/** For rendering to the screen */
|
|
33
|
-
clipSpace: ClipSpace;
|
|
34
32
|
textureModel: BackgroundTextureModel;
|
|
35
33
|
|
|
36
34
|
constructor(device: Device, props: ShaderPassRendererProps) {
|
|
@@ -55,33 +53,6 @@ export class ShaderPassRenderer {
|
|
|
55
53
|
backgroundTexture: this.swapFramebuffers.current.colorAttachments[0].texture
|
|
56
54
|
});
|
|
57
55
|
|
|
58
|
-
this.clipSpace = new ClipSpace(device, {
|
|
59
|
-
source: /* wgsl */ `\
|
|
60
|
-
@group(0) @binding(0) var sourceTexture: texture_2d<f32>;
|
|
61
|
-
@group(0) @binding(1) var sourceTextureSampler: sampler;
|
|
62
|
-
|
|
63
|
-
@fragment
|
|
64
|
-
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
|
|
65
|
-
let texCoord: vec2<f32> = inputs.coordinate;
|
|
66
|
-
return textureSample(sourceTexture, sourceTextureSampler, texCoord);
|
|
67
|
-
}
|
|
68
|
-
`,
|
|
69
|
-
|
|
70
|
-
fs: /* glsl */ `\
|
|
71
|
-
#version 300 es
|
|
72
|
-
|
|
73
|
-
uniform sampler2D sourceTexture;
|
|
74
|
-
in vec2 uv;
|
|
75
|
-
in vec2 coordinate;
|
|
76
|
-
out vec4 fragColor;
|
|
77
|
-
|
|
78
|
-
void main() {
|
|
79
|
-
vec2 texCoord = coordinate;
|
|
80
|
-
fragColor = texture(sourceTexture, coordinate);
|
|
81
|
-
}
|
|
82
|
-
`
|
|
83
|
-
});
|
|
84
|
-
|
|
85
56
|
this.passRenderers = props.shaderPasses.map(shaderPass => new PassRenderer(device, shaderPass));
|
|
86
57
|
}
|
|
87
58
|
|
|
@@ -91,15 +62,19 @@ void main() {
|
|
|
91
62
|
subPassRenderer.destroy();
|
|
92
63
|
}
|
|
93
64
|
this.swapFramebuffers.destroy();
|
|
94
|
-
this.
|
|
65
|
+
this.textureModel.destroy();
|
|
95
66
|
}
|
|
96
67
|
|
|
97
|
-
resize(width: number, height: number): void {
|
|
98
|
-
this.
|
|
99
|
-
|
|
68
|
+
resize(size?: [width: number, height: number]): void {
|
|
69
|
+
size ||= this.device.getCanvasContext().getDrawingBufferSize();
|
|
70
|
+
this.swapFramebuffers.resize({width: size[0], height: size[1]});
|
|
100
71
|
}
|
|
101
72
|
|
|
102
|
-
renderToScreen(options: {
|
|
73
|
+
renderToScreen(options: {
|
|
74
|
+
sourceTexture: DynamicTexture;
|
|
75
|
+
uniforms?: any;
|
|
76
|
+
bindings?: any;
|
|
77
|
+
}): boolean {
|
|
103
78
|
// Run the shader passes and generate an output texture
|
|
104
79
|
const outputTexture = this.renderToTexture(options);
|
|
105
80
|
if (!outputTexture) {
|
|
@@ -109,16 +84,15 @@ void main() {
|
|
|
109
84
|
|
|
110
85
|
const framebuffer = this.device
|
|
111
86
|
.getDefaultCanvasContext()
|
|
112
|
-
|
|
113
|
-
.getCurrentFramebuffer({depthStencilAttachment: false});
|
|
87
|
+
.getCurrentFramebuffer({depthStencilFormat: false});
|
|
114
88
|
const renderPass = this.device.beginRenderPass({
|
|
115
89
|
id: 'shader-pass-renderer-to-screen',
|
|
116
90
|
framebuffer,
|
|
117
|
-
clearColor: [
|
|
118
|
-
clearDepth:
|
|
91
|
+
// clearColor: [1, 1, 0, 1],
|
|
92
|
+
clearDepth: false
|
|
119
93
|
});
|
|
120
|
-
this.
|
|
121
|
-
this.
|
|
94
|
+
this.textureModel.setProps({backgroundTexture: outputTexture});
|
|
95
|
+
this.textureModel.draw(renderPass);
|
|
122
96
|
renderPass.end();
|
|
123
97
|
return true;
|
|
124
98
|
}
|
|
@@ -127,7 +101,7 @@ void main() {
|
|
|
127
101
|
* @returns null if the the sourceTexture has not yet been loaded
|
|
128
102
|
*/
|
|
129
103
|
renderToTexture(options: {
|
|
130
|
-
sourceTexture:
|
|
104
|
+
sourceTexture: DynamicTexture;
|
|
131
105
|
uniforms?: any;
|
|
132
106
|
bindings?: any;
|
|
133
107
|
}): Texture | null {
|
|
@@ -136,20 +110,23 @@ void main() {
|
|
|
136
110
|
return null;
|
|
137
111
|
}
|
|
138
112
|
|
|
139
|
-
|
|
140
|
-
this.
|
|
141
|
-
|
|
142
|
-
}
|
|
113
|
+
// If no shader passes are provided, just return the original texture
|
|
114
|
+
if (this.passRenderers.length === 0) {
|
|
115
|
+
return sourceTexture.texture;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.textureModel.setProps({backgroundTexture: sourceTexture});
|
|
143
119
|
|
|
144
120
|
// Clear the current texture before we begin
|
|
145
121
|
const clearTexturePass = this.device.beginRenderPass({
|
|
146
122
|
id: 'shader-pass-renderer-clear-texture',
|
|
147
123
|
framebuffer: this.swapFramebuffers.current,
|
|
148
|
-
clearColor: [
|
|
124
|
+
clearColor: [1, 0, 0, 1]
|
|
149
125
|
});
|
|
150
126
|
this.textureModel.draw(clearTexturePass);
|
|
151
127
|
clearTexturePass.end();
|
|
152
128
|
|
|
129
|
+
// Copy the texture contents
|
|
153
130
|
// const commandEncoder = this.device.createCommandEncoder();
|
|
154
131
|
// commandEncoder.copyTextureToTexture({
|
|
155
132
|
// sourceTexture: sourceTexture.texture,
|
|
@@ -108,4 +108,20 @@ export class GroupNode extends ScenegraphNode {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
preorderTraversal(
|
|
113
|
+
visitor: (node: ScenegraphNode, context: {worldMatrix: Matrix4}) => void,
|
|
114
|
+
{worldMatrix = new Matrix4()} = {}
|
|
115
|
+
) {
|
|
116
|
+
const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
117
|
+
visitor(this, {worldMatrix: modelMatrix});
|
|
118
|
+
|
|
119
|
+
for (const child of this.children) {
|
|
120
|
+
if (child instanceof GroupNode) {
|
|
121
|
+
child.preorderTraversal(visitor, {worldMatrix: modelMatrix});
|
|
122
|
+
} else {
|
|
123
|
+
visitor(child, {worldMatrix: modelMatrix});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
111
127
|
}
|
|
@@ -9,12 +9,12 @@ import {Model} from '../model/model';
|
|
|
9
9
|
export type ModelNodeProps = ScenegraphNodeProps & {
|
|
10
10
|
model: Model;
|
|
11
11
|
managedResources?: any[];
|
|
12
|
-
bounds?: [number
|
|
12
|
+
bounds?: [[number, number, number], [number, number, number]];
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export class ModelNode extends ScenegraphNode {
|
|
16
16
|
readonly model: Model;
|
|
17
|
-
bounds: [number
|
|
17
|
+
bounds: [[number, number, number], [number, number, number]] | null = null;
|
|
18
18
|
managedResources: any[];
|
|
19
19
|
|
|
20
20
|
// TODO - is this used? override callbacks to make sure we call them with this
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
import {Vector3, Matrix4, NumericArray} from '@math.gl/core';
|
|
6
6
|
import {uid} from '../utils/uid';
|
|
7
7
|
|
|
8
|
+
function assert(condition: boolean, message?: string): asserts condition {
|
|
9
|
+
if (!condition) {
|
|
10
|
+
throw new Error(message);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
/** Properties for creating a new Scenegraph */
|
|
9
15
|
export type ScenegraphNodeProps = {
|
|
10
16
|
id?: string;
|
|
@@ -57,19 +63,19 @@ export class ScenegraphNode {
|
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
setPosition(position: any): this {
|
|
60
|
-
|
|
66
|
+
assert(position.length === 3, 'setPosition requires vector argument');
|
|
61
67
|
this.position = position;
|
|
62
68
|
return this;
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
setRotation(rotation: any): this {
|
|
66
|
-
|
|
72
|
+
assert(rotation.length === 3 || rotation.length === 4, 'setRotation requires vector argument');
|
|
67
73
|
this.rotation = rotation;
|
|
68
74
|
return this;
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
setScale(scale: any): this {
|
|
72
|
-
|
|
78
|
+
assert(scale.length === 3, 'setScale requires vector argument');
|
|
73
79
|
this.scale = scale;
|
|
74
80
|
return this;
|
|
75
81
|
}
|
|
@@ -105,19 +111,20 @@ export class ScenegraphNode {
|
|
|
105
111
|
}
|
|
106
112
|
|
|
107
113
|
updateMatrix(): this {
|
|
108
|
-
const pos = this.position;
|
|
109
|
-
const rot = this.rotation;
|
|
110
|
-
const scale = this.scale;
|
|
111
|
-
|
|
112
114
|
this.matrix.identity();
|
|
113
|
-
this.matrix.translate(
|
|
114
|
-
this.
|
|
115
|
-
|
|
115
|
+
this.matrix.translate(this.position);
|
|
116
|
+
if (this.rotation.length === 4) {
|
|
117
|
+
const rotationMatrix = new Matrix4().fromQuaternion(this.rotation);
|
|
118
|
+
this.matrix.multiplyRight(rotationMatrix);
|
|
119
|
+
} else {
|
|
120
|
+
this.matrix.rotateXYZ(this.rotation);
|
|
121
|
+
}
|
|
122
|
+
this.matrix.scale(this.scale);
|
|
123
|
+
|
|
116
124
|
return this;
|
|
117
125
|
}
|
|
118
126
|
|
|
119
|
-
update(
|
|
120
|
-
const {position, rotation, scale} = options;
|
|
127
|
+
update({position, rotation, scale}: {position?: any; rotation?: any; scale?: any} = {}): this {
|
|
121
128
|
if (position) {
|
|
122
129
|
this.setPosition(position);
|
|
123
130
|
}
|
|
@@ -127,7 +134,9 @@ export class ScenegraphNode {
|
|
|
127
134
|
if (scale) {
|
|
128
135
|
this.setScale(scale);
|
|
129
136
|
}
|
|
137
|
+
|
|
130
138
|
this.updateMatrix();
|
|
139
|
+
|
|
131
140
|
return this;
|
|
132
141
|
}
|
|
133
142
|
|
|
@@ -188,18 +197,20 @@ export class ScenegraphNode {
|
|
|
188
197
|
// this.display = props.display;
|
|
189
198
|
// }
|
|
190
199
|
|
|
191
|
-
if (
|
|
200
|
+
if (props?.position) {
|
|
192
201
|
this.setPosition(props.position);
|
|
193
202
|
}
|
|
194
|
-
if (
|
|
203
|
+
if (props?.rotation) {
|
|
195
204
|
this.setRotation(props.rotation);
|
|
196
205
|
}
|
|
197
|
-
if (
|
|
206
|
+
if (props?.scale) {
|
|
198
207
|
this.setScale(props.scale);
|
|
199
208
|
}
|
|
200
209
|
|
|
210
|
+
this.updateMatrix();
|
|
211
|
+
|
|
201
212
|
// Matrix overwrites other props
|
|
202
|
-
if (
|
|
213
|
+
if (props?.matrix) {
|
|
203
214
|
this.setMatrix(props.matrix);
|
|
204
215
|
}
|
|
205
216
|
|
package/src/shader-inputs.ts
CHANGED
|
@@ -2,16 +2,25 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {Binding,
|
|
5
|
+
import type {Binding, CompositeShaderType} from '@luma.gl/core';
|
|
6
6
|
import {log} from '@luma.gl/core';
|
|
7
7
|
// import type {VariableShaderType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getShaderModuleDependencies,
|
|
10
|
+
ShaderModule,
|
|
11
|
+
ShaderModuleUniformValue
|
|
12
|
+
} from '@luma.gl/shadertools';
|
|
9
13
|
import {splitUniformsAndBindings} from './model/split-uniforms-and-bindings';
|
|
10
14
|
|
|
11
15
|
export type ShaderInputsOptions = {
|
|
12
16
|
disableWarnings?: boolean;
|
|
13
17
|
};
|
|
14
18
|
|
|
19
|
+
type ShaderInputsModule = Pick<
|
|
20
|
+
ShaderModule<any, any, any>,
|
|
21
|
+
'bindingLayout' | 'defaultUniforms' | 'dependencies' | 'getUniforms' | 'name' | 'uniformTypes'
|
|
22
|
+
>;
|
|
23
|
+
|
|
15
24
|
/**
|
|
16
25
|
* ShaderInputs holds uniform and binding values for one or more shader modules,
|
|
17
26
|
* - It can generate binary data for any uniform buffer
|
|
@@ -33,10 +42,10 @@ export class ShaderInputs<
|
|
|
33
42
|
* @todo should should this include the resolved dependencies?
|
|
34
43
|
*/
|
|
35
44
|
// @ts-ignore Fix typings
|
|
36
|
-
modules: Readonly<{[P in keyof ShaderPropsT]:
|
|
45
|
+
modules: Readonly<{[P in keyof ShaderPropsT]: ShaderInputsModule}>;
|
|
37
46
|
|
|
38
47
|
/** Stores the uniform values for each module */
|
|
39
|
-
moduleUniforms: Record<keyof ShaderPropsT, Record<string,
|
|
48
|
+
moduleUniforms: Record<keyof ShaderPropsT, Record<string, ShaderModuleUniformValue>>;
|
|
40
49
|
/** Stores the uniform bindings for each module */
|
|
41
50
|
moduleBindings: Record<keyof ShaderPropsT, Record<string, Binding>>;
|
|
42
51
|
/** Tracks if uniforms have changed */
|
|
@@ -48,14 +57,14 @@ export class ShaderInputs<
|
|
|
48
57
|
*/
|
|
49
58
|
constructor(
|
|
50
59
|
// @ts-ignore Fix typings
|
|
51
|
-
modules: {[P in keyof ShaderPropsT]?:
|
|
60
|
+
modules: {[P in keyof ShaderPropsT]?: ShaderInputsModule},
|
|
52
61
|
options?: ShaderInputsOptions
|
|
53
62
|
) {
|
|
54
63
|
Object.assign(this.options, options);
|
|
55
64
|
|
|
56
65
|
// Extract modules with dependencies
|
|
57
66
|
const resolvedModules = getShaderModuleDependencies(
|
|
58
|
-
Object.values(modules).filter(
|
|
67
|
+
Object.values(modules).filter(isShaderInputsModuleWithDependencies)
|
|
59
68
|
);
|
|
60
69
|
for (const resolvedModule of resolvedModules) {
|
|
61
70
|
// @ts-ignore
|
|
@@ -66,15 +75,20 @@ export class ShaderInputs<
|
|
|
66
75
|
|
|
67
76
|
// Store the module definitions and create storage for uniform values and binding values, per module
|
|
68
77
|
// @ts-ignore Fix typings
|
|
69
|
-
this.modules = modules as {[P in keyof ShaderPropsT]:
|
|
70
|
-
this.moduleUniforms = {} as Record<
|
|
78
|
+
this.modules = modules as {[P in keyof ShaderPropsT]: ShaderInputsModule};
|
|
79
|
+
this.moduleUniforms = {} as Record<
|
|
80
|
+
keyof ShaderPropsT,
|
|
81
|
+
Record<string, ShaderModuleUniformValue>
|
|
82
|
+
>;
|
|
71
83
|
this.moduleBindings = {} as Record<keyof ShaderPropsT, Record<string, Binding>>;
|
|
72
84
|
|
|
73
85
|
// Initialize the modules
|
|
74
86
|
for (const [name, module] of Object.entries(modules)) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
if (module) {
|
|
88
|
+
this._addModule(module);
|
|
89
|
+
if (module.name && name !== module.name && !this.options.disableWarnings) {
|
|
90
|
+
log.warn(`Module name: ${name} vs ${module.name}`)();
|
|
91
|
+
}
|
|
78
92
|
}
|
|
79
93
|
}
|
|
80
94
|
}
|
|
@@ -95,18 +109,24 @@ export class ShaderInputs<
|
|
|
95
109
|
if (!this.options.disableWarnings) {
|
|
96
110
|
log.warn(`Module ${name} not found`)();
|
|
97
111
|
}
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
} else {
|
|
113
|
+
const oldUniforms = this.moduleUniforms[moduleName];
|
|
114
|
+
const oldBindings = this.moduleBindings[moduleName];
|
|
115
|
+
const uniformsAndBindings =
|
|
116
|
+
module.getUniforms?.(moduleProps, oldUniforms) || (moduleProps as any);
|
|
100
117
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
const {uniforms, bindings} = splitUniformsAndBindings(
|
|
119
|
+
uniformsAndBindings,
|
|
120
|
+
module.uniformTypes as Readonly<Record<string, CompositeShaderType>>
|
|
121
|
+
);
|
|
122
|
+
this.moduleUniforms[moduleName] = mergeModuleUniforms(
|
|
123
|
+
oldUniforms as Record<string, ShaderModuleUniformValue>,
|
|
124
|
+
uniforms,
|
|
125
|
+
module.uniformTypes as Readonly<Record<string, CompositeShaderType>>
|
|
126
|
+
);
|
|
127
|
+
this.moduleBindings[moduleName] = {...oldBindings, ...bindings};
|
|
128
|
+
// this.moduleUniformsChanged ||= moduleName;
|
|
129
|
+
}
|
|
110
130
|
|
|
111
131
|
// console.log(`setProps(${String(moduleName)}`, moduleName, this.moduleUniforms[moduleName])
|
|
112
132
|
}
|
|
@@ -117,11 +137,13 @@ export class ShaderInputs<
|
|
|
117
137
|
* @todo should should this include the resolved dependencies?
|
|
118
138
|
*/
|
|
119
139
|
getModules(): ShaderModule[] {
|
|
120
|
-
return Object.values(this.modules);
|
|
140
|
+
return Object.values(this.modules) as ShaderModule[];
|
|
121
141
|
}
|
|
122
142
|
|
|
123
143
|
/** Get all uniform values for all modules */
|
|
124
|
-
getUniformValues(): Partial<
|
|
144
|
+
getUniformValues(): Partial<
|
|
145
|
+
Record<keyof ShaderPropsT, Record<string, ShaderModuleUniformValue>>
|
|
146
|
+
> {
|
|
125
147
|
return this.moduleUniforms;
|
|
126
148
|
}
|
|
127
149
|
|
|
@@ -150,10 +172,129 @@ export class ShaderInputs<
|
|
|
150
172
|
return table;
|
|
151
173
|
}
|
|
152
174
|
|
|
153
|
-
_addModule(module:
|
|
175
|
+
_addModule(module: ShaderInputsModule): void {
|
|
154
176
|
const moduleName = module.name as keyof ShaderPropsT;
|
|
155
177
|
// Get default uniforms from module
|
|
156
|
-
this.moduleUniforms[moduleName] =
|
|
178
|
+
this.moduleUniforms[moduleName] = mergeModuleUniforms(
|
|
179
|
+
{},
|
|
180
|
+
(module.defaultUniforms || {}) as Record<string, ShaderModuleUniformValue>,
|
|
181
|
+
module.uniformTypes as Readonly<Record<string, CompositeShaderType>>
|
|
182
|
+
);
|
|
157
183
|
this.moduleBindings[moduleName] = {};
|
|
158
184
|
}
|
|
159
185
|
}
|
|
186
|
+
|
|
187
|
+
function mergeModuleUniforms(
|
|
188
|
+
currentUniforms: Record<string, ShaderModuleUniformValue> = {},
|
|
189
|
+
nextUniforms: Record<string, ShaderModuleUniformValue> = {},
|
|
190
|
+
uniformTypes: Readonly<Record<string, CompositeShaderType>> = {}
|
|
191
|
+
): Record<string, ShaderModuleUniformValue> {
|
|
192
|
+
const mergedUniforms = {...currentUniforms};
|
|
193
|
+
for (const [key, value] of Object.entries(nextUniforms)) {
|
|
194
|
+
if (value !== undefined) {
|
|
195
|
+
mergedUniforms[key] = mergeModuleUniformValue(currentUniforms[key], value, uniformTypes[key]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return mergedUniforms;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function mergeModuleUniformValue(
|
|
202
|
+
currentValue: ShaderModuleUniformValue | undefined,
|
|
203
|
+
nextValue: ShaderModuleUniformValue,
|
|
204
|
+
uniformType: CompositeShaderType | undefined
|
|
205
|
+
): ShaderModuleUniformValue {
|
|
206
|
+
if (!uniformType || typeof uniformType === 'string') {
|
|
207
|
+
return cloneModuleUniformValue(nextValue);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (Array.isArray(uniformType)) {
|
|
211
|
+
if (isPackedUniformArrayValue(nextValue) || !Array.isArray(nextValue)) {
|
|
212
|
+
return cloneModuleUniformValue(nextValue);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const currentArray: Array<ShaderModuleUniformValue | undefined> =
|
|
216
|
+
Array.isArray(currentValue) && !isPackedUniformArrayValue(currentValue)
|
|
217
|
+
? [...currentValue]
|
|
218
|
+
: [];
|
|
219
|
+
const mergedArray = currentArray.slice();
|
|
220
|
+
for (let index = 0; index < nextValue.length; index++) {
|
|
221
|
+
const elementValue = nextValue[index];
|
|
222
|
+
if (elementValue !== undefined) {
|
|
223
|
+
mergedArray[index] = mergeModuleUniformValue(
|
|
224
|
+
currentArray[index],
|
|
225
|
+
elementValue,
|
|
226
|
+
uniformType[0] as CompositeShaderType
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return mergedArray;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!isPlainUniformObject(nextValue)) {
|
|
234
|
+
return cloneModuleUniformValue(nextValue);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const uniformStruct = uniformType as Record<string, CompositeShaderType>;
|
|
238
|
+
const currentObject = isPlainUniformObject(currentValue) ? currentValue : {};
|
|
239
|
+
const mergedObject: Record<string, ShaderModuleUniformValue | undefined> = {...currentObject};
|
|
240
|
+
for (const [key, value] of Object.entries(nextValue)) {
|
|
241
|
+
if (value !== undefined) {
|
|
242
|
+
mergedObject[key] = mergeModuleUniformValue(currentObject[key], value, uniformStruct[key]);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return mergedObject as ShaderModuleUniformValue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function cloneModuleUniformValue(value: ShaderModuleUniformValue): ShaderModuleUniformValue {
|
|
249
|
+
if (ArrayBuffer.isView(value)) {
|
|
250
|
+
return Array.prototype.slice.call(value) as ShaderModuleUniformValue;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (Array.isArray(value)) {
|
|
254
|
+
if (isPackedUniformArrayValue(value)) {
|
|
255
|
+
return value.slice() as ShaderModuleUniformValue;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const compositeArray = value as ReadonlyArray<ShaderModuleUniformValue | undefined>;
|
|
259
|
+
return compositeArray.map(element =>
|
|
260
|
+
element === undefined ? undefined : cloneModuleUniformValue(element)
|
|
261
|
+
) as ShaderModuleUniformValue;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (isPlainUniformObject(value)) {
|
|
265
|
+
return Object.fromEntries(
|
|
266
|
+
Object.entries(value).map(([key, nestedValue]) => [
|
|
267
|
+
key,
|
|
268
|
+
nestedValue === undefined ? undefined : cloneModuleUniformValue(nestedValue)
|
|
269
|
+
])
|
|
270
|
+
) as ShaderModuleUniformValue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return value;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function isPackedUniformArrayValue(
|
|
277
|
+
value: unknown
|
|
278
|
+
): value is ReadonlyArray<number> | ArrayBufferView {
|
|
279
|
+
return (
|
|
280
|
+
ArrayBuffer.isView(value) ||
|
|
281
|
+
(Array.isArray(value) && (value.length === 0 || typeof value[0] === 'number'))
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function isPlainUniformObject(
|
|
286
|
+
value: unknown
|
|
287
|
+
): value is Record<string, ShaderModuleUniformValue | undefined> {
|
|
288
|
+
return (
|
|
289
|
+
Boolean(value) &&
|
|
290
|
+
typeof value === 'object' &&
|
|
291
|
+
!Array.isArray(value) &&
|
|
292
|
+
!ArrayBuffer.isView(value)
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function isShaderInputsModuleWithDependencies(
|
|
297
|
+
module: ShaderInputsModule | undefined
|
|
298
|
+
): module is ShaderInputsModule & {dependencies: NonNullable<ShaderInputsModule['dependencies']>} {
|
|
299
|
+
return Boolean(module?.dependencies);
|
|
300
|
+
}
|
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
import {type BufferLayout, type ShaderLayout} from '@luma.gl/core';
|
|
6
6
|
|
|
7
|
+
function getMinLocation(
|
|
8
|
+
attributeNames: string[],
|
|
9
|
+
shaderLayoutMap: Record<string, number | undefined>
|
|
10
|
+
): number {
|
|
11
|
+
let minLocation = Infinity;
|
|
12
|
+
|
|
13
|
+
for (const name of attributeNames) {
|
|
14
|
+
const location = shaderLayoutMap[name];
|
|
15
|
+
if (location !== undefined) {
|
|
16
|
+
minLocation = Math.min(minLocation, location);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return minLocation;
|
|
21
|
+
}
|
|
22
|
+
|
|
7
23
|
export function sortedBufferLayoutByShaderSourceLocations(
|
|
8
24
|
shaderLayout: ShaderLayout,
|
|
9
25
|
bufferLayout: BufferLayout[]
|
|
@@ -16,8 +32,8 @@ export function sortedBufferLayoutByShaderSourceLocations(
|
|
|
16
32
|
sortedLayout.sort((a, b) => {
|
|
17
33
|
const attributeNamesA = a.attributes ? a.attributes.map(attr => attr.attribute) : [a.name];
|
|
18
34
|
const attributeNamesB = b.attributes ? b.attributes.map(attr => attr.attribute) : [b.name];
|
|
19
|
-
const minLocationA =
|
|
20
|
-
const minLocationB =
|
|
35
|
+
const minLocationA = getMinLocation(attributeNamesA, shaderLayoutMap);
|
|
36
|
+
const minLocationB = getMinLocation(attributeNamesB, shaderLayoutMap);
|
|
21
37
|
|
|
22
38
|
return minLocationA - minLocationB;
|
|
23
39
|
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {ComputeShaderLayout, ShaderLayout} from '@luma.gl/core';
|
|
6
|
+
import type {ShaderModule} from '@luma.gl/shadertools';
|
|
7
|
+
|
|
8
|
+
type AnyShaderLayout = ShaderLayout | ComputeShaderLayout;
|
|
9
|
+
|
|
10
|
+
export function mergeShaderModuleBindingsIntoLayout<TShaderLayout extends AnyShaderLayout>(
|
|
11
|
+
shaderLayout: TShaderLayout | null | undefined,
|
|
12
|
+
modules: ShaderModule[]
|
|
13
|
+
): TShaderLayout | null | undefined {
|
|
14
|
+
if (!shaderLayout || !modules.some(module => module.bindingLayout?.length)) {
|
|
15
|
+
return shaderLayout;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const mergedLayout = {
|
|
19
|
+
...shaderLayout,
|
|
20
|
+
bindings: shaderLayout.bindings.map(binding => ({...binding}))
|
|
21
|
+
} as TShaderLayout;
|
|
22
|
+
|
|
23
|
+
if ('attributes' in (shaderLayout || {})) {
|
|
24
|
+
(mergedLayout as ShaderLayout).attributes = (shaderLayout as ShaderLayout)?.attributes || [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (const module of modules) {
|
|
28
|
+
for (const bindingLayout of module.bindingLayout || []) {
|
|
29
|
+
for (const relatedBindingName of getRelatedBindingNames(bindingLayout.name)) {
|
|
30
|
+
const binding = mergedLayout.bindings.find(
|
|
31
|
+
candidate => candidate.name === relatedBindingName
|
|
32
|
+
);
|
|
33
|
+
if (binding?.group === 0) {
|
|
34
|
+
binding.group = bindingLayout.group;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return mergedLayout;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function shaderModuleHasUniforms(module: ShaderModule): boolean {
|
|
44
|
+
return Boolean(module.uniformTypes && !isObjectEmpty(module.uniformTypes));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Returns binding-name aliases that should share the module-declared bind group. */
|
|
48
|
+
function getRelatedBindingNames(bindingName: string): string[] {
|
|
49
|
+
const bindingNames = new Set<string>([bindingName, `${bindingName}Uniforms`]);
|
|
50
|
+
|
|
51
|
+
if (!bindingName.endsWith('Uniforms')) {
|
|
52
|
+
bindingNames.add(`${bindingName}Sampler`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return [...bindingNames];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isObjectEmpty(obj: object): boolean {
|
|
59
|
+
// @ts-ignore key is intentionally unused
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
|
+
for (const key in obj) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|