simulationjsv2 0.10.5 → 0.11.0

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 (48) hide show
  1. package/README.md +4 -0
  2. package/TODO.md +4 -20
  3. package/dist/backend.d.ts +38 -0
  4. package/dist/backend.js +127 -0
  5. package/dist/backends/backend.d.ts +22 -0
  6. package/dist/backends/backend.js +21 -0
  7. package/dist/backends/webgl.d.ts +19 -0
  8. package/dist/backends/webgl.js +112 -0
  9. package/dist/backends/webgpu.d.ts +25 -0
  10. package/dist/backends/webgpu.js +134 -0
  11. package/dist/buffers/buffer.d.ts +15 -0
  12. package/dist/buffers/buffer.js +42 -0
  13. package/dist/buffers/webgl.d.ts +13 -0
  14. package/dist/buffers/webgl.js +46 -0
  15. package/dist/buffers/webgpu.d.ts +12 -0
  16. package/dist/buffers/webgpu.js +40 -0
  17. package/dist/buffers.d.ts +20 -7
  18. package/dist/buffers.js +54 -20
  19. package/dist/constants.d.ts +1 -0
  20. package/dist/constants.js +1 -0
  21. package/dist/geometry.d.ts +3 -2
  22. package/dist/geometry.js +8 -4
  23. package/dist/globals.d.ts +6 -7
  24. package/dist/globals.js +7 -12
  25. package/dist/graphics.d.ts +20 -21
  26. package/dist/graphics.js +57 -59
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.js +3 -1
  29. package/dist/internalUtils.d.ts +3 -4
  30. package/dist/internalUtils.js +3 -1
  31. package/dist/shaders/shader.d.ts +18 -0
  32. package/dist/shaders/shader.js +63 -0
  33. package/dist/shaders/utils.d.ts +33 -0
  34. package/dist/shaders/utils.js +25 -0
  35. package/dist/shaders/webgl.d.ts +74 -0
  36. package/dist/shaders/webgl.js +242 -0
  37. package/dist/shaders/webgpu.d.ts +40 -0
  38. package/dist/{shaders.js → shaders/webgpu.js} +73 -114
  39. package/dist/simulation.d.ts +11 -5
  40. package/dist/simulation.js +49 -86
  41. package/dist/types.d.ts +54 -36
  42. package/dist/utils.d.ts +3 -4
  43. package/dist/utils.js +6 -9
  44. package/package.json +26 -26
  45. package/pnpm-workspace.yaml +2 -0
  46. package/dist/pipelineUtil.d.ts +0 -5
  47. package/dist/pipelineUtil.js +0 -22
  48. package/dist/shaders.d.ts +0 -37
