@luma.gl/engine 8.6.0-alpha.5 → 9.0.0-alpha.3

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.
Files changed (129) hide show
  1. package/dist/animation/key-frames.d.ts +1 -0
  2. package/dist/animation/key-frames.d.ts.map +1 -1
  3. package/dist/animation/key-frames.js.map +1 -1
  4. package/dist/animation/timeline.d.ts +1 -1
  5. package/dist/animation/timeline.d.ts.map +1 -1
  6. package/dist/animation/timeline.js.map +1 -1
  7. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  8. package/dist/geometries/cone-geometry.js +1 -1
  9. package/dist/geometries/cone-geometry.js.map +1 -1
  10. package/dist/geometries/cube-geometry.d.ts +4 -0
  11. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  12. package/dist/geometries/cube-geometry.js +30 -7
  13. package/dist/geometries/cube-geometry.js.map +1 -1
  14. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  15. package/dist/geometries/cylinder-geometry.js +1 -1
  16. package/dist/geometries/cylinder-geometry.js.map +1 -1
  17. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  18. package/dist/geometries/ico-sphere-geometry.js +1 -1
  19. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  20. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  21. package/dist/geometries/plane-geometry.js +1 -1
  22. package/dist/geometries/plane-geometry.js.map +1 -1
  23. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  24. package/dist/geometries/sphere-geometry.js +1 -1
  25. package/dist/geometries/sphere-geometry.js.map +1 -1
  26. package/dist/geometries/truncated-cone-geometry.d.ts +15 -3
  27. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  28. package/dist/geometries/truncated-cone-geometry.js +29 -15
  29. package/dist/geometries/truncated-cone-geometry.js.map +1 -1
  30. package/dist/geometry/geometry-table.d.ts +15 -0
  31. package/dist/geometry/geometry-table.d.ts.map +1 -0
  32. package/dist/geometry/geometry-table.js +2 -0
  33. package/dist/{transform/transform-types.js.map → geometry/geometry-table.js.map} +1 -1
  34. package/dist/geometry/geometry-utils.js.map +1 -1
  35. package/dist/geometry/geometry.d.ts +34 -7
  36. package/dist/geometry/geometry.d.ts.map +1 -1
  37. package/dist/geometry/geometry.js +33 -11
  38. package/dist/geometry/geometry.js.map +1 -1
  39. package/dist/geometry/primitive-utils.d.ts +1 -0
  40. package/dist/geometry/primitive-utils.d.ts.map +1 -0
  41. package/dist/geometry/primitive-utils.js +2 -0
  42. package/dist/geometry/primitive-utils.js.map +1 -0
  43. package/dist/index.d.ts +3 -5
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -4
  46. package/dist/index.js.map +1 -1
  47. package/dist/lib/animation-loop.d.ts +14 -73
  48. package/dist/lib/animation-loop.d.ts.map +1 -1
  49. package/dist/lib/animation-loop.js +39 -160
  50. package/dist/lib/animation-loop.js.map +1 -1
  51. package/dist/lib/animation-props.d.ts +24 -0
  52. package/dist/lib/animation-props.d.ts.map +1 -0
  53. package/dist/lib/animation-props.js +2 -0
  54. package/dist/lib/animation-props.js.map +1 -0
  55. package/dist/lib/clip-space.d.ts +1 -0
  56. package/dist/lib/clip-space.d.ts.map +1 -0
  57. package/dist/lib/clip-space.js +2 -0
  58. package/dist/lib/clip-space.js.map +1 -0
  59. package/dist/lib/model-utils.d.ts +4 -3
  60. package/dist/lib/model-utils.d.ts.map +1 -1
  61. package/dist/lib/model-utils.js +24 -70
  62. package/dist/lib/model-utils.js.map +1 -1
  63. package/dist/lib/model.d.ts +34 -104
  64. package/dist/lib/model.d.ts.map +1 -1
  65. package/dist/lib/model.js +108 -505
  66. package/dist/lib/model.js.map +1 -1
  67. package/dist/lib/pipeline-factory.d.ts +55 -0
  68. package/dist/lib/pipeline-factory.d.ts.map +1 -0
  69. package/dist/lib/pipeline-factory.js +191 -0
  70. package/dist/lib/pipeline-factory.js.map +1 -0
  71. package/dist/lib/render-loop.d.ts +4 -17
  72. package/dist/lib/render-loop.d.ts.map +1 -1
  73. package/dist/lib/render-loop.js +14 -21
  74. package/dist/lib/render-loop.js.map +1 -1
  75. package/package.json +5 -5
  76. package/src/animation/key-frames.ts +1 -0
  77. package/src/animation/timeline.ts +1 -1
  78. package/src/geometries/cone-geometry.ts +1 -1
  79. package/src/geometries/cube-geometry.ts +159 -8
  80. package/src/geometries/cylinder-geometry.ts +1 -1
  81. package/src/geometries/ico-sphere-geometry.ts +1 -1
  82. package/src/geometries/plane-geometry.ts +1 -1
  83. package/src/geometries/sphere-geometry.ts +2 -2
  84. package/src/geometries/truncated-cone-geometry.ts +30 -12
  85. package/src/geometry/geometry-table.ts +16 -0
  86. package/src/geometry/geometry-utils.ts +1 -1
  87. package/src/geometry/geometry.ts +58 -13
  88. package/src/geometry/primitive-utils.ts +30 -0
  89. package/src/index.ts +7 -8
  90. package/src/lib/animation-loop.ts +85 -274
  91. package/src/lib/animation-props.ts +31 -0
  92. package/src/{utils → lib}/clip-space.ts +5 -2
  93. package/src/lib/model-utils.ts +60 -32
  94. package/src/lib/model.ts +126 -642
  95. package/src/lib/pipeline-factory.ts +225 -0
  96. package/src/lib/render-loop.ts +21 -19
  97. package/dist/lib/program-manager.d.ts +0 -39
  98. package/dist/lib/program-manager.d.ts.map +0 -1
  99. package/dist/lib/program-manager.js +0 -175
  100. package/dist/lib/program-manager.js.map +0 -1
  101. package/dist/transform/buffer-transform.d.ts +0 -36
  102. package/dist/transform/buffer-transform.d.ts.map +0 -1
  103. package/dist/transform/buffer-transform.js +0 -255
  104. package/dist/transform/buffer-transform.js.map +0 -1
  105. package/dist/transform/texture-transform.d.ts +0 -57
  106. package/dist/transform/texture-transform.d.ts.map +0 -1
  107. package/dist/transform/texture-transform.js +0 -412
  108. package/dist/transform/texture-transform.js.map +0 -1
  109. package/dist/transform/transform-shader-utils.d.ts +0 -26
  110. package/dist/transform/transform-shader-utils.d.ts.map +0 -1
  111. package/dist/transform/transform-shader-utils.js +0 -149
  112. package/dist/transform/transform-shader-utils.js.map +0 -1
  113. package/dist/transform/transform-types.d.ts +0 -44
  114. package/dist/transform/transform-types.d.ts.map +0 -1
  115. package/dist/transform/transform-types.js +0 -2
  116. package/dist/transform/transform.d.ts +0 -47
  117. package/dist/transform/transform.d.ts.map +0 -1
  118. package/dist/transform/transform.js +0 -198
  119. package/dist/transform/transform.js.map +0 -1
  120. package/dist/utils/clip-space.d.ts +0 -5
  121. package/dist/utils/clip-space.d.ts.map +0 -1
  122. package/dist/utils/clip-space.js +0 -34
  123. package/dist/utils/clip-space.js.map +0 -1
  124. package/src/lib/program-manager.ts +0 -187
  125. package/src/transform/buffer-transform.ts +0 -214
  126. package/src/transform/texture-transform.ts +0 -344
  127. package/src/transform/transform-shader-utils.ts +0 -169
  128. package/src/transform/transform-types.ts +0 -42
  129. package/src/transform/transform.ts +0 -189
