simulationjsv2 0.4.9 → 0.4.10

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/TODO.md CHANGED
@@ -1,4 +1,4 @@
1
1
  # TODO
2
2
 
3
- - [ ] Memoize render scene buffer
3
+ - [x] Memoize render scene buffer
4
4
  - Should only be reset to resize to a new larger object then reused on all frames
@@ -1,4 +1,4 @@
1
- import { CircleGeometryParams, CubeGeometryParams, EmptyParams, Line2dGeometryParams, Line3dGeometryParams, Mat4, PolygonGeometryParams, Spline2dGeometryParams, SquareGeometryParams, Vector2, Vector3, VertexColorMap } from './types.js';
1
+ import { BufferExtenderInfo, CircleGeometryParams, CubeGeometryParams, EmptyParams, Line2dGeometryParams, Line3dGeometryParams, Mat4, PolygonGeometryParams, Spline2dGeometryParams, SquareGeometryParams, Vector2, Vector3, VertexColorMap } from './types.js';
2
2
  import { Color, Vertex } from './utils.js';
3
3
  import { CubicBezierCurve2d, SplinePoint2d } from './graphics.js';
4
4
  export declare abstract class Geometry<T extends EmptyParams> {
@@ -14,9 +14,9 @@ export declare abstract class Geometry<T extends EmptyParams> {
14
14
  abstract recompute(): void;
15
15
  getTriangleVertexCount(): number;
16
16
  getWireframeVertexCount(): number;
17
- protected bufferFromOrder(order: number[], color: Color): number[];
18
- getWireframeBuffer(color: Color): number[];
19
- getTriangleBuffer(color: Color): number[];
17
+ protected bufferFromOrder(order: number[], color: Color, bufferExtender?: BufferExtenderInfo): number[];
18
+ getWireframeBuffer(color: Color, bufferExtender?: BufferExtenderInfo): number[];
19
+ getTriangleBuffer(color: Color, bufferExtender?: BufferExtenderInfo): number[];
20
20
  }
21
21
  export declare class PlaneGeometry extends Geometry<EmptyParams> {
22
22
  protected params: {};
@@ -26,7 +26,7 @@ export declare class PlaneGeometry extends Geometry<EmptyParams> {
26
26
  constructor(vertices: Vertex[]);
27
27
  recompute(): void;
28
28
  updateVertices(vertices: Vertex[]): void;
29
- getTriangleBuffer(color: Color): number[];
29
+ getTriangleBuffer(color: Color, bufferExtender?: BufferExtenderInfo): number[];
30
30
  }
31
31
  export declare class CubeGeometry extends Geometry<CubeGeometryParams> {
32
32
  protected params: CubeGeometryParams;
@@ -48,7 +48,7 @@ export declare class SquareGeometry extends Geometry<SquareGeometryParams> {
48
48
  setWidth(width: number): void;
49
49
  setHeight(height: number): void;
50
50
  recompute(): void;
51
- getTriangleBuffer(color: Color): number[];
51
+ getTriangleBuffer(color: Color, bufferExtender?: BufferExtenderInfo): number[];
52
52
  }
53
53
  export declare class BlankGeometry extends Geometry<EmptyParams> {
54
54
  protected wireframeOrder: never[];
@@ -83,8 +83,8 @@ export declare class Spline2dGeometry extends Geometry<Spline2dGeometryParams> {
83
83
  private computeCurves;
84
84
  private updateWireframeOrder;
85
85
  recompute(): void;
86
- getWireframeBuffer(color: Color): number[];
87
- getTriangleBuffer(_: Color): number[];
86
+ getWireframeBuffer(color: Color, bufferExtender?: BufferExtenderInfo): number[];
87
+ getTriangleBuffer(_: Color, bufferExtender?: BufferExtenderInfo): number[];
88
88
  }
89
89
  export declare class Line2dGeometry extends Geometry<Line2dGeometryParams> {
90
90
  protected wireframeOrder: number[];
package/dist/geometry.js CHANGED
@@ -24,20 +24,20 @@ export class Geometry {
24
24
  getWireframeVertexCount() {
25
25
  return this.wireframeOrder.length;
26
26
  }
27
- bufferFromOrder(order, color) {
27
+ bufferFromOrder(order, color, bufferExtender) {
28
28
  return order
29
29
  .map((vertexIndex) => {
30
30
  const pos = cloneBuf(this.vertices[vertexIndex]);
31
31
  vec3.transformMat4(pos, this.matrix, pos);
32
- return bufferGenerator.generate(pos[0], pos[1], pos[2], color);
32
+ return bufferGenerator.generate(pos[0], pos[1], pos[2], color, vector2(), bufferExtender);
33
33
  })
34
34
  .flat();
35
35
  }
36
- getWireframeBuffer(color) {
37
- return this.bufferFromOrder(this.wireframeOrder, color);
36
+ getWireframeBuffer(color, bufferExtender) {
37
+ return this.bufferFromOrder(this.wireframeOrder, color, bufferExtender);
38
38
  }
39
- getTriangleBuffer(color) {
40
- return this.bufferFromOrder(this.triangleOrder, color);
39
+ getTriangleBuffer(color, bufferExtender) {
40
+ return this.bufferFromOrder(this.triangleOrder, color, bufferExtender);
41
41
  }
42
42
  }
43
43
  export class PlaneGeometry extends Geometry {
@@ -61,13 +61,13 @@ export class PlaneGeometry extends Geometry {
61
61
  .fill(0)
62
62
  .map((_, index) => index)).flat();
63
63
  }
64
- getTriangleBuffer(color) {
64
+ getTriangleBuffer(color, bufferExtender) {
65
65
  return this.triangleOrder
66
66
  .map((index) => {
67
67
  const vertex = this.rawVertices[index];
68
68
  const pos = cloneBuf(vertex.getPos());
69
69
  vec3.transformMat4(pos, this.matrix, pos);
70
- return bufferGenerator.generate(pos[0], pos[1], pos[2], vertex.getColor() || color);
70
+ return bufferGenerator.generate(pos[0], pos[1], pos[2], vertex.getColor() || color, vector2(), bufferExtender);
71
71
  })
72
72
  .flat();
73
73
  }
@@ -155,12 +155,12 @@ export class SquareGeometry extends Geometry {
155
155
  vector3(-this.params.width * centerOffset[0], -this.params.height * (1 - centerOffset[1]))
156
156
  ];
157
157
  }
158
- getTriangleBuffer(color) {
158
+ getTriangleBuffer(color, bufferExtender) {
159
159
  return this.triangleOrder
160
160
  .map((vertexIndex) => {
161
161
  const pos = cloneBuf(this.vertices[vertexIndex]);
162
162
  vec3.transformMat4(pos, this.matrix, pos);
163
- return bufferGenerator.generate(pos[0], pos[1], pos[2], this.params.colorMap[vertexIndex] || color);
163
+ return bufferGenerator.generate(pos[0], pos[1], pos[2], this.params.colorMap[vertexIndex] || color, vector2(), bufferExtender);
164
164
  })
165
165
  .flat();
166
166
  }
@@ -349,22 +349,21 @@ export class Spline2dGeometry extends Geometry {
349
349
  .map((_, index) => index)).flat();
350
350
  this.updateWireframeOrder();
351
351
  }
352
- getWireframeBuffer(color) {
352
+ getWireframeBuffer(color, bufferExtender) {
353
353
  return this.wireframeOrder
354
354
  .map((vertexIndex) => {
355
355
  const vertex = cloneBuf(this.vertices[vertexIndex]);
356
356
  vec3.transformMat4(vertex, this.matrix, vertex);
357
- return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], color);
357
+ return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], color, vector2(), bufferExtender);
358
358
  })
359
359
  .flat();
360
360
  }
361
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
362
- getTriangleBuffer(_) {
361
+ getTriangleBuffer(_, bufferExtender) {
363
362
  return this.triangleOrder
364
363
  .map((vertexIndex) => {
365
364
  const vertex = cloneBuf(this.vertices[vertexIndex]);
366
365
  vec3.transformMat4(vertex, this.matrix, vertex);
367
- return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], this.params.vertexColors[vertexIndex]);
366
+ return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], this.params.vertexColors[vertexIndex], vector2(), bufferExtender);
368
367
  })
369
368
  .flat();
370
369
  }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@webgpu/types" />
2
2
  import { Camera } from './simulation.js';
3
- import type { Vector2, Vector3, LerpFunc, VertexColorMap, ElementRotation, Mat4, AnySimulationElement } from './types.js';
3
+ import type { Vector2, Vector3, LerpFunc, VertexColorMap, ElementRotation, Mat4, AnySimulationElement, BufferExtenderInfo } from './types.js';
4
4
  import { Vertex, Color } from './utils.js';
5
5
  import { BlankGeometry, CircleGeometry, CubeGeometry, Geometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry } from './geometry.js';
6
6
  import { VertexCache } from './internalUtils.js';
@@ -30,7 +30,7 @@ export declare abstract class SimulationElement<T extends Vector2 | Vector3 = Ve
30
30
  protected abstract updateMatrix(camera: Camera): void;
31
31
  getVertexCount(): number;
32
32
  protected defaultUpdateMatrix(camera: Camera): void;
33
- getBuffer(camera: Camera): number[];
33
+ getBuffer(camera: Camera, bufferExtender?: BufferExtenderInfo): number[];
34
34
  }
35
35
  export declare abstract class SimulationElement3d extends SimulationElement {
36
36
  protected pos: Vector3;
package/dist/graphics.js CHANGED
@@ -73,19 +73,21 @@ export class SimulationElement {
73
73
  }
74
74
  this.geometry.updateMatrix(matrix);
75
75
  }
76
- getBuffer(camera) {
77
- if (this.vertexCache.shouldUpdate() || camera.hasUpdated()) {
76
+ getBuffer(camera, bufferExtender) {
77
+ const shouldEvalExtender = bufferExtender?.shouldEvaluate?.();
78
+ const reEvalExtender = shouldEvalExtender === undefined ? true : shouldEvalExtender;
79
+ if (this.vertexCache.shouldUpdate() || camera.hasUpdated() || reEvalExtender) {
78
80
  this.updateMatrix(camera);
79
81
  this.geometry.recompute();
80
82
  if (this.isInstanced) {
81
83
  bufferGenerator.setInstancing(true);
82
84
  }
83
- let resBuffer = [];
85
+ let resBuffer;
84
86
  if (this.isWireframe()) {
85
- resBuffer = this.geometry.getWireframeBuffer(this.color);
87
+ resBuffer = this.geometry.getWireframeBuffer(this.color, bufferExtender);
86
88
  }
87
89
  else {
88
- resBuffer = this.geometry.getTriangleBuffer(this.color);
90
+ resBuffer = this.geometry.getTriangleBuffer(this.color, bufferExtender);
89
91
  }
90
92
  bufferGenerator.setInstancing(false);
91
93
  this.vertexCache.setCache(resBuffer);
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@webgpu/types" />
2
- import { AnySimulationElement, Mat4, Vector2, Vector3 } from './types.js';
2
+ import { AnySimulationElement, BufferExtenderInfo, Mat4, Vector2, Vector3, VertexParamInfo } from './types.js';
3
3
  import { Color } from './utils.js';
4
4
  export declare class VertexCache {
5
5
  private vertices;
@@ -52,14 +52,14 @@ declare class BufferGenerator {
52
52
  private instancing;
53
53
  constructor();
54
54
  setInstancing(state: boolean): void;
55
- generate(x: number, y: number, z: number, color: Color, uv?: Vector2): number[];
55
+ generate(x: number, y: number, z: number, color: Color, uv?: Vector2, bufferExtender?: BufferExtenderInfo): number[];
56
56
  }
57
57
  export declare const bufferGenerator: BufferGenerator;
58
58
  export declare function vector3ToPixelRatio(vec: Vector3): void;
59
59
  export declare function vector2ToPixelRatio(vec: Vector2): void;
60
60
  export declare function matrixFromRotation(rotation: Vector3): Mat4;
61
61
  export declare function rotateMat4(mat: Mat4, rotation: Vector3): void;
62
- export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayout: GPUBindGroupLayout, presentationFormat: GPUTextureFormat, entryPoint: string, topology: GPUPrimitiveTopology): GPURenderPipeline;
62
+ export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayout: GPUBindGroupLayout, presentationFormat: GPUTextureFormat, entryPoint: string, topology: GPUPrimitiveTopology, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
63
63
  export declare function triangulateWireFrameOrder(len: number): number[];
64
64
  export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
65
65
  export {};
@@ -182,7 +182,15 @@ class BufferGenerator {
182
182
  setInstancing(state) {
183
183
  this.instancing = state;
184
184
  }
185
- generate(x, y, z, color, uv = vector2()) {
185
+ generate(x, y, z, color, uv = vector2(), bufferExtender) {
186
+ if (bufferExtender) {
187
+ const buf = bufferExtender.extender(x, y, z, color);
188
+ if (buf.length !== bufferExtender.size) {
189
+ logger.log_error(`Vertex size for shader group does not match buffer extension size (${buf.length} to expected ${bufferExtender.size})`);
190
+ return [];
191
+ }
192
+ return buf;
193
+ }
186
194
  return [x, y, z, 1, ...color.toBuffer(), ...uv, this.instancing ? 1 : 0];
187
195
  }
188
196
  }
@@ -208,7 +216,47 @@ export function rotateMat4(mat, rotation) {
208
216
  mat4.rotateY(mat, rotation[1], mat);
209
217
  mat4.rotateX(mat, rotation[0], mat);
210
218
  }
211
- export function createPipeline(device, module, bindGroupLayout, presentationFormat, entryPoint, topology) {
219
+ export function createPipeline(device, module, bindGroupLayout, presentationFormat, entryPoint, topology, vertexParams) {
220
+ let params = [
221
+ {
222
+ // position
223
+ shaderLocation: 0,
224
+ offset: 0,
225
+ format: 'float32x4'
226
+ },
227
+ {
228
+ // color
229
+ shaderLocation: 1,
230
+ offset: colorOffset,
231
+ format: 'float32x4'
232
+ },
233
+ {
234
+ // size
235
+ shaderLocation: 2,
236
+ offset: uvOffset,
237
+ format: 'float32x2'
238
+ },
239
+ {
240
+ // drawing instances
241
+ shaderLocation: 3,
242
+ offset: drawingInstancesOffset,
243
+ format: 'float32'
244
+ }
245
+ ];
246
+ let stride = vertexSize;
247
+ if (vertexParams) {
248
+ params = [];
249
+ let offset = 0;
250
+ for (let i = 0; i < vertexParams.length; i++) {
251
+ params.push({
252
+ shaderLocation: i,
253
+ offset,
254
+ format: vertexParams[i].format
255
+ });
256
+ offset += vertexParams[i].size;
257
+ }
258
+ stride = offset;
259
+ }
212
260
  return device.createRenderPipeline({
213
261
  layout: device.createPipelineLayout({
214
262
  bindGroupLayouts: [bindGroupLayout]
@@ -218,33 +266,8 @@ export function createPipeline(device, module, bindGroupLayout, presentationForm
218
266
  entryPoint,
219
267
  buffers: [
220
268
  {
221
- arrayStride: vertexSize,
222
- attributes: [
223
- {
224
- // position
225
- shaderLocation: 0,
226
- offset: 0,
227
- format: 'float32x4'
228
- },
229
- {
230
- // color
231
- shaderLocation: 1,
232
- offset: colorOffset,
233
- format: 'float32x4'
234
- },
235
- {
236
- // size
237
- shaderLocation: 2,
238
- offset: uvOffset,
239
- format: 'float32x2'
240
- },
241
- {
242
- // drawing instances
243
- shaderLocation: 3,
244
- offset: drawingInstancesOffset,
245
- format: 'float32'
246
- }
247
- ]
269
+ arrayStride: stride,
270
+ attributes: params
248
271
  }
249
272
  ]
250
273
  },
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@webgpu/types" />
2
2
  import { SimulationElement3d } from './graphics.js';
3
- import type { Vector2, Vector3, LerpFunc, AnySimulationElement } from './types.js';
3
+ import type { Vector2, Vector3, LerpFunc, AnySimulationElement, BufferExtenderInfo, VertexParamInfo } from './types.js';
4
4
  import { Color } from './utils.js';
5
5
  import { BlankGeometry } from './geometry.js';
6
6
  import { SimSceneObjInfo } from './internalUtils.js';
@@ -39,13 +39,13 @@ export declare class SceneCollection extends SimulationElement3d {
39
39
  protected geometry: BlankGeometry;
40
40
  private name;
41
41
  private scene;
42
- private device;
43
- constructor(name: string);
42
+ protected device: GPUDevice | null;
43
+ constructor(name?: string);
44
44
  setWireframe(_: boolean): void;
45
- getName(): string;
45
+ getName(): string | null;
46
46
  getScene(): SimSceneObjInfo[];
47
47
  setDevice(device: GPUDevice): void;
48
- private propagateDevice;
48
+ protected propagateDevice(device: GPUDevice): void;
49
49
  getVertexCount(): number;
50
50
  getSceneObjects(): AnySimulationElement[];
51
51
  setSceneObjects(newScene: AnySimulationElement[]): void;
@@ -82,3 +82,17 @@ export declare class Camera {
82
82
  getPos(): Vector3;
83
83
  getAspectRatio(): number;
84
84
  }
85
+ export declare class ShaderGroup extends SceneCollection {
86
+ protected geometry: BlankGeometry;
87
+ private code;
88
+ private module;
89
+ private pipeline;
90
+ private topology;
91
+ private bufferExtender;
92
+ private vertexParams;
93
+ constructor(shaderCode: string, topology: GPUPrimitiveTopology | undefined, vertexParams: VertexParamInfo[], bufferExtender: BufferExtenderInfo);
94
+ protected propagateDevice(device: GPUDevice): void;
95
+ getPipeline(): GPURenderPipeline | null;
96
+ protected updateMatrix(camera: Camera): void;
97
+ getBufferExtender(): BufferExtenderInfo;
98
+ }
@@ -31,9 +31,15 @@ fn vertex_main_3d(
31
31
  ) -> VertexOutput {
32
32
  var output : VertexOutput;
33
33
 
34
- output.Position = uniforms.modelViewProjectionMatrix * position;
34
+ if (drawingInstance == 1) {
35
+ let transformedPos = instanceMatrices[instanceIdx] * position;
36
+ output.Position = uniforms.modelViewProjectionMatrix * transformedPos;
37
+ } else {
38
+ output.Position = uniforms.modelViewProjectionMatrix * position;
39
+ }
40
+
35
41
  output.fragUV = uv;
36
- output.fragPosition = position;
42
+ output.fragPosition = output.Position;
37
43
  output.fragColor = color;
38
44
  return output;
39
45
  }
@@ -56,7 +62,7 @@ fn vertex_main_2d(
56
62
  }
57
63
 
58
64
  output.fragUV = uv;
59
- output.fragPosition = position;
65
+ output.fragPosition = output.Position;
60
66
  output.fragColor = color;
61
67
  return output;
62
68
  }
@@ -70,9 +76,7 @@ fn fragment_main(
70
76
  return fragColor;
71
77
  }
72
78
  `;
73
- const simjsFrameRateCss = `@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Roboto:wght@100&display=swap');
74
-
75
- .simjs-frame-rate {
79
+ const simjsFrameRateCss = `.simjs-frame-rate {
76
80
  position: absolute;
77
81
  top: 0;
78
82
  left: 0;
@@ -80,13 +84,14 @@ const simjsFrameRateCss = `@import url('https://fonts.googleapis.com/css2?family
80
84
  color: white;
81
85
  padding: 8px 12px;
82
86
  z-index: 1000;
83
- font-family: Roboto Mono;
87
+ font-family: monospace;
84
88
  font-size: 16px;
85
89
  }`;
86
90
  class FrameRateView {
87
91
  el;
88
92
  fpsBuffer = [];
89
93
  maxFpsBufferLength = 8;
94
+ prevAvg = 0;
90
95
  constructor(show) {
91
96
  this.el = document.createElement('div');
92
97
  this.el.classList.add('simjs-frame-rate');
@@ -106,7 +111,10 @@ class FrameRateView {
106
111
  this.fpsBuffer.push(num);
107
112
  }
108
113
  const fps = Math.round(this.fpsBuffer.reduce((acc, curr) => acc + curr, 0) / this.fpsBuffer.length);
109
- this.el.innerHTML = `${fps} FPS`;
114
+ if (fps !== this.prevAvg) {
115
+ this.el.innerHTML = `${fps} FPS`;
116
+ this.prevAvg = fps;
117
+ }
110
118
  }
111
119
  }
112
120
  export class Simulation {
@@ -394,7 +402,7 @@ export class Simulation {
394
402
  };
395
403
  requestAnimationFrame(frame);
396
404
  }
397
- renderScene(device, passEncoder, vertexBuffer, scene, startOffset, diff) {
405
+ renderScene(device, passEncoder, vertexBuffer, scene, startOffset, diff, shaderInfo) {
398
406
  if (this.pipelines === null)
399
407
  return 0;
400
408
  let currentOffset = startOffset;
@@ -411,15 +419,26 @@ export class Simulation {
411
419
  }
412
420
  const obj = scene[i].getObj();
413
421
  if (obj instanceof SceneCollection) {
414
- currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff);
422
+ let shaderInfo = undefined;
423
+ if (obj instanceof ShaderGroup) {
424
+ const pipeline = obj.getPipeline();
425
+ if (pipeline !== null) {
426
+ shaderInfo = { pipeline, bufferExtender: obj.getBufferExtender() };
427
+ }
428
+ }
429
+ currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff, shaderInfo || undefined);
415
430
  continue;
416
431
  }
417
- const buffer = new Float32Array(obj.getBuffer(this.camera));
418
- const vertexCount = buffer.length / BUF_LEN;
432
+ const buffer = new Float32Array(obj.getBuffer(this.camera, shaderInfo?.bufferExtender));
433
+ const bufLen = shaderInfo?.bufferExtender?.size || BUF_LEN;
434
+ const vertexCount = buffer.length / bufLen;
419
435
  device.queue.writeBuffer(vertexBuffer, currentOffset, buffer);
420
436
  vertexBuffer.unmap();
421
437
  const is3d = Boolean(obj.is3d);
422
- if (obj.isWireframe()) {
438
+ if (shaderInfo) {
439
+ passEncoder.setPipeline(shaderInfo.pipeline);
440
+ }
441
+ else if (obj.isWireframe()) {
423
442
  if (is3d) {
424
443
  passEncoder.setPipeline(this.pipelines.lineStrip3d);
425
444
  }
@@ -500,7 +519,7 @@ export class SceneCollection extends SimulationElement3d {
500
519
  constructor(name) {
501
520
  super(vector3());
502
521
  this.wireframe = false;
503
- this.name = name;
522
+ this.name = name || null;
504
523
  this.scene = [];
505
524
  this.geometry = new BlankGeometry();
506
525
  }
@@ -564,9 +583,11 @@ export class SceneCollection extends SimulationElement3d {
564
583
  getSceneBuffer(camera) {
565
584
  return this.scene.map((item) => item.getObj().getBuffer(camera)).flat();
566
585
  }
586
+ // TODO - improve
567
587
  getWireframe(camera) {
568
588
  return this.getSceneBuffer(camera);
569
589
  }
590
+ // TODO - improve
570
591
  getTriangles(camera) {
571
592
  return this.getSceneBuffer(camera);
572
593
  }
@@ -661,3 +682,65 @@ export class Camera {
661
682
  return this.aspectRatio;
662
683
  }
663
684
  }
685
+ export class ShaderGroup extends SceneCollection {
686
+ geometry;
687
+ code;
688
+ module;
689
+ pipeline;
690
+ topology;
691
+ bufferExtender;
692
+ vertexParams;
693
+ constructor(shaderCode, topology = 'triangle-list', vertexParams, bufferExtender) {
694
+ super();
695
+ const defaultCode = `
696
+ struct Uniforms {
697
+ modelViewProjectionMatrix : mat4x4<f32>,
698
+ orthoProjectionMatrix : mat4x4<f32>
699
+ }
700
+
701
+ @group(0) @binding(0) var<uniform> uniforms : Uniforms;
702
+
703
+ @group(0) @binding(1) var<storage, read> instanceMatrices : array<mat4x4f>;
704
+ `;
705
+ this.geometry = new BlankGeometry();
706
+ this.code = defaultCode + shaderCode;
707
+ this.module = null;
708
+ this.pipeline = null;
709
+ this.topology = topology;
710
+ this.bufferExtender = bufferExtender;
711
+ this.vertexParams = vertexParams;
712
+ }
713
+ propagateDevice(device) {
714
+ super.propagateDevice(device);
715
+ this.module = device.createShaderModule({ code: this.code });
716
+ const bindGroupLayout = device.createBindGroupLayout({
717
+ entries: [
718
+ {
719
+ binding: 0,
720
+ visibility: GPUShaderStage.VERTEX,
721
+ buffer: {
722
+ type: 'uniform'
723
+ }
724
+ },
725
+ {
726
+ binding: 1,
727
+ visibility: GPUShaderStage.VERTEX,
728
+ buffer: {
729
+ type: 'read-only-storage'
730
+ }
731
+ }
732
+ ]
733
+ });
734
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
735
+ this.pipeline = createPipeline(device, this.module, bindGroupLayout, presentationFormat, 'vertex_main_2d', this.topology, this.vertexParams);
736
+ }
737
+ getPipeline() {
738
+ return this.pipeline;
739
+ }
740
+ updateMatrix(camera) {
741
+ this.defaultUpdateMatrix(camera);
742
+ }
743
+ getBufferExtender() {
744
+ return this.bufferExtender;
745
+ }
746
+ }
package/dist/types.d.ts CHANGED
@@ -78,3 +78,20 @@ export type RenderInfo = {
78
78
  bindGroupLayout: GPUBindGroupLayout;
79
79
  vertexBuffer: GPUBuffer | null;
80
80
  };
81
+ export type BindingInfo = {
82
+ visibility: GPUBindGroupLayoutEntry['visibility'];
83
+ buffer: GPUBindGroupLayoutEntry['buffer'];
84
+ };
85
+ export type BufferExtenderInfo = {
86
+ size: number;
87
+ extender: (x: number, y: number, z: number, color: Color) => number[];
88
+ shouldEvaluate?: () => boolean;
89
+ };
90
+ export type ShaderInfo = {
91
+ pipeline: GPURenderPipeline;
92
+ bufferExtender: BufferExtenderInfo;
93
+ };
94
+ export type VertexParamInfo = {
95
+ format: GPUVertexFormat;
96
+ size: number;
97
+ };
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Jackson Otto",
7
7
  "description": "A simple graphics library using WebGPU",
8
- "version": "0.4.9",
8
+ "version": "0.4.10",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",