@luma.gl/engine 9.0.0-alpha.31 → 9.0.0-alpha.32
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/dist.dev.js +539 -286
- package/dist/geometries/truncated-cone-geometry.d.ts +0 -2
- package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +0 -11
- package/dist/geometries/truncated-cone-geometry.js.map +1 -1
- package/dist/geometry/geometry.d.ts +6 -7
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js.map +1 -1
- package/dist/geometry/gpu-geometry.d.ts +45 -0
- package/dist/geometry/gpu-geometry.d.ts.map +1 -0
- package/dist/geometry/gpu-geometry.js +123 -0
- package/dist/geometry/gpu-geometry.js.map +1 -0
- package/dist/geometry/gpu-table.d.ts +1 -0
- package/dist/geometry/gpu-table.d.ts.map +1 -0
- package/dist/geometry/gpu-table.js +2 -0
- package/dist/geometry/gpu-table.js.map +1 -0
- package/dist/index.cjs +311 -211
- package/dist/lib/pipeline-factory.d.ts +11 -44
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +28 -119
- package/dist/lib/pipeline-factory.js.map +1 -1
- package/dist/model/model-shaders.d.ts +35 -0
- package/dist/model/model-shaders.d.ts.map +1 -0
- package/dist/model/model-shaders.js +38 -0
- package/dist/model/model-shaders.js.map +1 -0
- package/dist/model/model-utils.d.ts +1 -1
- package/dist/model/model-utils.d.ts.map +1 -1
- package/dist/model/model-utils.js +1 -1
- package/dist/model/model-utils.js.map +1 -1
- package/dist/model/model.d.ts +107 -22
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +144 -93
- package/dist/model/model.js.map +1 -1
- package/dist.min.js +67 -67
- package/package.json +6 -6
- package/src/geometries/truncated-cone-geometry.ts +0 -10
- package/src/geometry/geometry.ts +7 -7
- package/src/geometry/gpu-geometry.ts +159 -0
- package/src/geometry/gpu-table.ts +41 -0
- package/src/lib/pipeline-factory.ts +43 -164
- package/src/model/model-shaders.ts +76 -0
- package/src/model/model-utils.ts +2 -2
- package/src/model/model.ts +268 -126
- package/dist/geometry/primitive-utils.d.ts +0 -1
- package/dist/geometry/primitive-utils.d.ts.map +0 -1
- package/dist/geometry/primitive-utils.js +0 -2
- package/dist/geometry/primitive-utils.js.map +0 -1
- package/src/geometry/primitive-utils.ts +0 -30
package/src/model/model.ts
CHANGED
|
@@ -1,138 +1,192 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
RenderPipelineProps,
|
|
7
|
-
RenderPass,
|
|
8
|
-
Binding,
|
|
9
|
-
PrimitiveTopology,
|
|
10
|
-
log
|
|
11
|
-
} from '@luma.gl/core';
|
|
12
|
-
import {RenderPipeline} from '@luma.gl/core';
|
|
3
|
+
import type {TypedArray, RenderPipelineProps, RenderPipelineParameters, BufferLayout} from '@luma.gl/core';
|
|
4
|
+
import type {Binding, UniformValue, PrimitiveTopology} from '@luma.gl/core';
|
|
5
|
+
import {Device, Buffer, RenderPipeline, RenderPass, log, uid, deepEqual} from '@luma.gl/core';
|
|
13
6
|
import type {ShaderModule} from '@luma.gl/shadertools';
|
|
7
|
+
import {ShaderAssembler} from '@luma.gl/shadertools';
|
|
14
8
|
import type {Geometry} from '../geometry/geometry';
|
|
15
|
-
import {
|
|
9
|
+
import {GPUGeometry, makeGPUGeometry} from '../geometry/gpu-geometry';
|
|
16
10
|
import {PipelineFactory} from '../lib/pipeline-factory';
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
/** @todo import type */
|
|
20
|
-
type UniformValue = unknown;
|
|
11
|
+
import {buildShaders} from './model-shaders';
|
|
21
12
|
|
|
22
13
|
export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
23
|
-
// Model also accepts a string
|
|
24
|
-
vs
|
|
25
|
-
fs
|
|
26
|
-
|
|
14
|
+
// Model also accepts a string shaders
|
|
15
|
+
vs: {glsl?: string; wgsl?: string} | string | null;
|
|
16
|
+
fs: {glsl?: string; wgsl?: string} | string | null;
|
|
17
|
+
/** shadertool shader modules (added to shader code) */
|
|
27
18
|
modules?: ShaderModule[];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
/** Shadertool module defines (configures shader code)*/
|
|
20
|
+
defines?: Record<string, string | number | boolean>;
|
|
21
|
+
// TODO - injections, hooks etc?
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/** pipeline factory to use to create render pipelines. Defaults to default factory for the device */
|
|
31
25
|
pipelineFactory?: PipelineFactory;
|
|
26
|
+
/** Shader assembler. Defaults to the ShaderAssembler.getShaderAssembler() */
|
|
27
|
+
shaderAssembler?: ShaderAssembler;
|
|
28
|
+
|
|
29
|
+
/** Geometry */
|
|
30
|
+
geometry?: GPUGeometry | Geometry | null;
|
|
31
|
+
/** Parameters that are built into the pipeline */
|
|
32
|
+
parameters?: RenderPipelineParameters;
|
|
33
|
+
/** shadertool modules */
|
|
34
|
+
moduleSettings?: Record<string, Record<string, any>>;
|
|
35
|
+
/** Vertex count */
|
|
32
36
|
vertexCount?: number;
|
|
37
|
+
/** instance count */
|
|
33
38
|
instanceCount?: number;
|
|
34
39
|
};
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
modules: [],
|
|
45
|
-
moduleSettings: {},
|
|
46
|
-
geometry: null,
|
|
47
|
-
pipelineFactory: undefined,
|
|
48
|
-
vertexCount: 0,
|
|
49
|
-
instanceCount: 0
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/** v9 API */
|
|
41
|
+
/**
|
|
42
|
+
* v9 Model API
|
|
43
|
+
* A model
|
|
44
|
+
* - automatically reuses pipelines (programs) when possible
|
|
45
|
+
* - automatically rebuilds pipelines if necessary to accommodate changed settings
|
|
46
|
+
* shadertools integration
|
|
47
|
+
* - accepts modules and performs shader transpilation
|
|
48
|
+
*/
|
|
53
49
|
export class Model {
|
|
50
|
+
static defaultProps: Required<ModelProps> = {
|
|
51
|
+
...RenderPipeline.defaultProps,
|
|
52
|
+
vs: null,
|
|
53
|
+
fs: null,
|
|
54
|
+
id: 'unnamed',
|
|
55
|
+
handle: undefined,
|
|
56
|
+
userData: {},
|
|
57
|
+
defines: {},
|
|
58
|
+
modules: [],
|
|
59
|
+
moduleSettings: {},
|
|
60
|
+
geometry: null,
|
|
61
|
+
|
|
62
|
+
pipelineFactory: undefined!,
|
|
63
|
+
shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(),
|
|
64
|
+
};
|
|
65
|
+
|
|
54
66
|
readonly device: Device;
|
|
55
67
|
readonly id: string;
|
|
56
68
|
readonly vs: string;
|
|
57
|
-
readonly fs: string
|
|
58
|
-
readonly topology: PrimitiveTopology;
|
|
69
|
+
readonly fs: string;
|
|
59
70
|
readonly pipelineFactory: PipelineFactory;
|
|
60
|
-
/** The underlying GPU "program". @note May be recreated if parameters change */
|
|
61
|
-
pipeline: RenderPipeline;
|
|
62
71
|
userData: {[key: string]: any} = {};
|
|
63
72
|
|
|
64
|
-
//
|
|
73
|
+
// Fixed properties (change can trigger pipeline rebuild)
|
|
74
|
+
|
|
75
|
+
/** The render pipeline GPU parameters, depth testing etc */
|
|
76
|
+
parameters: RenderPipelineParameters;
|
|
77
|
+
|
|
78
|
+
/** The primitive topology */
|
|
79
|
+
topology: PrimitiveTopology;
|
|
80
|
+
/** Buffer layout */
|
|
81
|
+
bufferLayout: BufferLayout[];
|
|
82
|
+
|
|
83
|
+
// Dynamic properties
|
|
65
84
|
|
|
66
85
|
/** Vertex count */
|
|
67
86
|
vertexCount: number;
|
|
68
87
|
/** instance count */
|
|
69
88
|
instanceCount: number = 0;
|
|
89
|
+
|
|
90
|
+
/** Index buffer */
|
|
91
|
+
indices: Buffer | null = null;
|
|
70
92
|
/** Buffer-valued attributes */
|
|
71
93
|
bufferAttributes: Record<string, Buffer> = {};
|
|
72
94
|
/** Constant-valued attributes */
|
|
73
95
|
constantAttributes: Record<string, TypedArray> = {};
|
|
74
96
|
/** Bindings (textures, samplers, uniform buffers) */
|
|
75
97
|
bindings: Record<string, Binding> = {};
|
|
76
|
-
/**
|
|
98
|
+
/** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
|
|
77
99
|
uniforms: Record<string, UniformValue> = {};
|
|
78
100
|
|
|
101
|
+
/** The underlying GPU "program". @note May be recreated if parameters change */
|
|
102
|
+
pipeline: RenderPipeline;
|
|
103
|
+
_pipelineNeedsUpdate: string | false = 'newly created';
|
|
79
104
|
private _getModuleUniforms: (props?: Record<string, Record<string, any>>) => Record<string, any>;
|
|
105
|
+
private props: Required<ModelProps>;
|
|
80
106
|
|
|
81
107
|
constructor(device: Device, props: ModelProps) {
|
|
82
|
-
props = {...
|
|
83
|
-
|
|
108
|
+
this.props = {...Model.defaultProps, ...props};
|
|
109
|
+
props = this.props;
|
|
110
|
+
this.id = props.id || uid('model');
|
|
84
111
|
this.device = device;
|
|
85
112
|
|
|
86
113
|
Object.assign(this.userData, props.userData);
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
115
|
+
const {vs, fs, getUniforms} = buildShaders(device, this.props);
|
|
116
|
+
this.vs = vs;
|
|
117
|
+
this.fs = fs;
|
|
118
|
+
this._getModuleUniforms = getUniforms;
|
|
119
|
+
|
|
120
|
+
this.vertexCount = this.props.vertexCount;
|
|
121
|
+
this.instanceCount = this.props.instanceCount;
|
|
96
122
|
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
123
|
+
this.topology = this.props.topology;
|
|
124
|
+
this.bufferLayout = this.props.bufferLayout;
|
|
125
|
+
this.parameters = this.props.parameters;
|
|
100
126
|
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
127
|
+
// Geometry, if provided, sets several attributes, indices, and also vertex count and topology
|
|
128
|
+
const gpuGeometry = props.geometry && makeGPUGeometry(device, props.geometry);
|
|
129
|
+
if (gpuGeometry) {
|
|
130
|
+
this.setGeometry(gpuGeometry);
|
|
104
131
|
}
|
|
105
132
|
|
|
106
133
|
this.pipelineFactory =
|
|
107
134
|
props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
108
|
-
const {pipeline, getUniforms} = this.pipelineFactory.createRenderPipeline({
|
|
109
|
-
...props,
|
|
110
|
-
vs: this.vs,
|
|
111
|
-
fs: this.fs,
|
|
112
|
-
topology: this.topology,
|
|
113
|
-
defines: props.defines,
|
|
114
|
-
parameters: props.parameters,
|
|
115
|
-
shaderLayout: props.shaderLayout
|
|
116
|
-
});
|
|
117
135
|
|
|
118
|
-
|
|
119
|
-
|
|
136
|
+
// Create the pipeline
|
|
137
|
+
// @note order is important
|
|
138
|
+
this.pipeline = this._updatePipeline();
|
|
139
|
+
|
|
140
|
+
// Now we can apply geometry attributes
|
|
120
141
|
|
|
121
|
-
|
|
122
|
-
|
|
142
|
+
// Apply any dynamic settings that will not trigger pipeline change
|
|
143
|
+
if (props.vertexCount) {
|
|
144
|
+
this.setVertexCount(props.vertexCount);
|
|
145
|
+
}
|
|
146
|
+
if (props.instanceCount) {
|
|
147
|
+
this.setInstanceCount(props.instanceCount);
|
|
148
|
+
}
|
|
149
|
+
if (props.indices) {
|
|
150
|
+
this.setIndexBuffer(props.indices);
|
|
151
|
+
}
|
|
152
|
+
if (props.attributes) {
|
|
153
|
+
this.setAttributes(props.attributes);
|
|
154
|
+
}
|
|
155
|
+
if (props.bindings) {
|
|
156
|
+
this.setBindings(props.bindings);
|
|
157
|
+
}
|
|
158
|
+
if (props.uniforms) {
|
|
159
|
+
this.setUniforms(props.uniforms);
|
|
160
|
+
}
|
|
161
|
+
if (props.moduleSettings) {
|
|
162
|
+
this.updateModuleSettings(props.moduleSettings);
|
|
123
163
|
}
|
|
124
164
|
|
|
125
165
|
this.setUniforms(this._getModuleUniforms()); // Get all default module uniforms
|
|
126
166
|
|
|
127
|
-
//
|
|
128
|
-
|
|
167
|
+
// Catch any access to non-standard props
|
|
168
|
+
Object.seal(this);
|
|
129
169
|
}
|
|
130
170
|
|
|
131
171
|
destroy(): void {
|
|
132
172
|
this.pipelineFactory.release(this.pipeline);
|
|
133
173
|
}
|
|
134
174
|
|
|
175
|
+
// Draw call
|
|
176
|
+
|
|
135
177
|
draw(renderPass: RenderPass): void {
|
|
178
|
+
// Check if the pipeline is invalidated
|
|
179
|
+
// TODO - this is likely the worst place to do this from performance perspective. Perhaps add a predraw()?
|
|
180
|
+
this.pipeline = this._updatePipeline();
|
|
181
|
+
|
|
182
|
+
// Set pipeline state, we may be sharing a pipeline so we need to set all state on every draw
|
|
183
|
+
// Any caching needs to be done inside the pipeline functions
|
|
184
|
+
this.pipeline.setIndexBuffer(this.indices);
|
|
185
|
+
this.pipeline.setAttributes(this.bufferAttributes);
|
|
186
|
+
this.pipeline.setConstantAttributes(this.constantAttributes);
|
|
187
|
+
this.pipeline.setBindings(this.bindings);
|
|
188
|
+
this.pipeline.setUniforms(this.uniforms);
|
|
189
|
+
|
|
136
190
|
this.pipeline.draw({
|
|
137
191
|
renderPass,
|
|
138
192
|
vertexCount: this.vertexCount,
|
|
@@ -140,91 +194,179 @@ export class Model {
|
|
|
140
194
|
});
|
|
141
195
|
}
|
|
142
196
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
197
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Updates the optional geometry
|
|
201
|
+
* @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
202
|
+
*/
|
|
203
|
+
setGeometry(geometry: GPUGeometry): void {
|
|
204
|
+
this.setTopology(geometry.topology || 'triangle-list');
|
|
205
|
+
this.bufferLayout = mergeBufferLayouts(this.bufferLayout, geometry.bufferLayout);
|
|
206
|
+
|
|
207
|
+
// TODO - delete previous geometry?
|
|
208
|
+
this.vertexCount = geometry.vertexCount;
|
|
209
|
+
this.setAttributes(geometry.attributes);
|
|
210
|
+
this.setIndexBuffer(geometry.indices);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Updates the primitive topology ('triangle-list', 'triangle-strip' etc).
|
|
215
|
+
* @note Triggers a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
216
|
+
*/
|
|
217
|
+
setTopology(topology: PrimitiveTopology): void {
|
|
218
|
+
if (topology !== this.topology) {
|
|
219
|
+
this.topology = topology;
|
|
220
|
+
// On WebGPU we need to rebuild the pipeline
|
|
221
|
+
if (this.device.info.type === 'webgpu') {
|
|
222
|
+
this._setPipelineNeedsUpdate('topology');
|
|
223
|
+
}
|
|
152
224
|
}
|
|
153
|
-
|
|
154
|
-
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Updates the buffer layout.
|
|
229
|
+
* @note Triggers a pipeline rebuild / pipeline cache fetch on WebGPU
|
|
230
|
+
*/
|
|
231
|
+
setBufferLayout(bufferLayout: BufferLayout[]): void {
|
|
232
|
+
if (bufferLayout !== this.bufferLayout) {
|
|
233
|
+
this.bufferLayout = bufferLayout;
|
|
234
|
+
// On WebGPU we need to rebuild the pipeline
|
|
235
|
+
if (this.device.info.type === 'webgpu') {
|
|
236
|
+
this._setPipelineNeedsUpdate('bufferLayout');
|
|
237
|
+
}
|
|
155
238
|
}
|
|
156
|
-
|
|
157
|
-
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Set GPU parameters.
|
|
243
|
+
* @note Can trigger a pipeline rebuild / pipeline cache fetch.
|
|
244
|
+
* @param parameters
|
|
245
|
+
*/
|
|
246
|
+
setParameters(parameters: RenderPipelineParameters) {
|
|
247
|
+
if (!deepEqual(parameters, this.parameters, 2)) {
|
|
248
|
+
this.parameters = parameters;
|
|
249
|
+
// On WebGPU we need to rebuild the pipeline
|
|
250
|
+
if (this.device.info.type === 'webgpu') {
|
|
251
|
+
this._setPipelineNeedsUpdate('parameters');
|
|
252
|
+
}
|
|
158
253
|
}
|
|
159
254
|
}
|
|
255
|
+
|
|
256
|
+
// Update dynamic fields
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Updates the vertex count (used in draw calls)
|
|
260
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
261
|
+
*/
|
|
262
|
+
setVertexCount(vertexCount: number): void {
|
|
263
|
+
this.vertexCount = vertexCount;
|
|
264
|
+
}
|
|
160
265
|
|
|
161
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Updates the instance count (used in draw calls)
|
|
268
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
269
|
+
*/
|
|
270
|
+
setInstanceCount(instanceCount: number): void {
|
|
271
|
+
this.instanceCount = instanceCount;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
276
|
+
*/
|
|
277
|
+
setShaderModuleProps(props: Record<string, any>): void {
|
|
162
278
|
const uniforms = this._getModuleUniforms(props);
|
|
163
|
-
this.
|
|
279
|
+
Object.assign(this.uniforms, uniforms);
|
|
164
280
|
}
|
|
165
281
|
|
|
282
|
+
/**
|
|
283
|
+
* @deprecated Updates shader module settings (which results in uniforms being set)
|
|
284
|
+
*/
|
|
285
|
+
updateModuleSettings(props: Record<string, any>): void {
|
|
286
|
+
this.setShaderModuleProps(props);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Sets the index buffer
|
|
291
|
+
* @todo - how to unset it if we change geometry?
|
|
292
|
+
*/
|
|
166
293
|
setIndexBuffer(indices: Buffer | null): void {
|
|
167
|
-
this.
|
|
168
|
-
// this._indices = indices;
|
|
294
|
+
this.indices = indices;
|
|
169
295
|
}
|
|
170
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Sets attributes (buffers)
|
|
299
|
+
* @note Overrides any attributes previously set with the same name
|
|
300
|
+
*/
|
|
171
301
|
setAttributes(bufferAttributes: Record<string, Buffer>): void {
|
|
172
302
|
if (bufferAttributes.indices) {
|
|
173
303
|
log.warn(`Model:${this.id} setAttributes() - indices should be set using setIndexBuffer()`);
|
|
174
304
|
}
|
|
175
305
|
|
|
176
|
-
this.pipeline.setAttributes(bufferAttributes);
|
|
177
306
|
Object.assign(this.bufferAttributes, bufferAttributes);
|
|
178
307
|
}
|
|
179
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Sets constant attributes
|
|
311
|
+
* @note Overrides any attributes previously set with the same name
|
|
312
|
+
* @param constantAttributes
|
|
313
|
+
*/
|
|
180
314
|
setConstantAttributes(constantAttributes: Record<string, TypedArray>): void {
|
|
181
315
|
// TODO - this doesn't work under WebGPU, we'll need to create buffers or inject uniforms
|
|
182
|
-
this.pipeline.setConstantAttributes(constantAttributes);
|
|
183
316
|
Object.assign(this.constantAttributes, constantAttributes);
|
|
184
317
|
}
|
|
185
318
|
|
|
186
|
-
/**
|
|
319
|
+
/**
|
|
320
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
321
|
+
*/
|
|
187
322
|
setBindings(bindings: Record<string, Binding>): void {
|
|
188
|
-
this.pipeline.setBindings(bindings);
|
|
189
323
|
Object.assign(this.bindings, bindings);
|
|
190
324
|
}
|
|
191
325
|
|
|
192
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Sets individual uniforms
|
|
328
|
+
* @deprecated WebGL only, use uniform buffers for portability
|
|
329
|
+
* @param uniforms
|
|
330
|
+
* @returns self for chaining
|
|
331
|
+
*/
|
|
332
|
+
setUniforms(uniforms: Record<string, UniformValue>): void {
|
|
193
333
|
this.pipeline.setUniforms(uniforms);
|
|
194
334
|
Object.assign(this.uniforms, uniforms);
|
|
195
335
|
}
|
|
196
336
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const geometryBuffers = getAttributeBuffersFromGeometry(this.device, geometry);
|
|
201
|
-
this.setAttributes(geometryBuffers);
|
|
337
|
+
_setPipelineNeedsUpdate(reason: string): void {
|
|
338
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
339
|
+
}
|
|
202
340
|
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
this.
|
|
341
|
+
_updatePipeline(): RenderPipeline {
|
|
342
|
+
if (this._pipelineNeedsUpdate) {
|
|
343
|
+
log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
344
|
+
this._pipelineNeedsUpdate = false;
|
|
345
|
+
this.pipeline = this.device.createRenderPipeline({
|
|
346
|
+
...this.props,
|
|
347
|
+
bufferLayout: this.bufferLayout,
|
|
348
|
+
topology: this.topology,
|
|
349
|
+
parameters: this.parameters,
|
|
350
|
+
vs: this.device.createShader({stage: 'vertex', source: this.vs}),
|
|
351
|
+
fs: this.fs ? this.device.createShader({stage: 'fragment', source: this.fs}) : null
|
|
352
|
+
});
|
|
206
353
|
}
|
|
354
|
+
return this.pipeline;
|
|
207
355
|
}
|
|
208
356
|
}
|
|
209
357
|
|
|
210
|
-
/**
|
|
211
|
-
function
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
throw new Error('WebGPU does not support GLSL shaders');
|
|
223
|
-
|
|
224
|
-
default:
|
|
225
|
-
if (shader?.glsl) {
|
|
226
|
-
return shader.glsl;
|
|
227
|
-
}
|
|
228
|
-
throw new Error('WebGL does not support WGSL shaders');
|
|
358
|
+
/** TODO - move to core, document add tests */
|
|
359
|
+
function mergeBufferLayouts(layouts1: BufferLayout[], layouts2: BufferLayout[]): BufferLayout[] {
|
|
360
|
+
const layouts = [...layouts1];
|
|
361
|
+
for (const attribute of layouts2) {
|
|
362
|
+
const index = layouts.findIndex(
|
|
363
|
+
(attribute2) => attribute2.name === attribute.name
|
|
364
|
+
);
|
|
365
|
+
if (index < 0) {
|
|
366
|
+
layouts.push(attribute);
|
|
367
|
+
} else {
|
|
368
|
+
layouts[index] = attribute;
|
|
369
|
+
}
|
|
229
370
|
}
|
|
230
|
-
|
|
371
|
+
return layouts;
|
|
372
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=primitive-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"primitive-utils.d.ts","sourceRoot":"","sources":["../../src/geometry/primitive-utils.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"primitive-utils.js","names":[],"sources":["../../src/geometry/primitive-utils.ts"],"sourcesContent":["/*\nimport type {GeometryTable} from './geometry-table';\n\nexport function unpackIndexedGeometry(geometry: GeometryTable): GeometryTable {\n const {indices, attributes} = geometry;\n if (!indices) {\n return geometry;\n }\n\n const vertexCount = indices.length;\n const unpackedAttributes = {};\n\n for (const [name, values] of Object.entries(attributes)) {\n const size = {POSITION: 3, NORMAL: 3, TEX_COORD0: 2}[name];\n const unpackedValues = new values.constructor(length * size);\n for (let x = 0; x < vertexCount; ++x) {\n const index = indices[x];\n for (let i = 0; i < size; i++) {\n unpackedValues[x * size + i] = values[index * size + i];\n }\n }\n unpackedAttributes[name] = unpackedValues;\n }\n\n return {\n length,\n attributes: unpackedAttributes\n };\n}\n*/"],"mappings":""}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
import type {GeometryTable} from './geometry-table';
|
|
3
|
-
|
|
4
|
-
export function unpackIndexedGeometry(geometry: GeometryTable): GeometryTable {
|
|
5
|
-
const {indices, attributes} = geometry;
|
|
6
|
-
if (!indices) {
|
|
7
|
-
return geometry;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const vertexCount = indices.length;
|
|
11
|
-
const unpackedAttributes = {};
|
|
12
|
-
|
|
13
|
-
for (const [name, values] of Object.entries(attributes)) {
|
|
14
|
-
const size = {POSITION: 3, NORMAL: 3, TEX_COORD0: 2}[name];
|
|
15
|
-
const unpackedValues = new values.constructor(length * size);
|
|
16
|
-
for (let x = 0; x < vertexCount; ++x) {
|
|
17
|
-
const index = indices[x];
|
|
18
|
-
for (let i = 0; i < size; i++) {
|
|
19
|
-
unpackedValues[x * size + i] = values[index * size + i];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
unpackedAttributes[name] = unpackedValues;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
length,
|
|
27
|
-
attributes: unpackedAttributes
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
*/
|