simulationjsv2 0.10.6 → 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.
- package/TODO.md +4 -20
- package/dist/backend.d.ts +38 -0
- package/dist/backend.js +127 -0
- package/dist/backends/backend.d.ts +22 -0
- package/dist/backends/backend.js +21 -0
- package/dist/backends/webgl.d.ts +19 -0
- package/dist/backends/webgl.js +112 -0
- package/dist/backends/webgpu.d.ts +25 -0
- package/dist/backends/webgpu.js +134 -0
- package/dist/buffers/buffer.d.ts +15 -0
- package/dist/buffers/buffer.js +42 -0
- package/dist/buffers/webgl.d.ts +13 -0
- package/dist/buffers/webgl.js +46 -0
- package/dist/buffers/webgpu.d.ts +12 -0
- package/dist/buffers/webgpu.js +40 -0
- package/dist/buffers.d.ts +20 -6
- package/dist/buffers.js +54 -20
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/geometry.d.ts +3 -2
- package/dist/geometry.js +8 -4
- package/dist/globals.d.ts +6 -6
- package/dist/globals.js +7 -12
- package/dist/graphics.d.ts +18 -18
- package/dist/graphics.js +57 -59
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/internalUtils.d.ts +2 -2
- package/dist/internalUtils.js +3 -1
- package/dist/shaders/shader.d.ts +18 -0
- package/dist/shaders/shader.js +63 -0
- package/dist/shaders/utils.d.ts +33 -0
- package/dist/shaders/utils.js +25 -0
- package/dist/shaders/webgl.d.ts +74 -0
- package/dist/shaders/webgl.js +242 -0
- package/dist/shaders/webgpu.d.ts +40 -0
- package/dist/{shaders.js → shaders/webgpu.js} +73 -114
- package/dist/simulation.d.ts +11 -5
- package/dist/simulation.js +49 -86
- package/dist/types.d.ts +54 -35
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +6 -9
- package/package.json +26 -26
- package/dist/pipelineUtil.d.ts +0 -5
- package/dist/pipelineUtil.js +0 -22
- package/dist/shaders.d.ts +0 -36
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ export * from './simulation.js';
|
|
|
2
2
|
export * from './graphics.js';
|
|
3
3
|
export * from './utils.js';
|
|
4
4
|
export * from './types.js';
|
|
5
|
-
export * from './shaders.js';
|
|
5
|
+
export * as webGPUShaderUtils from './shaders/webgpu.js';
|
|
6
6
|
export * from './materials.js';
|
|
7
7
|
export * from './constants.js';
|
|
8
|
+
export * from './backends/backend.js';
|
|
9
|
+
export * from './shaders/shader.js';
|
|
8
10
|
export { vec2, vec3, vec4, mat3, mat4, quat } from 'wgpu-matrix';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,9 @@ export * from './simulation.js';
|
|
|
2
2
|
export * from './graphics.js';
|
|
3
3
|
export * from './utils.js';
|
|
4
4
|
export * from './types.js';
|
|
5
|
-
export * from './shaders.js';
|
|
5
|
+
export * as webGPUShaderUtils from './shaders/webgpu.js';
|
|
6
6
|
export * from './materials.js';
|
|
7
7
|
export * from './constants.js';
|
|
8
|
+
export * from './backends/backend.js';
|
|
9
|
+
export * from './shaders/shader.js';
|
|
8
10
|
export { vec2, vec3, vec4, mat3, mat4, quat } from 'wgpu-matrix';
|
package/dist/internalUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Mat4, Vector3 } from './types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { SimJSWebGPUShader } from './shaders/webgpu.js';
|
|
3
3
|
import { SimulationElement3d } from './graphics.js';
|
|
4
4
|
export declare class Float32ArrayCache {
|
|
5
5
|
private vertices;
|
|
@@ -32,7 +32,7 @@ export declare function triangulateWireFrameOrder(len: number): number[];
|
|
|
32
32
|
export declare function getVertexAndIndexSize(scene: SimulationElement3d[]): readonly [number, number];
|
|
33
33
|
export declare function internalTransitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
|
|
34
34
|
export declare function posTo2dScreen(pos: Vector3): Vector3;
|
|
35
|
-
export declare function createPipeline(device: GPUDevice, info: string, shader:
|
|
35
|
+
export declare function createPipeline(device: GPUDevice, info: string, shader: SimJSWebGPUShader): GPURenderPipeline;
|
|
36
36
|
export declare function addToScene(scene: SimulationElement3d[], el: SimulationElement3d, id?: string): void;
|
|
37
37
|
export declare function removeSceneObj(scene: SimulationElement3d[], el: SimulationElement3d): void;
|
|
38
38
|
export declare function removeSceneId(scene: SimulationElement3d[], id: string): void;
|
package/dist/internalUtils.js
CHANGED
|
@@ -88,7 +88,7 @@ export const buildMultisampleTexture = (device, ctx, width, height) => {
|
|
|
88
88
|
sampleCount: 4
|
|
89
89
|
});
|
|
90
90
|
};
|
|
91
|
-
//
|
|
91
|
+
// optimized for speed, depending on orientation of vertices as input, shape may not be preserved
|
|
92
92
|
export function lossyTriangulate(vertices) {
|
|
93
93
|
const res = [];
|
|
94
94
|
let facingRight = true;
|
|
@@ -236,6 +236,7 @@ export function addToScene(scene, el, id) {
|
|
|
236
236
|
export function removeSceneObj(scene, el) {
|
|
237
237
|
for (let i = 0; i < scene.length; i++) {
|
|
238
238
|
if (scene[i] === el) {
|
|
239
|
+
scene[i].delete();
|
|
239
240
|
scene.splice(i, 1);
|
|
240
241
|
break;
|
|
241
242
|
}
|
|
@@ -244,6 +245,7 @@ export function removeSceneObj(scene, el) {
|
|
|
244
245
|
export function removeSceneId(scene, id) {
|
|
245
246
|
for (let i = 0; i < scene.length; i++) {
|
|
246
247
|
if (scene[i].getId() === id) {
|
|
248
|
+
scene[i].delete();
|
|
247
249
|
scene.splice(i, 1);
|
|
248
250
|
break;
|
|
249
251
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MemoBuffer } from '../buffers/buffer.js';
|
|
2
|
+
import { SimulationElement3d } from '../graphics.js';
|
|
3
|
+
import { BackendType, SpecificShaderType, Vector3, VertexBufferWriter } from '../types.js';
|
|
4
|
+
export declare abstract class SimJSShader {
|
|
5
|
+
protected abstract buffers: MemoBuffer[];
|
|
6
|
+
protected vertexBufferWriter: VertexBufferWriter;
|
|
7
|
+
protected compatableBackend: BackendType;
|
|
8
|
+
protected bufferLength: number;
|
|
9
|
+
constructor(conpatableBackend: BackendType, vertexBufferWriter: VertexBufferWriter);
|
|
10
|
+
abstract writeUniformBuffers(obj: SimulationElement3d): void;
|
|
11
|
+
setVertexInfo(element: SimulationElement3d, buffer: Float32Array, vertex: Vector3, vertexIndex: number, offset: number): void;
|
|
12
|
+
getCompatableBackend(): BackendType;
|
|
13
|
+
compatableWith(backendType: BackendType): boolean;
|
|
14
|
+
getBufferLength(): number;
|
|
15
|
+
as<T extends BackendType>(type: T): SpecificShaderType<T>;
|
|
16
|
+
}
|
|
17
|
+
export declare const defaultVertexBufferWriter: VertexBufferWriter;
|
|
18
|
+
export declare const defaultVertexColorBufferWriter: VertexBufferWriter;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { logger } from '../globals.js';
|
|
2
|
+
export class SimJSShader {
|
|
3
|
+
vertexBufferWriter;
|
|
4
|
+
compatableBackend;
|
|
5
|
+
bufferLength;
|
|
6
|
+
constructor(conpatableBackend, vertexBufferWriter) {
|
|
7
|
+
this.bufferLength = 0;
|
|
8
|
+
this.vertexBufferWriter = vertexBufferWriter;
|
|
9
|
+
this.compatableBackend = conpatableBackend;
|
|
10
|
+
}
|
|
11
|
+
setVertexInfo(element, buffer, vertex, vertexIndex, offset) {
|
|
12
|
+
this.vertexBufferWriter(element, buffer, vertex, vertexIndex, offset);
|
|
13
|
+
}
|
|
14
|
+
getCompatableBackend() {
|
|
15
|
+
return this.compatableBackend;
|
|
16
|
+
}
|
|
17
|
+
compatableWith(backendType) {
|
|
18
|
+
return this.compatableBackend === backendType;
|
|
19
|
+
}
|
|
20
|
+
// returns number of floats (4 bytes)
|
|
21
|
+
getBufferLength() {
|
|
22
|
+
return this.bufferLength;
|
|
23
|
+
}
|
|
24
|
+
as(type) {
|
|
25
|
+
if (this.compatableBackend !== type)
|
|
26
|
+
throw logger.error('Incompatible shader cast');
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const defaultVertexBufferWriter = (el, buffer, vertex, vertexIndex, offset) => {
|
|
31
|
+
const material = el.getMaterial();
|
|
32
|
+
const colors = material.getVertexColors();
|
|
33
|
+
const vertexColor = colors[vertexIndex] ?? el.getColor();
|
|
34
|
+
// const vertexColor = color(0, 255, 255);
|
|
35
|
+
buffer[offset] = vertex[0];
|
|
36
|
+
buffer[offset + 1] = vertex[1];
|
|
37
|
+
buffer[offset + 2] = vertex[2];
|
|
38
|
+
buffer[offset + 3] = vertexColor.r / 255;
|
|
39
|
+
buffer[offset + 4] = vertexColor.g / 255;
|
|
40
|
+
buffer[offset + 5] = vertexColor.b / 255;
|
|
41
|
+
buffer[offset + 6] = vertexColor.a;
|
|
42
|
+
// TODO possibly change uv for textures
|
|
43
|
+
buffer[offset + 7] = 0;
|
|
44
|
+
buffer[offset + 8] = 0;
|
|
45
|
+
buffer[offset + 9] = el.isInstanced ? 1 : 0;
|
|
46
|
+
};
|
|
47
|
+
export const defaultVertexColorBufferWriter = (el, buffer, vertex, vertexIndex, offset) => {
|
|
48
|
+
const material = el.getMaterial();
|
|
49
|
+
const colors = material.getVertexColors();
|
|
50
|
+
const vertexColor = colors[vertexIndex] ?? el.getColor();
|
|
51
|
+
// const vertexColor = color(0, 255, 255);
|
|
52
|
+
buffer[offset] = vertex[0];
|
|
53
|
+
buffer[offset + 1] = vertex[1];
|
|
54
|
+
buffer[offset + 2] = vertex[2];
|
|
55
|
+
buffer[offset + 3] = vertexColor.r / 255;
|
|
56
|
+
buffer[offset + 4] = vertexColor.g / 255;
|
|
57
|
+
buffer[offset + 5] = vertexColor.b / 255;
|
|
58
|
+
buffer[offset + 6] = vertexColor.a;
|
|
59
|
+
// TODO possibly change uv for textures
|
|
60
|
+
buffer[offset + 7] = 0;
|
|
61
|
+
buffer[offset + 8] = 0;
|
|
62
|
+
buffer[offset + 9] = el.isInstanced ? 1 : 0;
|
|
63
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BackendType } from '../types.js';
|
|
2
|
+
export declare function getDefaultShaderForBackend(backendType: BackendType): import("./webgpu.js").SimJSWebGPUShader | import("./webgl.js").SimJSWebGLShader<{
|
|
3
|
+
attributeLocations: [{
|
|
4
|
+
readonly position: 3;
|
|
5
|
+
}, {
|
|
6
|
+
readonly color: 4;
|
|
7
|
+
}, {
|
|
8
|
+
readonly uv: 2;
|
|
9
|
+
}, {
|
|
10
|
+
readonly drawingInstance: 1;
|
|
11
|
+
}];
|
|
12
|
+
uniformLocations: [{
|
|
13
|
+
readonly worldProjectionMatrix: 64;
|
|
14
|
+
}, {
|
|
15
|
+
readonly modelProjectionMatrix: 64;
|
|
16
|
+
}];
|
|
17
|
+
}>;
|
|
18
|
+
export declare function getDefaultVertexColorShaderForBackend(backendType: BackendType): import("./webgpu.js").SimJSWebGPUShader | import("./webgl.js").SimJSWebGLShader<{
|
|
19
|
+
attributeLocations: [{
|
|
20
|
+
readonly position: 3;
|
|
21
|
+
}, {
|
|
22
|
+
readonly color: 4;
|
|
23
|
+
}, {
|
|
24
|
+
readonly uv: 2;
|
|
25
|
+
}, {
|
|
26
|
+
readonly drawingInstance: 1;
|
|
27
|
+
}];
|
|
28
|
+
uniformLocations: [{
|
|
29
|
+
readonly worldProjectionMatrix: 64;
|
|
30
|
+
}, {
|
|
31
|
+
readonly modelProjectionMatrix: 64;
|
|
32
|
+
}];
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { logger } from '../globals.js';
|
|
2
|
+
import { defaultWebGLShader } from './webgl.js';
|
|
3
|
+
import { defaultWebGPUShader, defaultWebGPUVertexColorShader } from './webgpu.js';
|
|
4
|
+
export function getDefaultShaderForBackend(backendType) {
|
|
5
|
+
if (backendType === 'webgpu') {
|
|
6
|
+
return defaultWebGPUShader;
|
|
7
|
+
}
|
|
8
|
+
else if (backendType === 'webgl') {
|
|
9
|
+
return defaultWebGLShader;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
throw logger.error('Unknown backend');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function getDefaultVertexColorShaderForBackend(backendType) {
|
|
16
|
+
if (backendType === 'webgpu') {
|
|
17
|
+
return defaultWebGPUVertexColorShader;
|
|
18
|
+
}
|
|
19
|
+
else if (backendType === 'webgl') {
|
|
20
|
+
return defaultWebGLShader;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw logger.error('Unknown backend');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { WebGLMemoBuffer } from '../buffers/webgl.js';
|
|
2
|
+
import { SimulationElement3d } from '../graphics.js';
|
|
3
|
+
import { VertexBufferWriter, WebGLBufferDecleration } from '../types.js';
|
|
4
|
+
import { SimJSShader } from './shader.js';
|
|
5
|
+
type WebGLUniformBufferWriter<T> = (programInfo: T, gl: WebGL2RenderingContext, element: SimulationElement3d, buffers: WebGLMemoBuffer[]) => void;
|
|
6
|
+
type ProgramInfoLayout = {
|
|
7
|
+
attributeLocations: {
|
|
8
|
+
[key: string]: number;
|
|
9
|
+
}[];
|
|
10
|
+
uniformLocations: {
|
|
11
|
+
[key: string]: number;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
type ToTuple<T> = [keyof T, T[keyof T]];
|
|
15
|
+
type ToTupleList<T> = T extends [infer First, ...infer Rest] ? [ToTuple<First>, ...ToTupleList<Rest>] : [];
|
|
16
|
+
type ProgramInfoLayoutToInfo<T extends ProgramInfoLayout> = {
|
|
17
|
+
program: WebGLProgram;
|
|
18
|
+
attributeLocations: ToTupleList<T['attributeLocations']>;
|
|
19
|
+
uniformLocations: ToTupleList<T['uniformLocations']>;
|
|
20
|
+
};
|
|
21
|
+
export declare class SimJSWebGLShader<T extends ProgramInfoLayout> extends SimJSShader {
|
|
22
|
+
protected buffers: WebGLMemoBuffer[];
|
|
23
|
+
private shaderProgram;
|
|
24
|
+
private shaderProgramInfoLayout;
|
|
25
|
+
private shaderProgramInfo;
|
|
26
|
+
private gl;
|
|
27
|
+
private uniformBufferWriter;
|
|
28
|
+
private getShaderProgramInfoFn;
|
|
29
|
+
private vertexSource;
|
|
30
|
+
private fragmentSource;
|
|
31
|
+
private bufferDeclerations;
|
|
32
|
+
constructor(vertexSource: string, fragmentSource: string, bufferDeclerations: WebGLBufferDecleration[], uniformBufferWriter: WebGLUniformBufferWriter<ProgramInfoLayoutToInfo<T>>, vertexBufferWriter: VertexBufferWriter, getShaderProgramInfoFn: () => T);
|
|
33
|
+
init(gl: WebGL2RenderingContext): void;
|
|
34
|
+
programInfoLayoutToProgramInfo(program: WebGLProgram, gl: WebGL2RenderingContext, layout: T): ProgramInfoLayoutToInfo<T>;
|
|
35
|
+
private initShaderProgram;
|
|
36
|
+
private loadShader;
|
|
37
|
+
getShaderProgram(): WebGLProgram;
|
|
38
|
+
getShaderProgramInfo(): ProgramInfoLayoutToInfo<T>;
|
|
39
|
+
writeUniformBuffers(obj: SimulationElement3d): void;
|
|
40
|
+
writeShaderProgramAttributes(buffer: WebGLMemoBuffer, vertexCallOffset: number, vertexCallBuffer: Float32Array): void;
|
|
41
|
+
}
|
|
42
|
+
export declare const defaultWebGLShader: SimJSWebGLShader<{
|
|
43
|
+
attributeLocations: [{
|
|
44
|
+
readonly position: 3;
|
|
45
|
+
}, {
|
|
46
|
+
readonly color: 4;
|
|
47
|
+
}, {
|
|
48
|
+
readonly uv: 2;
|
|
49
|
+
}, {
|
|
50
|
+
readonly drawingInstance: 1;
|
|
51
|
+
}];
|
|
52
|
+
uniformLocations: [{
|
|
53
|
+
readonly worldProjectionMatrix: 64;
|
|
54
|
+
}, {
|
|
55
|
+
readonly modelProjectionMatrix: 64;
|
|
56
|
+
}];
|
|
57
|
+
}>;
|
|
58
|
+
export declare const defaultWebGLVertexColorShader: SimJSWebGLShader<{
|
|
59
|
+
attributeLocations: [{
|
|
60
|
+
readonly position: 3;
|
|
61
|
+
}, {
|
|
62
|
+
readonly color: 4;
|
|
63
|
+
}, {
|
|
64
|
+
readonly uv: 2;
|
|
65
|
+
}, {
|
|
66
|
+
readonly drawingInstance: 1;
|
|
67
|
+
}];
|
|
68
|
+
uniformLocations: [{
|
|
69
|
+
readonly worldProjectionMatrix: 64;
|
|
70
|
+
}, {
|
|
71
|
+
readonly modelProjectionMatrix: 64;
|
|
72
|
+
}];
|
|
73
|
+
}>;
|
|
74
|
+
export {};
|
|
@@ -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 {};
|