package/src/lib/model.ts CHANGED
@@ -1,695 +1,179 @@
1
- // luma.gl, MIT license
2
- import {Device} from '@luma.gl/api';
3
- import GL from '@luma.gl/constants';
4
- import type {ProgramProps} from '@luma.gl/webgl';
5
- import {
6
- WebGLDevice,
7
- Program,
8
- VertexArray,
9
- clear,
10
- TransformFeedback,
11
- Buffer,
12
- log,
13
- isObjectEmpty,
14
- uid,
15
- assert
16
- } from '@luma.gl/webgl';
17
- import {
18
- getDebugTableForUniforms,
19
- getDebugTableForVertexArray,
20
- getDebugTableForProgramConfiguration
21
- } from '@luma.gl/webgl';
22
- import ProgramManager from './program-manager';
23
- import {getBuffersFromGeometry} from './model-utils';
24
-
25
- const LOG_DRAW_PRIORITY = 2;
26
- const LOG_DRAW_TIMEOUT = 10000;
27
-
28
- const ERR_MODEL_PARAMS = 'Model needs drawMode and vertexCount';
29
-
30
- const NOOP = () => {};
31
- const DRAW_PARAMS = {};
32
-
33
- export type ModelProps = ProgramProps & {
34
- id?: string;
35
-
36
- // program props
37
- // vs,
38
- // fs,
39
- varyings?: string[];
40
- bufferMode?;
41
-
42
- program?: Program;
43
- modules?: any[];
44
- defines?: Record<string, number | boolean>;
45
- inject?: Record<string, any>;
46
- transpileToGLSL100?: boolean;
47
-
48
- moduleSettings?: object; // UniformsOptions
49
- attributes?: object;
50
- uniforms?: object; // Uniforms
51
- geometry?: object; // Geometry
52
- vertexCount?: number
53
- drawMode?: number
54
- isInstanced?: boolean
55
- instanceCount?: number
56
- programManager?: ProgramManager
57
- onBeforeRender?: () => void
58
- onAfterRender?: () => void
59
- _feedbackBuffers?: object; // FeedbackBuffers
60
-
61
- // Deprecated?
62
- isIndexed?: boolean;
63
- indexType?;
64
- indexOffset?: number;
65
- vertexArrayInstanced?: boolean;
66
-
67
- /** @deprecated Use isInstanced */
68
- instanced?: boolean
1
+ import type {Device, Buffer, RenderPipelineProps, RenderPass, Binding} from '@luma.gl/api';
2
+ import {RenderPipeline, Shader, cast} from '@luma.gl/api';
3
+ import type { ShaderModule } from '@luma.gl/shadertools';
4
+ import type Geometry from '../geometry/geometry';
5
+ import {getAttributeBuffersFromGeometry, getIndexBufferFromGeometry} from './model-utils';
6
+ import PipelineFactory from './pipeline-factory';
7
+
8
+ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
9
+ // Model also accepts a string
10
+ vs?: {glsl?: string; wgsl?: string} | string;
11
+ fs?: {glsl?: string; wgsl?: string} | string;
12
+ modules?: ShaderModule[];
13
+ moduleSettings?: Record<string, Record<string, any>>;
14
+ geometry?: Geometry;
69
15
  };