@@ -0,0 +1,242 @@
1
+ import { WebGLMemoBuffer } from '../buffers/webgl.js';
2
+ import { FLOAT_SIZE, mat4ByteLength } from '../constants.js';
3
+ import { globalInfo, logger } from '../globals.js';
4
+ import { orthogonalMatrix, worldProjectionMatrix } from '../simulation.js';
5
+ import { defaultVertexBufferWriter, defaultVertexColorBufferWriter, SimJSShader } from './shader.js';
6
+ export class SimJSWebGLShader extends SimJSShader {
7
+ buffers;
8
+ shaderProgram = null;
9
+ shaderProgramInfoLayout = null;
10
+ shaderProgramInfo = null;
11
+ gl = null;
12
+ uniformBufferWriter;
13
+ getShaderProgramInfoFn;
14
+ vertexSource;
15
+ fragmentSource;
16
+ bufferDeclerations;
17
+ constructor(vertexSource, fragmentSource, bufferDeclerations, uniformBufferWriter, vertexBufferWriter, getShaderProgramInfoFn) {
18
+ super('webgl', vertexBufferWriter);
19
+ this.buffers = [];
20
+ this.vertexSource = vertexSource;
21
+ this.fragmentSource = fragmentSource;
22
+ this.uniformBufferWriter = uniformBufferWriter;
23
+ this.getShaderProgramInfoFn = getShaderProgramInfoFn;
24
+ this.bufferDeclerations = bufferDeclerations;
25
+ const canvas = globalInfo.getCanvas();
26
+ if (!canvas) {
27
+ globalInfo.addToInitShader(this);
28
+ return;
29
+ }
30
+ const backend = canvas.getBackend().as('webgl');
31
+ this.init(backend.getContextOrError());
32
+ }
33
+ init(gl) {
34
+ this.gl = gl;
35
+ this.shaderProgram = this.initShaderProgram(gl, this.vertexSource, this.fragmentSource);
36
+ this.shaderProgramInfoLayout = this.getShaderProgramInfoFn();
37
+ this.shaderProgramInfo = this.programInfoLayoutToProgramInfo(this.shaderProgram, gl, this.shaderProgramInfoLayout);
38
+ for (const dec of this.bufferDeclerations) {
39
+ const buf = new WebGLMemoBuffer(this.gl, dec.target, dec.usage, dec.defaultCapacity ?? 0);
40
+ this.buffers.push(buf);
41
+ }
42
+ }
43
+ programInfoLayoutToProgramInfo(program, gl, layout) {
44
+ const res = {
45
+ program: program,
46
+ // @ts-ignore
47
+ attributeLocations: [],
48
+ // @ts-ignore
49
+ uniformLocations: []
50
+ };
51
+ let bufferLength = 0;
52
+ for (const obj of layout.attributeLocations) {
53
+ const key = Object.keys(obj)[0];
54
+ const size = obj[key];
55
+ const loc = gl.getAttribLocation(program, key);
56
+ const tuple = [key, loc];
57
+ // @ts-ignore
58
+ res.attributeLocations.push(tuple);
59
+ bufferLength += size;
60
+ }
61
+ this.bufferLength = bufferLength;
62
+ for (const obj of layout.uniformLocations) {
63
+ const key = Object.keys(obj)[0];
64
+ const loc = gl.getUniformLocation(program, key);
65
+ const tuple = [key, loc];
66
+ // @ts-ignore
67
+ res.uniformLocations.push(tuple);
68
+ }
69
+ return res;
70
+ }
71
+ initShaderProgram(gl, vertexShaderSource, fragmentShaderSource) {
72
+ const vertexShader = this.loadShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
73
+ const fragmentShader = this.loadShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
74
+ const shaderProgram = gl.createProgram();
75
+ if (!shaderProgram)
76
+ throw logger.error('Shader program init error');
77
+ gl.attachShader(shaderProgram, vertexShader);
78
+ gl.attachShader(shaderProgram, fragmentShader);
79
+ gl.linkProgram(shaderProgram);
80
+ if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
81
+ throw logger.error('Error initializing shader program');
82
+ }
83
+ return shaderProgram;
84
+ }
85
+ loadShader(ctx, shaderType, code) {
86
+ const shader = ctx.createShader(shaderType);
87
+ if (!shader)
88
+ throw logger.error('Error creating shader');
89
+ ctx.shaderSource(shader, code);
90
+ ctx.compileShader(shader);
91
+ if (!ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)) {
92
+ const err = logger.error(`Error compiling shaders: ${ctx.getShaderInfoLog(shader)}`);
93
+ ctx.deleteShader(shader);
94
+ throw err;
95
+ }
96
+ return shader;
97
+ }
98
+ getShaderProgram() {
99
+ if (!this.shaderProgram)
100
+ throw logger.error('Shader program not initialized');
101
+ return this.shaderProgram;
102
+ }
103
+ getShaderProgramInfo() {
104
+ if (!this.shaderProgramInfo)
105
+ throw logger.error('Shader program not initialized');
106
+ return this.shaderProgramInfo;
107
+ }
108
+ writeUniformBuffers(obj) {
109
+ if (!this.gl || !this.shaderProgramInfo)
110
+ throw logger.error('Shader not initialized');
111
+ this.uniformBufferWriter(this.shaderProgramInfo, this.gl, obj, this.buffers);
112
+ }
113
+ writeShaderProgramAttributes(buffer, vertexCallOffset, vertexCallBuffer) {
114
+ if (!this.gl || !this.shaderProgramInfoLayout || !this.shaderProgramInfo) {
115
+ throw logger.error('Shader not initialized');
116
+ }
117
+ const gl = this.gl;
118
+ buffer.write(vertexCallBuffer, vertexCallOffset);
119
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.getBuffer());
120
+ const STRIDE = this.bufferLength * FLOAT_SIZE;
121
+ let localOffset = 0;
122
+ for (let i = 0; i < this.shaderProgramInfo.attributeLocations.length; i++) {
123
+ const [key, loc] = this.shaderProgramInfo.attributeLocations[i];
124
+ const size = this.shaderProgramInfoLayout.attributeLocations[i][key];
125
+ gl.enableVertexAttribArray(loc);
126
+ gl.vertexAttribPointer(loc, size, gl.FLOAT, false, STRIDE, vertexCallOffset + localOffset);
127
+ localOffset += size * FLOAT_SIZE;
128
+ }
129
+ }
130
+ }
131
+ function defaultWebGLUniformBufferWriter(programInfo, gl, obj, _buffers) {
132
+ const projBuf = obj.is3d ? worldProjectionMatrix : orthogonalMatrix;
133
+ let buffer = obj.getUniformBuffer();
134
+ if (!buffer) {
135
+ buffer = new WebGLMemoBuffer(gl, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW, WEBGL_DEFAULT_SHADER_UNIFORM_BUFFER_SIZE);
136
+ obj.setUniformBuffer(buffer);
137
+ }
138
+ else {
139
+ buffer.as('webgl');
140
+ }
141
+ gl.uniformMatrix4fv(programInfo.uniformLocations[0][1], false, projBuf);
142
+ const modelMatrix = obj.getModelMatrix();
143
+ gl.uniformMatrix4fv(programInfo.uniformLocations[1][1], false, modelMatrix);
144
+ // gl.bindBuffer(gl.ARRAY_BUFFER, null);
145
+ // if (obj.isInstance) {
146
+ // buffers[0].write((obj as Instance<SimulationElement3d>).getInstanceBuffer());
147
+ // }
148
+ // gl.bindBuffer(gl.ARRAY_BUFFER, buffers[0].getBuffer());
149
+ // const mat4BaseLoc = programInfo.attributeLocations.instanceMatrix;
150
+ // const mat4Stride = 64;
151
+ // for (let i = 0; i < 4; i++) {
152
+ // const loc = mat4BaseLoc + i;
153
+ // const offset = i * 4 * FLOAT_SIZE;
154
+ // gl.enableVertexAttribArray(loc);
155
+ // gl.vertexAttribPointer(loc, 4, gl.FLOAT, false, mat4Stride, offset);
156
+ // gl.vertexAttribDivisor(loc, 1);
157
+ // }
158
+ // gl.bindBuffer(gl.ARRAY_BUFFER, null);
159
+ }
160
+ const defaultWebGLVertexShader = `#version 300 es
161
+
162
+ // uniforms
163
+ uniform mat4 worldProjectionMatrix;
164
+ uniform mat4 modelProjectionMatrix;
165
+
166
+ // attributes
167
+ layout(location = 0) in vec3 position;
168
+ layout(location = 1) in vec4 color;
169
+ layout(location = 2) in vec2 uv;
170
+ layout(location = 3) in float drawingInstance;
171
+
172
+ // consumes locations 4, 5, 6, 7
173
+ //layout(location = 4) in mat4 instanceMatrix;
174
+
175
+ out vec2 vFragUV;
176
+ out vec4 vFragColor;
177
+ out vec4 vFragPosition;
178
+
179
+ void main() {
180
+ vec4 finalPosition;
181
+ vec4 posInput = vec4(position, 1.0);
182
+
183
+ if (drawingInstance == 1.0) {
184
+ //finalPosition = worldProjectionMatrix * modelProjectionMatrix * instanceMatrix * posInput;
185
+ finalPosition = worldProjectionMatrix * modelProjectionMatrix * posInput;
186
+ } else {
187
+ finalPosition = worldProjectionMatrix * modelProjectionMatrix * posInput;
188
+ }
189
+
190
+ gl_Position = finalPosition;
191
+
192
+ vFragUV = uv;
193
+ vFragColor = color;
194
+ vFragPosition = finalPosition;
195
+ }
196
+ `;
197
+ const defaultWebGLFragmentShader = `#version 300 es
198
+ precision mediump float;
199
+
200
+ in vec2 vFragUV;
201
+ in vec4 vFragColor;
202
+ in vec4 vFragPosition;
203
+
204
+ layout(location = 0) out vec4 outColor;
205
+
206
+ void main() {
207
+ outColor = vFragColor;
208
+ }
209
+ `;
210
+ const WEBGL_DEFAULT_SHADER_UNIFORM_BUFFER_SIZE = mat4ByteLength * 2;
211
+ export const defaultWebGLShader = new SimJSWebGLShader(defaultWebGLVertexShader, defaultWebGLFragmentShader, [
212
+ // {
213
+ // target: WebGL2RenderingContext.ARRAY_BUFFER,
214
+ // usage: WebGL2RenderingContext.DYNAMIC_DRAW,
215
+ // defaultCapacity: 64
216
+ // }
217
+ ], defaultWebGLUniformBufferWriter, defaultVertexBufferWriter, () => ({
218
+ attributeLocations: [
219
+ { position: 3 },
220
+ { color: 4 },
221
+ { uv: 2 },
222
+ { drawingInstance: 1 }
223
+ // instanceMatrix: 16
224
+ ],
225
+ uniformLocations: [{ worldProjectionMatrix: 64 }, { modelProjectionMatrix: 64 }]
226
+ }));
227
+ export const defaultWebGLVertexColorShader = new SimJSWebGLShader(defaultWebGLVertexShader, defaultWebGLFragmentShader, [
228
+ // {
229
+ // target: WebGL2RenderingContext.ARRAY_BUFFER,
230
+ // usage: WebGL2RenderingContext.DYNAMIC_DRAW,
231
+ // defaultCapacity: 64
232
+ // }
233
+ ], defaultWebGLUniformBufferWriter, defaultVertexColorBufferWriter, () => ({
234
+ attributeLocations: [
235
+ { position: 3 },
236
+ { color: 4 },
237
+ { uv: 2 },
238
+ { drawingInstance: 1 }
239
+ // instanceMatrix: 16
240
+ ],
241
+ uniformLocations: [{ worldProjectionMatrix: 64 }, { modelProjectionMatrix: 64 }]
242
+ }));
@@ -0,0 +1,40 @@
1
+ import { WebGPUMemoBuffer } from '../buffers/webgpu.js';
2
+ import { SimulationElement3d } from '../graphics.js';
3
+ import { WebGPUBufferDecleration, Vector3, VertexBufferWriter, VertexParamInfo } from '../types.js';
4
+ import { SimJSShader } from './shader.js';
5
+ export declare const WEBGPU_DEFAULT_SHADER_UNIFORM_BUFFER_SIZE: number;
6
+ type WebGPUUniformBufferWriter = (device: GPUDevice, element: SimulationElement3d, buffers: WebGPUMemoBuffer[]) => void;
7
+ type WebGPUBindGroupGenerator = (device: GPUDevice, element: SimulationElement3d, buffers: WebGPUMemoBuffer[]) => GPUBindGroup[];
8
+ export declare class SimJSWebGPUShader extends SimJSShader {
9
+ protected buffers: WebGPUMemoBuffer[];
10
+ private bindGroupLayoutDescriptors;
11
+ private bindGroupLayouts;
12
+ private module;
13
+ private code;
14
+ private fragmentMain;
15
+ private vertexMain;
16
+ private vertexBuffers;
17
+ private uniformBufferWriter;
18
+ private bindGroupGenerator;
19
+ private bufferDeclerations;
20
+ private device;
21
+ constructor(code: string, descriptors: GPUBindGroupLayoutDescriptor[], vertexParams: VertexParamInfo[], bufferDeclerations: WebGPUBufferDecleration[], uniformBufferWriter: WebGPUUniformBufferWriter, bindGroupGenerator: WebGPUBindGroupGenerator, vertexBufferWriter: VertexBufferWriter, vertexMain?: string, fragmentMain?: string);
22
+ init(device: GPUDevice): void;
23
+ getCode(): string;
24
+ getVertexBuffers(): GPUVertexBufferLayout;
25
+ getBindGroupLayouts(): GPUBindGroupLayout[];
26
+ getBindGroupLayoutDescriptors(): GPUBindGroupLayoutDescriptor[];
27
+ getBufferInfo(): WebGPUBufferDecleration[];
28
+ getUniformBufferWriter(): WebGPUUniformBufferWriter;
29
+ getVertexBufferWriter(): VertexBufferWriter;
30
+ getBindGroupGenerator(): WebGPUBindGroupGenerator;
31
+ getModule(): GPUShaderModule;
32
+ getVertexMain(): string;
33
+ getFragmentMain(): string;
34
+ setVertexInfo(element: SimulationElement3d, buffer: Float32Array, vertex: Vector3, vertexIndex: number, offset: number): void;
35
+ writeUniformBuffers(el: SimulationElement3d): void;
36
+ getBindGroups(device: GPUDevice, el: SimulationElement3d): GPUBindGroup[];
37
+ }
38
+ export declare const defaultWebGPUShader: SimJSWebGPUShader;
39
+ export declare const defaultWebGPUVertexColorShader: SimJSWebGPUShader;
40
+ export {};
@@ -1,32 +1,44 @@
1
- import { MemoBuffer } from './buffers.js';
2
- import { mat4ByteLength } from './constants.js';
3
- import { globalInfo } from './globals.js';
4
- import { createBindGroup, writeUniformWorldMatrix } from './utils.js';
5
- export const uniformBufferSize = mat4ByteLength * 2 + 4 * 2 + 8; // 4x4 matrix * 2 + vec2<f32> + 8 bc 144 is cool
1
+ import { WebGPUMemoBuffer } from '../buffers/webgpu.js';
2
+ import { mat4ByteLength, modelProjMatOffset } from '../constants.js';
3
+ import { globalInfo, logger } from '../globals.js';
4
+ import { createBindGroup } from '../utils.js';
5
+ import { orthogonalMatrix, worldProjectionMatrix } from '../simulation.js';
6
+ import { worldProjMatOffset } from '../constants.js';
7
+ import { defaultVertexColorBufferWriter, SimJSShader } from './shader.js';
8
+ export const WEBGPU_DEFAULT_SHADER_UNIFORM_BUFFER_SIZE = mat4ByteLength * 2 + 4 * 2 + 8; // 4x4 matrix * 2 + vec2<f32> + 8 bc 144 is cool
6
9
  const defaultInfos = [
7
10
  {
8
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
9
- owned: false
10
- },
11
- {
12
- usage: GPUBufferUsage.STORAGE,
11
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
13
12
  defaultSize: 10 * 4 * 16 // not sure where this came from, made it up a while ago
14
13
  }
15
14
  ];