70
16
 
71
-
72
- export type ModelDrawOptions = {
73
- moduleSettings?;
74
- framebuffer?;
75
- uniforms?;
76
- attributes?;
77
- transformFeedback?;
78
- parameters?;
79
- vertexArray?;
17
+ const DEFAULT_MODEL_PROPS: Required<ModelProps> = {
18
+ ...RenderPipeline._DEFAULT_PROPS,
19
+ vs: undefined,
20
+ fs: undefined,
21
+ id: 'unnamed',
22
+ handle: undefined,
23
+ userData: {},
24
+ modules: [],
25
+ moduleSettings: {},
26
+ geometry: undefined
80
27
  };
81
28
 
82
- /* TODO - from autogenerated declarations, copy types and delete
83
- interface ModelProps extends ProgramProps {
84
- id?: string
85
- moduleSettings?: UniformsOptions
86
- uniforms?: Uniforms
87
- geometry?: Geometry
88
- vertexCount?: number
89
- drawMode?: number
90
- programManager?: ProgramManager
91
- onBeforeRender?: () => void
92
- onAfterRender?: () => void
93
- _feedbackBuffers?: FeedbackBuffers
94
- }
95
-
96
- interface DrawOpts {
97
- moduleSettings?: UniformsOptions
98
- framebuffer: Framebuffer
99
- uniforms?: Uniforms
100
- attributes?: Attributes
101
- parameters?: Parameters
102
- transformFeedback?: TransformFeedback
103
- vertexArray?: VertexArray
104
- }
105
-
106
- interface ClearOpts {
107
- framebuffer?: Framebuffer
108
- color?: boolean
109
- depth?: boolean
110
- stencil?: boolean
111
- }
112
-
113
- interface TransformOpts extends DrawOpts {
114
- discard: boolean
115
- feedbackBuffers: FeedbackBuffers
116
- unbindModels: Array<Model>
117
- parameters: Parameters
118
- }
119
- */
120
-
29
+ /** v9 API */
121
30
  export default class Model {
122
31
  readonly device: Device;
123
- readonly gl: WebGLRenderingContext;
124
-
32
+ readonly pipeline: RenderPipeline;
125
33
  readonly id: string;
126
- readonly animated: boolean = false;
127
- programManager: ProgramManager;
128
- vertexCount: number;
129
-
130
- lastLogTime: number = 0; // TODO - move to probe.gl
131
-
132
- props: ModelProps;
133
- userData: Record<string, any> = {};
134
- needsRedraw: boolean = true;
135
- attributes: Record<string, any> = {};
136
- _attributes: Record<string, any> = {};
137
- uniforms: Record<string, any> = {};
138
-
139
- drawMode;
140
- instanceCount: number;
141
- pickable: boolean = true;
142
-
143
- programProps: ProgramProps & {program?: Program; modules; inject; defines; varyings; bufferMode; transpileToGLSL100;};
144
- vertexArray: VertexArray;
145
- program: Program;
146
- transformFeedback: TransformFeedback | undefined;
147
- _programDirty = true;
148
- _programManagerState;
149
- _managedProgram;
34
+ readonly vs: string;
35
+ readonly fs: string | undefined;
36
+ readonly topology: string;
37
+ readonly vertexCount;
38
+ props: Required<ModelProps>;
150
39
 
151
- // Track buffers created by setGeometry
152
- geometryBuffers = {};
153
- // geometry might have set drawMode and vertexCount
154
- isInstanced: boolean;
155
- // TODO - just to unbreak deck.gl 7.0-beta, remove as soon as updated
156
- geometry = {};
40
+ private _getModuleUniforms: (props?: Record<string, Record<string, any>>) => Record<string, any>;
157
41
 
158
- constructor(device: Device, props?: ModelProps);
159
- /* @deprecated */
160
- constructor(gl: WebGLRenderingContext, props?: ModelProps);
161
- constructor(device, props: ModelProps = {}) {
162
- // Deduce a helpful id
163
- const {id = uid('model')} = props;
164
- this.id = id;
165
- const webglDevice = WebGLDevice.attach(device);
166
- this.device = webglDevice;
167
- this.gl = webglDevice.gl;
168
- this.id = props.id || uid('Model');
169
- this.initialize(props);
170
- }
171
-
172
- initialize(props: ModelProps) {
173
- this.props = {};
174
-
175
- this.programManager = props.programManager || ProgramManager.getDefaultProgramManager(this.device);
176
- this._programManagerState = -1;
177
- this._managedProgram = false;
178
-
179
- const {
180
- program = null,
181
- vs,
182
- fs,
183
- modules,
184
- defines,
185
- inject,
186
- varyings,
187
- bufferMode,
188
- transpileToGLSL100
189
- } = props;
190
-
191
- this.programProps = {
192
- program,
193
- modules,
194
- vs,
195
- fs,
196
- defines,
197
- inject,
198
- varyings,
199
- bufferMode,
200
- transpileToGLSL100
201
- };
202
- this.program = null;
203
- this.vertexArray = null;
204
- this._programDirty = true;
205
-
206
- // Initialize state
207
- this.userData = {};
208
- this.needsRedraw = true;
209
-
210
- // Attributes and buffers
211
- // Model manages auto Buffer creation from typed arrays
212
- this._attributes = {}; // All attributes
213
- this.attributes = {}; // User defined attributes
214
-
215
- // Model manages uniform animation
216
- this.uniforms = {};
217
-
218
- // picking options
219
- this.pickable = true;
220
-
221
- this._checkProgram();
222
-
223
- this.setUniforms(
224
- Object.assign(
225
- {},
226
- this.getModuleUniforms(props.moduleSettings) // Get unforms for supplied parameters
227
- )
228
- );
229
-
230
- this.drawMode = props.drawMode !== undefined ? props.drawMode : GL.TRIANGLES;
231
- this.vertexCount = props.vertexCount || 0;
232
-
233
- // Track buffers created by setGeometry
234
- this.geometryBuffers = {};
235
-
236
- // geometry might have set drawMode and vertexCount
237
- this.isInstanced = props.isInstanced || props.instanced || props.instanceCount > 0;
238
-
239
- this._setModelProps(props);
240
-
241
- // TODO - just to unbreak deck.gl 7.0-beta, remove as soon as updated
242
- this.geometry = {};
243
-
244
- // assert(program || program instanceof Program);
245
- assert(this.drawMode !== undefined && Number.isFinite(this.vertexCount), ERR_MODEL_PARAMS);
246
- }
247
-
248
- setProps(props) {
249
- this._setModelProps(props);
250
- }
251
-
252
- destroy(): void {
253
- // delete all attributes created by this model
254
- // TODO - should buffer deletes be handled by vertex array?
255
- for (const key in this._attributes) {
256
- if (this._attributes[key] !== this.attributes[key]) {
257
- this._attributes[key].delete();
258
- }
259
- }
42
+ constructor(device: Device, props: ModelProps) {
43
+ this.props = {...DEFAULT_MODEL_PROPS, ...props};
44
+ props = this.props;
45
+ this.id = props.id;
46
+ this.device = device;
260
47
 
261
- if (this._managedProgram) {
262
- this.programManager.release(this.program);
263
- this._managedProgram = false;
48
+ // Create the pipeline
49
+ this.vs = getShaderSource(this.device, props.vs);
50
+ if (props.fs) {
51
+ this.fs = getShaderSource(this.device, props.fs);
264
52
  }
265
53
 
266
- this.vertexArray.delete();
267
-
268
- this._deleteGeometryBuffers();
269
- }
270
-
271
- /** @deprecated Use .destroy() */
272
- delete(): void {
273
- this.destroy();
274
- }
275
-
276
- // GETTERS
54
+ this.vertexCount = this.props.vertexCount;
55
+ this.topology = this.props.topology;
277
56
 
278
- getDrawMode() {
279
- return this.drawMode;
280
- }
281
-
282
- getVertexCount(): number {
283
- return this.vertexCount;
284
- }
285
-
286
- getInstanceCount(): number {
287
- return this.instanceCount;
288
- }
57
+ if (this.props.geometry) {
58
+ this.vertexCount = this.props.geometry.vertexCount;
59
+ this.topology = this.props.geometry.topology;
60
+ }
289
61
 
290
- getAttributes() {
291
- return this.attributes;
292
- }
62
+ const {renderPipeline, getUniforms} = PipelineFactory.getDefaultPipelineFactory(this.device).createRenderPipeline({
63
+ ...this.props,
64
+ vs: this.vs,
65
+ fs: this.fs,
66
+ topology: this.topology,
67
+ parameters: props.parameters,
68
+ // Geometry in the vertex shader!
69
+ // @ts-expect-error
70
+ layout: props.layout
71
+ });
293
72
 
294
- getProgram(): Program {
295
- return this.program;
296
- }
73
+ this.pipeline = renderPipeline;
74
+ this._getModuleUniforms = getUniforms;
297
75
 
298
- setProgram(props): void {
299
- const {program, vs, fs, modules, defines, inject, varyings, bufferMode, transpileToGLSL100} =
300
- props;
301
- this.programProps = {
302
- program,
303
- vs,
304
- fs,
305
- modules,
306
- defines,
307
- inject,
308
- varyings,
309
- bufferMode,
310
- transpileToGLSL100
311
- };
312
- this._programDirty = true;
76
+ if (this.props.geometry) {
77
+ this._setGeometry(this.props.geometry);
78
+ }
79
+ this.setUniforms(this._getModuleUniforms()) // Get all default module uniforms
80
+ this.setProps(this.props);
313
81
  }
314
82
 
315
- getUniforms() {
316
- return this.uniforms;
83
+ destroy(): void {
84
+ this.pipeline.destroy();
317
85
  }
318
86
 
319
- // SETTERS
320
-
321
- setDrawMode(drawMode): this {
322
- this.drawMode = drawMode;
87
+ draw(renderPass?: RenderPass): this {
88
+ this.pipeline.draw({
89
+ renderPass,
90
+ vertexCount: this.vertexCount,
91
+ instanceCount: this.props.instanceCount
92
+ });
323
93
  return this;
324
94
  }
325
95
 
326
- setVertexCount(vertexCount): this {
327
- assert(Number.isFinite(vertexCount));
328
- this.vertexCount = vertexCount;
96
+ setProps(props: ModelProps): this {
97
+ if (props.indices) {
98
+ this.setIndexBuffer(props.indices);
99
+ }
100
+ if (props.attributes) {
101
+ this.setAttributes(props.attributes);
102
+ }
103
+ if (props.bindings) {
104
+ this.setBindings(props.bindings);
105
+ }
106
+ if (props.uniforms) {
107
+ this.setUniforms(props.uniforms);
108
+ }
109
+ if (props.moduleSettings) {
110
+ this.updateModuleSettings(props.moduleSettings);
111
+ }
329
112
  return this;
330
113
  }
331
114
 
332
- setInstanceCount(instanceCount): this {
333
- assert(Number.isFinite(instanceCount));
334
- this.instanceCount = instanceCount;
115
+ updateModuleSettings(props: Record<string, any>): this {
116
+ const uniforms = this._getModuleUniforms(props);
117
+ this.setUniforms(uniforms);
335
118
  return this;
336
119
  }
337
120
 
338
- setGeometry(geometry): this {
339
- this.drawMode = geometry.drawMode;
340
- this.vertexCount = geometry.getVertexCount();
341
-
342
- this._deleteGeometryBuffers();
343
-
344
- this.geometryBuffers = getBuffersFromGeometry(this.gl, geometry);
345
- this.vertexArray.setAttributes(this.geometryBuffers);
121
+ setIndexBuffer(indices: Buffer): this {
122
+ this.pipeline.setIndexBuffer(indices);
123
+ // this._indices = indices;
346
124
  return this;
347
125
  }
348
126
 
349
- setAttributes(attributes = {}): this {
350
- // Avoid setting needsRedraw if no attributes
351
- if (isObjectEmpty(attributes)) {
352
- return this;
353
- }
354
-
355
- const normalizedAttributes = {};
356
- for (const name in attributes) {
357
- const attribute = attributes[name];
358
- // The `getValue` call provides support for deck.gl `Attribute` class
359
- // TODO - remove once deck refactoring completes
360
- normalizedAttributes[name] = attribute.getValue ? attribute.getValue() : attribute;
361
- }
362
-
363
- this.vertexArray.setAttributes(normalizedAttributes);
127
+ setAttributes(attributes: Record<string, Buffer>): this {
128
+ this.pipeline.setAttributes(attributes);
129
+ Object.assign(this.props.attributes, attributes);
364
130
  return this;
365
131
  }
366
132
 
367
- // TODO - should actually set the uniforms
368
- setUniforms(uniforms = {}): this {
369
- Object.assign(this.uniforms, uniforms);
133
+ /** Set the bindings */
134
+ setBindings(bindings: Record<string, Binding>): this {
135
+ this.pipeline.setBindings(bindings);
136
+ Object.assign(this.props.bindings, bindings);
370
137
  return this;
371
138
  }
372
139
 
373
- getModuleUniforms(opts?) {
374
- this._checkProgram();
375
-
376
- const getUniforms = this.programManager.getUniforms(this.program);
377
-
378
- if (getUniforms) {
379
- return getUniforms(opts);
380
- }
381
-
382
- return {};
383
- }
384
-
385
- updateModuleSettings(opts?): this {
386
- const uniforms = this.getModuleUniforms(opts || {});
387
- return this.setUniforms(uniforms);
388
- }
389
-
390
- // DRAW CALLS
391
-
392
- clear(opts): this {
393
- clear(this.program.gl, opts);
140
+ setUniforms(uniforms: Record<string, any>): this {
141
+ this.pipeline.setUniforms(uniforms);
142
+ Object.assign(this.props.uniforms, uniforms);
394
143
  return this;
395
144
  }
396
145
 
397
- draw(opts: ModelDrawOptions = {}): boolean {
398
- // Lazy update program and vertex array
399
- this._checkProgram();
400
-
401
- const {
402
- moduleSettings = null,
403
- framebuffer,
404
- uniforms = {},
405
- attributes = {},
406
- transformFeedback = this.transformFeedback,
407
- parameters = {},
408
- vertexArray = this.vertexArray
409
- } = opts;
410
-
411
- // Update model with any just provided attributes, settings or uniforms
412
- this.setAttributes(attributes);
413
- this.updateModuleSettings(moduleSettings);
414
- this.setUniforms(uniforms);
146
+ _setGeometry(geometry: Geometry): void {
147
+ // this._deleteGeometryBuffers();
415
148
 
416
- let logPriority;
149
+ const geometryBuffers = getAttributeBuffersFromGeometry(this.device, geometry);
150
+ this.setAttributes(geometryBuffers);
417
151
 
418
- if (log.priority >= LOG_DRAW_PRIORITY) {
419
- logPriority = this._logDrawCallStart(LOG_DRAW_PRIORITY);
152
+ const indexBuffer = getIndexBufferFromGeometry(this.device, geometry);
153
+ if (indexBuffer) {
154
+ this.setIndexBuffer(indexBuffer);
420
155
  }
421
-
422
- const drawParams = this.vertexArray.getDrawParams();
423
- const {
424
- isIndexed = drawParams.isIndexed,
425
- indexType = drawParams.indexType,
426
- indexOffset = drawParams.indexOffset,
427
- vertexArrayInstanced = drawParams.isInstanced
428
- } = this.props;
429
-
430
- if (vertexArrayInstanced && !this.isInstanced) {
431
- log.warn('Found instanced attributes on non-instanced model', this.id)();
432
- }
433
-
434
- const {isInstanced, instanceCount} = this;
435
-
436
- const {onBeforeRender = NOOP, onAfterRender = NOOP} = this.props;
437
-
438
- onBeforeRender();
439
-
440
- this.program.setUniforms(this.uniforms);
441
-
442
- const didDraw = this.program.draw(
443
- Object.assign(DRAW_PARAMS, opts, {
444
- logPriority,
445
- uniforms: null, // Already set (may contain "function values" not understood by Program)
446
- framebuffer,
447
- parameters,
448
- drawMode: this.getDrawMode(),
449
- vertexCount: this.getVertexCount(),
450
- vertexArray,
451
- transformFeedback,
452
- isIndexed,
453
- indexType,
454
- isInstanced,
455
- instanceCount,
456
- offset: isIndexed ? indexOffset : 0
457
- })
458
- );
459
-
460
- onAfterRender();
461
-
462
- if (log.priority >= LOG_DRAW_PRIORITY) {
463
- this._logDrawCallEnd(logPriority, vertexArray, framebuffer);
464
- }
465
-
466
- return didDraw;
467
- }
468
-
469
- // Draw call for transform feedback, TBD...
470
- transform(opts: ModelDrawOptions = {}): this {
471
- // @ts-expect-error
472
- const {discard = true, feedbackBuffers, unbindModels = []} = opts;
473
-
474
- let {parameters} = opts;
475
-
476
- if (feedbackBuffers) {
477
- this._setFeedbackBuffers(feedbackBuffers);
478
- }
479
-
480
- if (discard) {
481
- parameters = Object.assign({}, parameters, {[GL.RASTERIZER_DISCARD]: discard});
482
- }
483
-
484
- unbindModels.forEach((model) => model.vertexArray.unbindBuffers());
485
- try {
486
- this.draw(Object.assign({}, opts, {parameters}));
487
- } finally {
488
- unbindModels.forEach((model) => model.vertexArray.bindBuffers());
489
- }
490
-
491
- return this;
492
156
  }
157
+ }
493
158
 
494
- // DEPRECATED METHODS
495
-
496
- render(uniforms = {}): boolean {
497
- log.warn('Model.render() is deprecated. Use Model.setUniforms() and Model.draw()')();
498
- return this.setUniforms(uniforms).draw();
499
- }
500
-
501
- // PRIVATE METHODS
502
-
503
- _setModelProps(props): void {
504
- Object.assign(this.props, props);
505
-
506
- if ('uniforms' in props) {
507
- this.setUniforms(props.uniforms);
508
- }
509
-
510
- if ('pickable' in props) {
511
- this.pickable = props.pickable;
512
- }
513
-
514
- if ('instanceCount' in props) {
515
- this.instanceCount = props.instanceCount;
516
- }
517
- if ('geometry' in props) {
518
- this.setGeometry(props.geometry);
519
- }
520
-
521
- // webgl settings
522
- if ('attributes' in props) {
523
- this.setAttributes(props.attributes);
524
- }
525
- if ('_feedbackBuffers' in props) {
526
- this._setFeedbackBuffers(props._feedbackBuffers);
527
- }
159
+ /** Create a shader from the different overloads */
160
+ function getShaderSource(device: Device, shader: string | {glsl?: string; wgsl?: string}): string {
161
+ // TODO - detect WGSL/GLSL and throw an error if not supported
162
+ if (typeof shader === 'string') {
163
+ return shader;
528
164
  }
529
165
 
530
- _checkProgram(): void {
531
- const needsUpdate =
532
- this._programDirty || this.programManager.stateHash !== this._programManagerState;
533
-
534
- if (!needsUpdate) {
535
- return;
536
- }
537
-
538
- let {program} = this.programProps;
539
-
540
- if (program) {
541
- this._managedProgram = false;
542
- } else {
543
- const {vs, fs, modules, inject, defines, varyings, bufferMode, transpileToGLSL100} =
544
- this.programProps;
545
- program = this.programManager.get({
546
- // @ts-expect-error
547
- vs,
548
- // @ts-expect-error
549
- fs,
550
- modules,
551
- inject,
552
- defines,
553
- varyings,
554
- bufferMode,
555
- transpileToGLSL100
556
- });
557
- if (this.program && this._managedProgram) {
558
- this.programManager.release(this.program);
166
+ switch (device.info.type) {
167
+ case 'webgpu':
168
+ if (shader?.wgsl) {
169
+ return shader.wgsl;
559
170
  }
560
- this._programManagerState = this.programManager.stateHash;
561
- this._managedProgram = true;
562
- }
563
-
564
- assert(program instanceof Program, 'Model needs a program');
171
+ throw new Error('WebGPU does not support GLSL shaders');
565
172
 
566
- this._programDirty = false;
567
-
568
- if (program === this.program) {
569
- return;
570
- }
571
-
572
- this.program = program;
573
-
574
- if (this.vertexArray) {
575
- this.vertexArray.setProps({program: this.program, attributes: this.vertexArray.attributes});
576
- } else {
577
- this.vertexArray = new VertexArray(this.gl, {program: this.program});
578
- }
579
-
580
- // Make sure we have some reasonable default uniforms in place
581
- this.setUniforms(
582
- Object.assign(
583
- {},
584
- this.getModuleUniforms() // Get all default uniforms,
585
- )
586
- );
587
- }
588
-
589
- _deleteGeometryBuffers(): void {
590
- for (const name in this.geometryBuffers) {
591
- // Buffer is raw value (for indices) or first element of [buffer, accessor] pair
592
- const buffer = this.geometryBuffers[name][0] || this.geometryBuffers[name];
593
- if (buffer instanceof Buffer) {
594
- buffer.destroy();
173
+ default:
174
+ if (shader?.glsl) {
175
+ return shader.glsl;
595
176
  }
596
- }
597
- }
598
-
599
- // Updates (evaluates) all function valued uniforms based on a new set of animationProps
600
- // experimental
601
- _setAnimationProps(animationProps): void {
602
- if (this.animated) {
603
- assert(animationProps, 'Model.draw(): animated uniforms but no animationProps');
604
- // const animatedUniforms = this._evaluateAnimateUniforms(animationProps);
605
- // Object.assign(this.uniforms, animatedUniforms);
606
- }
607
- }
608
-
609
- // Transform Feedback
610
-
611
- _setFeedbackBuffers(feedbackBuffers = {}): this {
612
- // Avoid setting needsRedraw if no feedbackBuffers
613
- if (isObjectEmpty(feedbackBuffers)) {
614
- return this;
615
- }
616
-
617
- const {gl} = this.program;
618
- this.transformFeedback =
619
- this.transformFeedback ||
620
- new TransformFeedback(gl, {
621
- program: this.program
622
- });
623
-
624
- this.transformFeedback.setBuffers(feedbackBuffers);
625
- return this;
626
- }
627
-
628
- _logDrawCallStart(logLevel: number): number {
629
- const logDrawTimeout = logLevel > 3 ? 0 : LOG_DRAW_TIMEOUT;
630
- if (Date.now() - this.lastLogTime < logDrawTimeout) {
631
- return undefined;
632
- }
633
-
634
- this.lastLogTime = Date.now();
635
-
636
- log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, {collapsed: log.level <= 2})();
637
-
638
- return logLevel;
639
- }
640
-
641
- _logDrawCallEnd(logLevel, vertexArray, uniforms, framebuffer?): void {
642
- // HACK: logLevel === undefined means logDrawCallStart didn't run
643
- if (logLevel === undefined) {
644
- return;
645
- }
646
-
647
- const attributeTable = getDebugTableForVertexArray({
648
- vertexArray,
649
- header: `${this.id} attributes`,
650
- // @ts-expect-error
651
- attributes: this._attributes
652
- });
653
-
654
- const {
655
- table: uniformTable,
656
- unusedTable,
657
- unusedCount
658
- } = getDebugTableForUniforms({
659
- header: `${this.id} uniforms`,
660
- program: this.program,
661
- uniforms: Object.assign({}, this.program.uniforms, uniforms)
662
- });
663
-
664
- // log missing uniforms
665
- const {table: missingTable, count: missingCount} = getDebugTableForUniforms({
666
- header: `${this.id} uniforms`,
667
- program: this.program,
668
- uniforms: Object.assign({}, this.program.uniforms, uniforms),
669
- undefinedOnly: true
670
- });
671
-
672
- if (missingCount > 0) {
673
- log.log('MISSING UNIFORMS', Object.keys(missingTable))();
674
- // log.table(logLevel, missingTable)();
675
- }
676
- if (unusedCount > 0) {
677
- log.log('UNUSED UNIFORMS', Object.keys(unusedTable))();
678
- // log.log(logLevel, 'Unused uniforms ', unusedTable)();
679
- }
680
-
681
- const configTable = getDebugTableForProgramConfiguration(this.vertexArray.configuration);
682
-
683
- log.table(logLevel, attributeTable)();
684
-
685
- log.table(logLevel, uniformTable)();
686
-
687
- log.table(logLevel + 1, configTable)();
688
-
689
- if (framebuffer) {
690
- framebuffer.log({logLevel: LOG_DRAW_PRIORITY, message: `Rendered to ${framebuffer.id}`});
691
- }
692
-
693
- log.groupEnd(LOG_DRAW_PRIORITY)();
177
+ throw new Error('WebGL does not support WGSL shaders');
694
178
  }
695
179
  }