16
- const defaultBufferWriter = (el) => {
17
- writeUniformWorldMatrix(el);
18
- // not writing to buffer[0] because the buffer exists
19
- // on the element
15
+ const defaultWebGPUUniformBufferWriter = (device, el, buffers) => {
16
+ const projBuf = el.is3d ? worldProjectionMatrix : orthogonalMatrix;
17
+ let buffer = el.getUniformBuffer();
18
+ if (!buffer) {
19
+ buffer = new WebGPUMemoBuffer(device, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, WEBGPU_DEFAULT_SHADER_UNIFORM_BUFFER_SIZE);
20
+ el.setUniformBuffer(buffer);
21
+ }
22
+ device.queue.writeBuffer(buffer.getBuffer(), worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
23
+ const modelMatrix = el.getModelMatrix();
24
+ device.queue.writeBuffer(buffer.getBuffer(), modelProjMatOffset, modelMatrix.buffer, modelMatrix.byteOffset, modelMatrix.byteLength);
25
+ if (el.isInstance) {
26
+ buffers[0].write(el.getInstanceBuffer());
27
+ }
20
28
  };
21
- const defaultBindGroupGenerator = (el, buffers) => {
29
+ const defaultBindGroupGenerator = (_device, el, buffers) => {
30
+ // TODO - why is this here?
22
31
  const shader = el.getShader();
32
+ if (!shader.compatableWith('webgpu'))
33
+ throw logger.error('Wrong shader type for backend or something idk');
23
34
  const gpuBuffers = [
24
- el.getUniformBuffer(),
25
- el.isInstance ? el.getInstanceBuffer() : buffers[0].getBuffer()
35
+ el.getUniformBuffer().getBuffer(),
36
+ buffers[0].getBuffer()
26
37
  ];
27
38
  return [createBindGroup(shader, 0, gpuBuffers)];
28
39
  };
29
- export class Shader {
40
+ export class SimJSWebGPUShader extends SimJSShader {
41
+ buffers;
30
42
  bindGroupLayoutDescriptors;
31
43
  bindGroupLayouts;
32
44
  module;
@@ -34,29 +46,23 @@ export class Shader {
34
46
  fragmentMain;
35
47
  vertexMain;
36
48
  vertexBuffers;
37
- bufferLength;
38
- bufferWriter;
39
- vertexBufferWriter;
49
+ uniformBufferWriter;
40
50
  bindGroupGenerator;
41
- buffers;
42
- bufferInfos;
43
- constructor(code, descriptors, vertexParams, bufferInfos, bufferWriter, bindGroupGenerator, vertexBufferWriter, vertexMain = 'vertex_main', fragmentMain = 'fragment_main') {
51
+ bufferDeclerations;
52
+ device;
53
+ constructor(code, descriptors, vertexParams, bufferDeclerations, uniformBufferWriter, bindGroupGenerator, vertexBufferWriter, vertexMain = 'vertex_main', fragmentMain = 'fragment_main') {
54
+ super('webgpu', vertexBufferWriter);
55
+ this.buffers = [];
56
+ this.device = null;
44
57
  this.code = code;
45
58
  this.bindGroupLayoutDescriptors = descriptors;
46
59
  this.bindGroupLayouts = null;
47
60
  this.module = null;
48
- this.bufferWriter = bufferWriter;
49
- this.vertexBufferWriter = vertexBufferWriter;
61
+ this.uniformBufferWriter = uniformBufferWriter;
50
62
  this.bindGroupGenerator = bindGroupGenerator;
51
63
  this.vertexMain = vertexMain;
52
64
  this.fragmentMain = fragmentMain;
53
- this.bufferInfos = bufferInfos;
54
- this.buffers = [];
55
- for (let i = 0; i < bufferInfos.length; i++) {
56
- if (bufferInfos[i].owned === false)
57
- continue;
58
- this.buffers.push(new MemoBuffer(bufferInfos[i].usage, bufferInfos[i].defaultSize ?? 0));
59
- }
65
+ this.bufferDeclerations = bufferDeclerations;
60
66
  let stride = 0;
61
67
  const attributes = [];
62
68
  for (let i = 0; i < vertexParams.length; i++) {
@@ -72,18 +78,30 @@ export class Shader {
72
78
  arrayStride: stride,
73
79
  attributes
74
80
  };
81
+ const canvas = globalInfo.getCanvas();
82
+ if (!canvas) {
83
+ globalInfo.addToInitShader(this);
84
+ return;
85
+ }
86
+ const backend = canvas.getBackend().as('webgpu');
87
+ this.init(backend.getDeviceOrError());
88
+ }
89
+ init(device) {
90
+ this.device = device;
91
+ for (let i = 0; i < this.bufferDeclerations.length; i++) {
92
+ this.buffers.push(new WebGPUMemoBuffer(device, this.bufferDeclerations[i].usage, this.bufferDeclerations[i].defaultSize ?? 0));
93
+ }
75
94
  }
76
95
  getCode() {
77
96
  return this.code;
78
97
  }
79
- getBufferLength() {
80
- return this.bufferLength;
81
- }
82
98
  getVertexBuffers() {
83
99
  return this.vertexBuffers;
84
100
  }
85
101
  getBindGroupLayouts() {
86
- const device = globalInfo.errorGetDevice();
102
+ // TODO - probably change
103
+ const backend = globalInfo.errorGetCanvas().getBackend();
104
+ const device = backend.getDeviceOrError();
87
105
  if (!this.bindGroupLayouts) {
88
106
  this.bindGroupLayouts = this.bindGroupLayoutDescriptors.map((descriptor) => device.createBindGroupLayout(descriptor));
89
107
  }
@@ -93,10 +111,10 @@ export class Shader {
93
111
  return this.bindGroupLayoutDescriptors;
94
112
  }
95
113
  getBufferInfo() {
96
- return this.bufferInfos;
114
+ return this.bufferDeclerations;
97
115
  }
98
- getBufferWriter() {
99
- return this.bufferWriter;
116
+ getUniformBufferWriter() {
117
+ return this.uniformBufferWriter;
100
118
  }
101
119
  getVertexBufferWriter() {
102
120
  return this.vertexBufferWriter;
@@ -105,7 +123,9 @@ export class Shader {
105
123
  return this.bindGroupGenerator;
106
124
  }
107
125
  getModule() {
108
- const device = globalInfo.errorGetDevice();
126
+ // TODO - probably change
127
+ const backend = globalInfo.errorGetCanvas().getBackend();
128
+ const device = backend.getDeviceOrError();
109
129
  if (!this.module) {
110
130
  this.module = device.createShaderModule({ code: this.code });
111
131
  }
@@ -120,19 +140,20 @@ export class Shader {
120
140
  setVertexInfo(element, buffer, vertex, vertexIndex, offset) {
121
141
  this.vertexBufferWriter(element, buffer, vertex, vertexIndex, offset);
122
142
  }
123
- writeBuffers(el) {
124
- const device = globalInfo.errorGetDevice();
125
- this.bufferWriter(el, this.buffers, device);
143
+ writeUniformBuffers(el) {
144
+ if (!this.device)
145
+ throw logger.error('Shader not initialized');
146
+ this.uniformBufferWriter(this.device, el, this.buffers);
126
147
  }
127
- getBindGroups(el) {
128
- return this.bindGroupGenerator(el, this.buffers);
148
+ getBindGroups(device, el) {
149
+ return this.bindGroupGenerator(device, el, this.buffers);
129
150
  }
130
151
  }
131
152
  const positionSize = 4 * 3;
132
153
  const colorSize = 4 * 4;
133
154
  const uvSize = 4 * 2;
134
155
  const drawingInstancesSize = 4;
135
- export const defaultShader = new Shader(`struct Uniforms {
156
+ const defaultWebGPUShaderSource = `struct Uniforms {
136
157
  worldProjectionMatrix: mat4x4<f32>,
137
158
  modelProjectionMatrix: mat4x4<f32>,
138
159
  }
@@ -178,7 +199,8 @@ fn fragment_main(
178
199
  ) -> @location(0) vec4<f32> {
179
200
  return fragColor;
180
201
  }
181
- `, [
202
+ `;
203
+ export const defaultWebGPUShader = new SimJSWebGPUShader(defaultWebGPUShaderSource, [
182
204
  {
183
205
  entries: [
184
206
  {
@@ -214,7 +236,7 @@ fn fragment_main(
214
236
  size: drawingInstancesSize,
215
237
  format: 'float32'
216
238
  }
217
- ], defaultInfos, defaultBufferWriter, defaultBindGroupGenerator, (el, buffer, vertex, _, offset) => {
239
+ ], defaultInfos, defaultWebGPUUniformBufferWriter, defaultBindGroupGenerator, (el, buffer, vertex, _, offset) => {
218
240
  const material = el.getMaterial();
219
241
  const vertexColor = material.getColor();
220
242
  buffer[offset] = vertex[0];
@@ -229,54 +251,7 @@ fn fragment_main(
229
251
  buffer[offset + 8] = 0;
230
252
  buffer[offset + 9] = el.isInstanced ? 1 : 0;
231
253
  });
232
- export const vertexColorShader = new Shader(`
233
- struct Uniforms {
234
- worldProjectionMatrix: mat4x4<f32>,
235
- modelProjectionMatrix: mat4x4<f32>,
236
- }
237
-
238
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
239
-
240
- @group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
241
-
242
- struct VertexOutput {
243
- @builtin(position) Position: vec4<f32>,
244
- @location(0) fragUV: vec2<f32>,
245
- @location(1) fragColor: vec4<f32>,
246
- @location(2) fragPosition: vec4<f32>,
247
- }
248
-
249
- @vertex
250
- fn vertex_main(
251
- @builtin(instance_index) instanceIdx: u32,
252
- @location(0) position: vec3<f32>,
253
- @location(1) color: vec4<f32>,
254
- @location(2) uv: vec2<f32>,
255
- @location(3) drawingInstance: f32
256
- ) -> VertexOutput {
257
- var output: VertexOutput;
258
-
259
- if (drawingInstance == 1) {
260
- output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
261
- } else {
262
- output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * vec4(position, 1.0);
263
- }
264
-
265
- output.fragUV = uv;
266
- output.fragPosition = output.Position;
267
- output.fragColor = color;
268
- return output;
269
- }
270
-
271
- @fragment
272
- fn fragment_main(
273
- @location(0) fragUV: vec2<f32>,
274
- @location(1) fragColor: vec4<f32>,
275
- @location(2) fragPosition: vec4<f32>
276
- ) -> @location(0) vec4<f32> {
277
- return fragColor;
278
- }
279
- `, [
254
+ export const defaultWebGPUVertexColorShader = new SimJSWebGPUShader(defaultWebGPUShaderSource, [
280
255
  {
281
256
  entries: [
282
257
  {
@@ -312,20 +287,4 @@ fn fragment_main(
312
287
  size: drawingInstancesSize,
313
288
  format: 'float32'
314
289
  }
315
- ], defaultInfos, defaultBufferWriter, defaultBindGroupGenerator, (el, buffer, vertex, vertexIndex, offset) => {
316
- const material = el.getMaterial();
317
- const colors = material.getVertexColors();
318
- const vertexColor = colors[vertexIndex] ?? el.getColor();
319
- // const vertexColor = color(0, 255, 255);
320
- buffer[offset] = vertex[0];
321
- buffer[offset + 1] = vertex[1];
322
- buffer[offset + 2] = vertex[2];
323
- buffer[offset + 3] = vertexColor.r / 255;
324
- buffer[offset + 4] = vertexColor.g / 255;
325
- buffer[offset + 5] = vertexColor.b / 255;
326
- buffer[offset + 6] = vertexColor.a;
327
- // TODO possibly change uv for textures
328
- buffer[offset + 7] = 0;
329
- buffer[offset + 8] = 0;
330
- buffer[offset + 9] = el.isInstanced ? 1 : 0;
331
- });
290
+ ], defaultInfos, defaultWebGPUUniformBufferWriter, defaultBindGroupGenerator, defaultVertexColorBufferWriter);
@@ -1,7 +1,8 @@
1
1
  import { SimulationElement3d } from './graphics.js';
2
- import type { Vector2, Vector3, LerpFunc } from './types.js';
2
+ import type { Vector2, Vector3, LerpFunc, BackendType } from './types.js';
3
3
  import { Color } from './utils.js';
4
4
  import { Settings } from './settings.js';
5
+ import { SimJsBackend } from './backends/backend.js';
5
6
  export declare const worldProjectionMatrix: import("./types.js").Mat4;
6
7
  export declare const orthogonalMatrix: import("./types.js").Mat4;
7
8
  export declare class Camera {
@@ -24,9 +25,13 @@ export declare class Camera {
24
25
  getAspectRatio(): number;
25
26
  }
26
27
  export declare let camera: Camera;
28
+ type SimulationOptions = {
29
+ sceneCamera?: Camera | null;
30
+ showFrameRate?: boolean;
31
+ backendMode?: BackendType;
32
+ };
27
33
  export declare class Simulation extends Settings {
28
34
  canvasRef: HTMLCanvasElement | null;
29
- private bgColor;
30
35
  private scene;
31
36
  private fittingElement;
32
37
  private running;
@@ -34,12 +39,12 @@ export declare class Simulation extends Settings {
34
39
  private resizeEvents;
35
40
  private frameRateView;
36
41
  private transparentElements;
37
- private vertexBuffer;
38
- private indexBuffer;
39
- constructor(idOrCanvasRef: string | HTMLCanvasElement, sceneCamera?: Camera | null, showFrameRate?: boolean);
42
+ private backend;
43
+ constructor(idOrCanvasRef: string | HTMLCanvasElement, options?: SimulationOptions);
40
44
  private handleCanvasResize;
41
45
  on<K extends keyof HTMLElementEventMap>(event: K, cb: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
42
46
  onResize(cb: (width: number, height: number) => void): void;
47
+ getBackend(): SimJsBackend;
43
48
  getWidth(): number;
44
49
  getHeight(): number;
45
50
  add(el: SimulationElement3d, id?: string): void;
@@ -58,3 +63,4 @@ export declare class Simulation extends Settings {
58
63
  private renderScene;
59
64
  fitElement(): void;
60
65
  }
66
+ export {};