simulationjsv2 0.7.3 → 0.7.4
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 +1 -0
- package/dist/buffers.d.ts +11 -0
- package/dist/buffers.js +36 -0
- package/dist/graphics.d.ts +4 -3
- package/dist/graphics.js +49 -44
- package/dist/internalUtils.d.ts +21 -1
- package/dist/internalUtils.js +73 -3
- package/dist/materials.d.ts +3 -0
- package/dist/materials.js +3 -0
- package/dist/pipelines.d.ts +1 -0
- package/dist/pipelines.js +1 -0
- package/dist/shaders.d.ts +11 -0
- package/dist/shaders.js +89 -0
- package/dist/simulation.d.ts +2 -0
- package/dist/simulation.js +57 -141
- package/dist/types.d.ts +3 -2
- package/package.json +1 -1
package/TODO.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
- [ ] Make materials
|
|
4
4
|
- [ ] Move shader group to material
|
|
5
5
|
- [ ] Fix transparency
|
|
6
|
+
- [x] Change absolute pos function to pos function, and pos function to relative pos
|
|
6
7
|
- [x] Update `updateModelMatrix2d`
|
|
7
8
|
- [x] Trace line element (wireframe strip for tracing paths)
|
|
8
9
|
- [x] Test new transform things on 3d stuff
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="@webgpu/types" />
|
|
2
|
+
export declare class MemoBuffer {
|
|
3
|
+
private buffer;
|
|
4
|
+
private bufferSize;
|
|
5
|
+
private usage;
|
|
6
|
+
constructor(usage: GPUBufferDescriptor['usage'], size: number);
|
|
7
|
+
private allocBuffer;
|
|
8
|
+
getBuffer(): GPUBuffer;
|
|
9
|
+
setSize(size: number): void;
|
|
10
|
+
destroy(): void;
|
|
11
|
+
}
|
package/dist/buffers.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { globalInfo } from './internalUtils.js';
|
|
2
|
+
export class MemoBuffer {
|
|
3
|
+
buffer;
|
|
4
|
+
bufferSize;
|
|
5
|
+
usage;
|
|
6
|
+
constructor(usage, size) {
|
|
7
|
+
this.usage = usage;
|
|
8
|
+
this.bufferSize = size;
|
|
9
|
+
this.buffer = null;
|
|
10
|
+
}
|
|
11
|
+
allocBuffer() {
|
|
12
|
+
const device = globalInfo.getDevice();
|
|
13
|
+
if (!device)
|
|
14
|
+
return;
|
|
15
|
+
this.buffer = device.createBuffer({
|
|
16
|
+
size: this.bufferSize,
|
|
17
|
+
usage: this.usage
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getBuffer() {
|
|
21
|
+
if (!this.buffer)
|
|
22
|
+
this.allocBuffer();
|
|
23
|
+
return this.buffer;
|
|
24
|
+
}
|
|
25
|
+
setSize(size) {
|
|
26
|
+
if (!this.buffer)
|
|
27
|
+
this.allocBuffer();
|
|
28
|
+
if (size > this.bufferSize) {
|
|
29
|
+
this.bufferSize = size;
|
|
30
|
+
this.allocBuffer();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
destroy() {
|
|
34
|
+
this.buffer?.destroy();
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/graphics.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare abstract class SimulationElement3d {
|
|
|
35
35
|
setRotationOffset(offset: Vector3): void;
|
|
36
36
|
resetCenterOffset(): void;
|
|
37
37
|
getModelMatrix(): Mat4;
|
|
38
|
+
isTransparent(): boolean;
|
|
38
39
|
getUniformBuffer(mat: Mat4): GPUBuffer;
|
|
39
40
|
protected mirrorParentTransforms3d(mat: Mat4): void;
|
|
40
41
|
protected updateModelMatrix3d(): void;
|
|
@@ -44,8 +45,8 @@ export declare abstract class SimulationElement3d {
|
|
|
44
45
|
setWireframe(wireframe: boolean): void;
|
|
45
46
|
isWireframe(): boolean;
|
|
46
47
|
getColor(): Color;
|
|
48
|
+
getRelativePos(): Vector3;
|
|
47
49
|
getPos(): Vector3;
|
|
48
|
-
getAbsolutePos(): Vector3;
|
|
49
50
|
getRotation(): Vector3;
|
|
50
51
|
getCenterOffset(): Vector3;
|
|
51
52
|
fill(newColor: Color, t?: number, f?: LerpFunc): Promise<void>;
|
|
@@ -183,6 +184,7 @@ export declare class Spline2d extends SimulationElement2d {
|
|
|
183
184
|
private interpolateLimit;
|
|
184
185
|
private length;
|
|
185
186
|
constructor(pos: Vertex, points: SplinePoint2d[], thickness?: number, detail?: number);
|
|
187
|
+
isTransparent(): boolean;
|
|
186
188
|
private estimateLength;
|
|
187
189
|
getLength(): number;
|
|
188
190
|
setInterpolateStart(start: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
@@ -203,9 +205,8 @@ export declare class Instance<T extends AnySimulationElement> extends Simulation
|
|
|
203
205
|
private hasMapped;
|
|
204
206
|
isInstance: boolean;
|
|
205
207
|
constructor(obj: T, numInstances: number);
|
|
206
|
-
setNumInstances(numInstances: number): void;
|
|
208
|
+
setNumInstances(numInstances: number, forceResizeBuffer?: boolean): void;
|
|
207
209
|
setInstance(instance: number, transformation: Mat4): void;
|
|
208
|
-
private allocBuffer;
|
|
209
210
|
private mapBuffer;
|
|
210
211
|
getInstances(): Mat4[];
|
|
211
212
|
getNumInstances(): number;
|
package/dist/graphics.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Vertex, cloneBuf, color, colorFromVector4, vector2, vector3, vertex, Co
|
|
|
3
3
|
import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry, TraceLines2dGeometry as TraceLinesGeometry } from './geometry.js';
|
|
4
4
|
import { SimSceneObjInfo, VertexCache, bufferGenerator, globalInfo, internalTransitionValues, logger, posTo2dScreen, vector3ToPixelRatio } from './internalUtils.js';
|
|
5
5
|
import { mat4ByteLength, modelProjMatOffset } from './constants.js';
|
|
6
|
+
import { MemoBuffer } from './buffers.js';
|
|
6
7
|
export class SimulationElement3d {
|
|
7
8
|
children;
|
|
8
9
|
uniformBuffer;
|
|
@@ -23,6 +24,7 @@ export class SimulationElement3d {
|
|
|
23
24
|
* @param pos - Expected to be adjusted to devicePixelRatio before reaching constructor
|
|
24
25
|
*/
|
|
25
26
|
constructor(pos, rotation, color = new Color()) {
|
|
27
|
+
const uniformBufferSize = mat4ByteLength * 2 + 4 * 2 + 8; // 4x4 matrix * 2 + vec2<f32> + 8 bc 144 is cool
|
|
26
28
|
this.pos = pos;
|
|
27
29
|
this.centerOffset = vector3();
|
|
28
30
|
// TODO test this
|
|
@@ -31,7 +33,7 @@ export class SimulationElement3d {
|
|
|
31
33
|
this.vertexCache = new VertexCache();
|
|
32
34
|
this.wireframe = false;
|
|
33
35
|
this.rotation = cloneBuf(rotation);
|
|
34
|
-
this.uniformBuffer =
|
|
36
|
+
this.uniformBuffer = new MemoBuffer(GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, uniformBufferSize);
|
|
35
37
|
this.children = [];
|
|
36
38
|
this.modelMatrix = matrix4();
|
|
37
39
|
this.parent = null;
|
|
@@ -78,23 +80,20 @@ export class SimulationElement3d {
|
|
|
78
80
|
this.updateModelMatrix3d();
|
|
79
81
|
return this.modelMatrix;
|
|
80
82
|
}
|
|
83
|
+
isTransparent() {
|
|
84
|
+
return this.color.a < 1;
|
|
85
|
+
}
|
|
81
86
|
getUniformBuffer(mat) {
|
|
82
87
|
const device = globalInfo.errorGetDevice();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
size: uniformBufferSize,
|
|
87
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
device.queue.writeBuffer(this.uniformBuffer, modelProjMatOffset, mat);
|
|
91
|
-
return this.uniformBuffer;
|
|
88
|
+
const buffer = this.uniformBuffer.getBuffer();
|
|
89
|
+
device.queue.writeBuffer(buffer, modelProjMatOffset, mat);
|
|
90
|
+
return buffer;
|
|
92
91
|
}
|
|
93
92
|
mirrorParentTransforms3d(mat) {
|
|
94
93
|
if (!this.parent)
|
|
95
94
|
return;
|
|
96
95
|
this.parent.mirrorParentTransforms3d(mat);
|
|
97
|
-
mat4.translate(mat, this.parent.
|
|
96
|
+
mat4.translate(mat, this.parent.getRelativePos(), mat);
|
|
98
97
|
const parentRot = this.parent.getRotation();
|
|
99
98
|
mat4.rotateZ(mat, parentRot[2], mat);
|
|
100
99
|
mat4.rotateY(mat, parentRot[1], mat);
|
|
@@ -150,10 +149,10 @@ export class SimulationElement3d {
|
|
|
150
149
|
getColor() {
|
|
151
150
|
return this.color;
|
|
152
151
|
}
|
|
153
|
-
|
|
152
|
+
getRelativePos() {
|
|
154
153
|
return this.pos;
|
|
155
154
|
}
|
|
156
|
-
|
|
155
|
+
getPos() {
|
|
157
156
|
const vec = vector3();
|
|
158
157
|
this.updateModelMatrix3d();
|
|
159
158
|
mat4.getTranslation(this.modelMatrix, vec);
|
|
@@ -884,6 +883,17 @@ export class Spline2d extends SimulationElement2d {
|
|
|
884
883
|
this.geometry = new Spline2dGeometry(points, this.getColor(), this.thickness, this.detail);
|
|
885
884
|
this.estimateLength();
|
|
886
885
|
}
|
|
886
|
+
isTransparent() {
|
|
887
|
+
const curves = this.geometry.getCurves();
|
|
888
|
+
for (let i = 0; i < curves.length; i++) {
|
|
889
|
+
const colors = curves[i].getColors();
|
|
890
|
+
for (let j = 0; j < colors.length; j++) {
|
|
891
|
+
if (colors[j]?.a ?? 0 < 1)
|
|
892
|
+
return true;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return false;
|
|
896
|
+
}
|
|
887
897
|
estimateLength() {
|
|
888
898
|
this.length = 0;
|
|
889
899
|
const curves = this.geometry.getCurves();
|
|
@@ -927,7 +937,7 @@ export class Spline2d extends SimulationElement2d {
|
|
|
927
937
|
const clonePoint = newPoint.clone();
|
|
928
938
|
const start = clonePoint.getStart()?.getPos() || vector3();
|
|
929
939
|
const end = clonePoint.getEnd().getPos();
|
|
930
|
-
const pos = this.
|
|
940
|
+
const pos = this.getRelativePos();
|
|
931
941
|
vec3.sub(start, pos, start);
|
|
932
942
|
vec3.sub(end, pos, end);
|
|
933
943
|
this.geometry.updatePoint(pointIndex, clonePoint);
|
|
@@ -985,7 +995,7 @@ export class Instance extends SimulationElement3d {
|
|
|
985
995
|
super(vector3(), vector3());
|
|
986
996
|
// 32 matrices
|
|
987
997
|
this.maxInstances = 32;
|
|
988
|
-
this.matrixBuffer =
|
|
998
|
+
this.matrixBuffer = new MemoBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, this.maxInstances * mat4ByteLength);
|
|
989
999
|
obj.isInstanced = true;
|
|
990
1000
|
this.obj = obj;
|
|
991
1001
|
this.instanceMatrix = [];
|
|
@@ -998,12 +1008,12 @@ export class Instance extends SimulationElement3d {
|
|
|
998
1008
|
this.instanceMatrix.push(clone);
|
|
999
1009
|
}
|
|
1000
1010
|
}
|
|
1001
|
-
setNumInstances(numInstances) {
|
|
1011
|
+
setNumInstances(numInstances, forceResizeBuffer = false) {
|
|
1002
1012
|
if (numInstances < 0)
|
|
1003
1013
|
throw logger.error('Num instances is less than 0');
|
|
1004
|
-
if (numInstances > this.maxInstances) {
|
|
1014
|
+
if (numInstances > this.maxInstances || forceResizeBuffer) {
|
|
1005
1015
|
this.maxInstances = numInstances;
|
|
1006
|
-
this.
|
|
1016
|
+
this.matrixBuffer.setSize(numInstances * mat4ByteLength);
|
|
1007
1017
|
}
|
|
1008
1018
|
const oldLen = this.instanceMatrix.length;
|
|
1009
1019
|
if (numInstances < oldLen) {
|
|
@@ -1029,37 +1039,32 @@ export class Instance extends SimulationElement3d {
|
|
|
1029
1039
|
const device = globalInfo.getDevice();
|
|
1030
1040
|
if (!device)
|
|
1031
1041
|
return;
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
const size = Math.max(minSize, this.instanceMatrix.length);
|
|
1035
|
-
this.allocBuffer(size);
|
|
1036
|
-
}
|
|
1042
|
+
// this.allocBuffer(size);
|
|
1043
|
+
const gpuBuffer = this.matrixBuffer.getBuffer();
|
|
1037
1044
|
const buf = new Float32Array(transformation);
|
|
1038
|
-
device.queue.writeBuffer(
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
allocBuffer(size) {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1045
|
+
device.queue.writeBuffer(gpuBuffer, instance * mat4ByteLength, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1046
|
+
gpuBuffer.unmap();
|
|
1047
|
+
}
|
|
1048
|
+
// private allocBuffer(size: number) {
|
|
1049
|
+
// const device = globalInfo.getDevice();
|
|
1050
|
+
// if (!device) return;
|
|
1051
|
+
// const byteSize = size * mat4ByteLength;
|
|
1052
|
+
// this.matrixBuffer = device.createBuffer({
|
|
1053
|
+
// size: byteSize,
|
|
1054
|
+
// usage:
|
|
1055
|
+
// });
|
|
1056
|
+
// }
|
|
1051
1057
|
mapBuffer() {
|
|
1052
1058
|
const device = globalInfo.getDevice();
|
|
1053
1059
|
if (!device)
|
|
1054
1060
|
return;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
}
|
|
1061
|
+
const minSize = this.maxInstances * mat4ByteLength;
|
|
1062
|
+
const size = Math.max(minSize, this.instanceMatrix.length);
|
|
1063
|
+
this.matrixBuffer.setSize(size);
|
|
1064
|
+
const gpuBuffer = this.matrixBuffer.getBuffer();
|
|
1060
1065
|
const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
|
|
1061
|
-
device.queue.writeBuffer(
|
|
1062
|
-
|
|
1066
|
+
device.queue.writeBuffer(gpuBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1067
|
+
gpuBuffer.unmap();
|
|
1063
1068
|
this.hasMapped = true;
|
|
1064
1069
|
}
|
|
1065
1070
|
getInstances() {
|
|
@@ -1072,7 +1077,7 @@ export class Instance extends SimulationElement3d {
|
|
|
1072
1077
|
if (!this.hasMapped) {
|
|
1073
1078
|
this.mapBuffer();
|
|
1074
1079
|
}
|
|
1075
|
-
return this.matrixBuffer;
|
|
1080
|
+
return this.matrixBuffer.getBuffer();
|
|
1076
1081
|
}
|
|
1077
1082
|
getVertexCount() {
|
|
1078
1083
|
return this.obj.getVertexCount();
|
package/dist/internalUtils.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { VertexParamGeneratorInfo, Mat4, Vector2, Vector3, VertexParamInfo } from './types.js';
|
|
3
3
|
import { Color } from './utils.js';
|
|
4
4
|
import { SimulationElement3d } from './graphics.js';
|
|
5
|
+
import { Shader } from './shaders.js';
|
|
5
6
|
export declare class VertexCache {
|
|
6
7
|
private vertices;
|
|
7
8
|
private hasUpdated;
|
|
@@ -20,6 +21,15 @@ export declare class GlobalInfo {
|
|
|
20
21
|
getDevice(): GPUDevice | null;
|
|
21
22
|
}
|
|
22
23
|
export declare const globalInfo: GlobalInfo;
|
|
24
|
+
export declare class CachedArray<T> {
|
|
25
|
+
private length;
|
|
26
|
+
private data;
|
|
27
|
+
constructor();
|
|
28
|
+
add(index: T): void;
|
|
29
|
+
reset(): void;
|
|
30
|
+
clearCache(): void;
|
|
31
|
+
toArray(): T[];
|
|
32
|
+
}
|
|
23
33
|
export declare const updateProjectionMatrix: (mat: Mat4, aspectRatio: number, zNear?: number, zFar?: number) => any;
|
|
24
34
|
export declare const updateWorldProjectionMatrix: (worldProjMat: Mat4, projMat: Mat4) => void;
|
|
25
35
|
export declare const updateOrthoProjectionMatrix: (mat: Mat4, screenSize: [number, number]) => Float32Array;
|
|
@@ -65,11 +75,21 @@ declare class BufferGenerator {
|
|
|
65
75
|
export declare const bufferGenerator: BufferGenerator;
|
|
66
76
|
export declare function vector3ToPixelRatio(vec: Vector3): void;
|
|
67
77
|
export declare function vector2ToPixelRatio(vec: Vector2): void;
|
|
68
|
-
export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, topology: GPUPrimitiveTopology, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
|
|
78
|
+
export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, topology: GPUPrimitiveTopology, transparent: boolean, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
|
|
69
79
|
export declare function triangulateWireFrameOrder(len: number): number[];
|
|
70
80
|
export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
|
|
71
81
|
export declare function vectorCompAngle(a: number, b: number): number;
|
|
72
82
|
export declare function angleBetween(pos1: Vector3, pos2: Vector3): Vector3;
|
|
73
83
|
export declare function internalTransitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
|
|
74
84
|
export declare function posTo2dScreen(pos: Vector3): Vector3;
|
|
85
|
+
export declare function createShaderModule(shader: Shader): GPUShaderModule;
|
|
86
|
+
export declare function createDefaultPipelines(shader: Shader): {
|
|
87
|
+
triangleList: GPURenderPipeline;
|
|
88
|
+
triangleStrip: GPURenderPipeline;
|
|
89
|
+
lineStrip: GPURenderPipeline;
|
|
90
|
+
triangleListTransparent: GPURenderPipeline;
|
|
91
|
+
triangleStripTransparent: GPURenderPipeline;
|
|
92
|
+
lineStripTransparent: GPURenderPipeline;
|
|
93
|
+
};
|
|
94
|
+
export default function createUniformBindGroup(shader: Shader, buffers: GPUBuffer[]): GPUBindGroup;
|
|
75
95
|
export {};
|
package/dist/internalUtils.js
CHANGED
|
@@ -44,6 +44,33 @@ export class GlobalInfo {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
export const globalInfo = new GlobalInfo();
|
|
47
|
+
export class CachedArray {
|
|
48
|
+
length;
|
|
49
|
+
data;
|
|
50
|
+
constructor() {
|
|
51
|
+
this.length = 0;
|
|
52
|
+
this.data = [];
|
|
53
|
+
}
|
|
54
|
+
add(index) {
|
|
55
|
+
if (this.length < this.data.length) {
|
|
56
|
+
this.data[this.length - 1] = index;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
this.data.push(index);
|
|
60
|
+
}
|
|
61
|
+
this.length++;
|
|
62
|
+
}
|
|
63
|
+
reset() {
|
|
64
|
+
this.length = 0;
|
|
65
|
+
}
|
|
66
|
+
clearCache() {
|
|
67
|
+
this.reset();
|
|
68
|
+
this.data = [];
|
|
69
|
+
}
|
|
70
|
+
toArray() {
|
|
71
|
+
return this.data.slice(0, this.length);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
47
74
|
export const updateProjectionMatrix = (mat, aspectRatio, zNear = 1, zFar = 500) => {
|
|
48
75
|
const fov = Math.PI / 4;
|
|
49
76
|
return mat4.perspective(fov, aspectRatio, zNear, zFar, mat);
|
|
@@ -219,7 +246,7 @@ export function vector2ToPixelRatio(vec) {
|
|
|
219
246
|
vec[0] *= devicePixelRatio;
|
|
220
247
|
vec[1] *= devicePixelRatio;
|
|
221
248
|
}
|
|
222
|
-
export function createPipeline(device, module, bindGroupLayouts, presentationFormat, topology, vertexParams) {
|
|
249
|
+
export function createPipeline(device, module, bindGroupLayouts, presentationFormat, topology, transparent, vertexParams) {
|
|
223
250
|
let params = [
|
|
224
251
|
{
|
|
225
252
|
// position
|
|
@@ -279,7 +306,17 @@ export function createPipeline(device, module, bindGroupLayouts, presentationFor
|
|
|
279
306
|
entryPoint: 'fragment_main',
|
|
280
307
|
targets: [
|
|
281
308
|
{
|
|
282
|
-
format: presentationFormat
|
|
309
|
+
format: presentationFormat,
|
|
310
|
+
blend: {
|
|
311
|
+
color: {
|
|
312
|
+
srcFactor: 'src-alpha',
|
|
313
|
+
dstFactor: 'one-minus-src-alpha'
|
|
314
|
+
},
|
|
315
|
+
alpha: {
|
|
316
|
+
srcFactor: 'src-alpha',
|
|
317
|
+
dstFactor: 'one-minus-src-alpha'
|
|
318
|
+
}
|
|
319
|
+
}
|
|
283
320
|
}
|
|
284
321
|
]
|
|
285
322
|
},
|
|
@@ -290,7 +327,7 @@ export function createPipeline(device, module, bindGroupLayouts, presentationFor
|
|
|
290
327
|
count: 4
|
|
291
328
|
},
|
|
292
329
|
depthStencil: {
|
|
293
|
-
depthWriteEnabled:
|
|
330
|
+
depthWriteEnabled: !transparent,
|
|
294
331
|
depthCompare: 'less',
|
|
295
332
|
format: 'depth24plus'
|
|
296
333
|
}
|
|
@@ -346,3 +383,36 @@ export function posTo2dScreen(pos) {
|
|
|
346
383
|
newPos[1] = camera.getScreenSize()[1] + newPos[1];
|
|
347
384
|
return newPos;
|
|
348
385
|
}
|
|
386
|
+
export function createShaderModule(shader) {
|
|
387
|
+
const device = globalInfo.errorGetDevice();
|
|
388
|
+
return device.createShaderModule({
|
|
389
|
+
code: shader.getCode()
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
export function createDefaultPipelines(shader) {
|
|
393
|
+
const device = globalInfo.errorGetDevice();
|
|
394
|
+
const bindGroupLayout = device.createBindGroupLayout(shader.getBindGroupLayoutDescriptor());
|
|
395
|
+
const shaderModule = createShaderModule(shader);
|
|
396
|
+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
397
|
+
return {
|
|
398
|
+
triangleList: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list', false),
|
|
399
|
+
triangleStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip', false),
|
|
400
|
+
lineStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip', false),
|
|
401
|
+
triangleListTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list', true),
|
|
402
|
+
triangleStripTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip', true),
|
|
403
|
+
lineStripTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip', true)
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
export default function createUniformBindGroup(shader, buffers) {
|
|
407
|
+
const device = globalInfo.errorGetDevice();
|
|
408
|
+
const bindGroupLayout = shader.getBindGroupLayout();
|
|
409
|
+
return device.createBindGroup({
|
|
410
|
+
layout: bindGroupLayout,
|
|
411
|
+
entries: buffers.map((buffer, index) => ({
|
|
412
|
+
binding: index,
|
|
413
|
+
resource: {
|
|
414
|
+
buffer
|
|
415
|
+
}
|
|
416
|
+
}))
|
|
417
|
+
});
|
|
418
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="@webgpu/types" />
|
|
2
|
+
export declare class Shader {
|
|
3
|
+
private bindGroupLayoutDescriptor;
|
|
4
|
+
private bindGroupLayout;
|
|
5
|
+
private code;
|
|
6
|
+
constructor(code: string, descriptor: GPUBindGroupLayoutDescriptor);
|
|
7
|
+
getCode(): string;
|
|
8
|
+
getBindGroupLayout(): GPUBindGroupLayout;
|
|
9
|
+
getBindGroupLayoutDescriptor(): GPUBindGroupLayoutDescriptor;
|
|
10
|
+
}
|
|
11
|
+
export declare const defaultShader: Shader;
|
package/dist/shaders.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { globalInfo } from './internalUtils.js';
|
|
2
|
+
export class Shader {
|
|
3
|
+
bindGroupLayoutDescriptor;
|
|
4
|
+
bindGroupLayout;
|
|
5
|
+
code;
|
|
6
|
+
constructor(code, descriptor) {
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.bindGroupLayoutDescriptor = descriptor;
|
|
9
|
+
this.bindGroupLayout = null;
|
|
10
|
+
}
|
|
11
|
+
getCode() {
|
|
12
|
+
return this.code;
|
|
13
|
+
}
|
|
14
|
+
getBindGroupLayout() {
|
|
15
|
+
const device = globalInfo.errorGetDevice();
|
|
16
|
+
if (!this.bindGroupLayout) {
|
|
17
|
+
this.bindGroupLayout = device.createBindGroupLayout(this.bindGroupLayoutDescriptor);
|
|
18
|
+
}
|
|
19
|
+
return this.bindGroupLayout;
|
|
20
|
+
}
|
|
21
|
+
getBindGroupLayoutDescriptor() {
|
|
22
|
+
return this.bindGroupLayoutDescriptor;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export const defaultShader = new Shader(`
|
|
26
|
+
struct Uniforms {
|
|
27
|
+
worldProjectionMatrix: mat4x4<f32>,
|
|
28
|
+
modelProjectionMatrix: mat4x4<f32>,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
32
|
+
|
|
33
|
+
@group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
|
|
34
|
+
|
|
35
|
+
struct VertexOutput {
|
|
36
|
+
@builtin(position) Position: vec4<f32>,
|
|
37
|
+
@location(0) fragUV: vec2<f32>,
|
|
38
|
+
@location(1) fragColor: vec4<f32>,
|
|
39
|
+
@location(2) fragPosition: vec4<f32>,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@vertex
|
|
43
|
+
fn vertex_main(
|
|
44
|
+
@builtin(instance_index) instanceIdx: u32,
|
|
45
|
+
@location(0) position: vec3<f32>,
|
|
46
|
+
@location(1) color: vec4<f32>,
|
|
47
|
+
@location(2) uv: vec2<f32>,
|
|
48
|
+
@location(3) drawingInstance: f32
|
|
49
|
+
) -> VertexOutput {
|
|
50
|
+
var output: VertexOutput;
|
|
51
|
+
|
|
52
|
+
if (drawingInstance == 1) {
|
|
53
|
+
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
|
|
54
|
+
} else {
|
|
55
|
+
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * vec4(position, 1.0);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
output.fragUV = uv;
|
|
59
|
+
output.fragPosition = output.Position;
|
|
60
|
+
output.fragColor = color;
|
|
61
|
+
return output;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@fragment
|
|
65
|
+
fn fragment_main(
|
|
66
|
+
@location(0) fragUV: vec2<f32>,
|
|
67
|
+
@location(1) fragColor: vec4<f32>,
|
|
68
|
+
@location(2) fragPosition: vec4<f32>
|
|
69
|
+
) -> @location(0) vec4<f32> {
|
|
70
|
+
return fragColor;
|
|
71
|
+
}
|
|
72
|
+
`, {
|
|
73
|
+
entries: [
|
|
74
|
+
{
|
|
75
|
+
binding: 0,
|
|
76
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
77
|
+
buffer: {
|
|
78
|
+
type: 'uniform'
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
binding: 1,
|
|
83
|
+
visibility: GPUShaderStage.VERTEX,
|
|
84
|
+
buffer: {
|
|
85
|
+
type: 'read-only-storage'
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
});
|
package/dist/simulation.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export declare class Simulation extends Settings {
|
|
|
35
35
|
private renderInfo;
|
|
36
36
|
private resizeEvents;
|
|
37
37
|
private frameRateView;
|
|
38
|
+
private transparentElements;
|
|
39
|
+
private vertexBuffer;
|
|
38
40
|
constructor(idOrCanvasRef: string | HTMLCanvasElement, sceneCamera?: Camera | null, showFrameRate?: boolean);
|
|
39
41
|
private handleCanvasResize;
|
|
40
42
|
onResize(cb: (width: number, height: number) => void): void;
|
package/dist/simulation.js
CHANGED
|
@@ -3,56 +3,10 @@ import { EmptyElement, SimulationElement3d } from './graphics.js';
|
|
|
3
3
|
import { BUF_LEN, worldProjMatOffset } from './constants.js';
|
|
4
4
|
import { Color, matrix4, transitionValues, vector2, vector3 } from './utils.js';
|
|
5
5
|
import { BlankGeometry } from './geometry.js';
|
|
6
|
-
import { SimSceneObjInfo, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix, globalInfo } from './internalUtils.js';
|
|
6
|
+
import createUniformBindGroup, { SimSceneObjInfo, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix, globalInfo, CachedArray, createDefaultPipelines } from './internalUtils.js';
|
|
7
7
|
import { Settings } from './settings.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
worldProjectionMatrix: mat4x4<f32>,
|
|
11
|
-
modelProjectionMatrix: mat4x4<f32>,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
15
|
-
|
|
16
|
-
@group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
|
|
17
|
-
|
|
18
|
-
struct VertexOutput {
|
|
19
|
-
@builtin(position) Position: vec4<f32>,
|
|
20
|
-
@location(0) fragUV: vec2<f32>,
|
|
21
|
-
@location(1) fragColor: vec4<f32>,
|
|
22
|
-
@location(2) fragPosition: vec4<f32>,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@vertex
|
|
26
|
-
fn vertex_main(
|
|
27
|
-
@builtin(instance_index) instanceIdx: u32,
|
|
28
|
-
@location(0) position: vec3<f32>,
|
|
29
|
-
@location(1) color: vec4<f32>,
|
|
30
|
-
@location(2) uv: vec2<f32>,
|
|
31
|
-
@location(3) drawingInstance: f32
|
|
32
|
-
) -> VertexOutput {
|
|
33
|
-
var output: VertexOutput;
|
|
34
|
-
|
|
35
|
-
if (drawingInstance == 1) {
|
|
36
|
-
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
|
|
37
|
-
} else {
|
|
38
|
-
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * vec4(position, 1.0);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
output.fragUV = uv;
|
|
42
|
-
output.fragPosition = output.Position;
|
|
43
|
-
output.fragColor = color;
|
|
44
|
-
return output;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@fragment
|
|
48
|
-
fn fragment_main(
|
|
49
|
-
@location(0) fragUV: vec2<f32>,
|
|
50
|
-
@location(1) fragColor: vec4<f32>,
|
|
51
|
-
@location(2) fragPosition: vec4<f32>
|
|
52
|
-
) -> @location(0) vec4<f32> {
|
|
53
|
-
return fragColor;
|
|
54
|
-
}
|
|
55
|
-
`;
|
|
8
|
+
import { defaultShader } from './shaders.js';
|
|
9
|
+
import { MemoBuffer } from './buffers.js';
|
|
56
10
|
const simjsFrameRateCss = `.simjs-frame-rate {
|
|
57
11
|
position: absolute;
|
|
58
12
|
top: 0;
|
|
@@ -99,24 +53,6 @@ class FrameRateView {
|
|
|
99
53
|
}
|
|
100
54
|
}
|
|
101
55
|
}
|
|
102
|
-
const baseBindGroupLayout = {
|
|
103
|
-
entries: [
|
|
104
|
-
{
|
|
105
|
-
binding: 0,
|
|
106
|
-
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
107
|
-
buffer: {
|
|
108
|
-
type: 'uniform'
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
binding: 1,
|
|
113
|
-
visibility: GPUShaderStage.VERTEX,
|
|
114
|
-
buffer: {
|
|
115
|
-
type: 'read-only-storage'
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
};
|
|
120
56
|
let aspectRatio = 0;
|
|
121
57
|
const projMat = matrix4();
|
|
122
58
|
const worldProjMat = matrix4();
|
|
@@ -220,21 +156,21 @@ export class Simulation extends Settings {
|
|
|
220
156
|
renderInfo = null;
|
|
221
157
|
resizeEvents;
|
|
222
158
|
frameRateView;
|
|
159
|
+
transparentElements;
|
|
160
|
+
vertexBuffer;
|
|
223
161
|
constructor(idOrCanvasRef, sceneCamera = null, showFrameRate = false) {
|
|
224
162
|
super();
|
|
225
163
|
if (typeof idOrCanvasRef === 'string') {
|
|
226
164
|
const ref = document.getElementById(idOrCanvasRef);
|
|
227
|
-
if (ref
|
|
228
|
-
this.canvasRef = ref;
|
|
229
|
-
else
|
|
165
|
+
if (!ref)
|
|
230
166
|
throw logger.error(`Cannot find canvas with id ${idOrCanvasRef}`);
|
|
167
|
+
this.canvasRef = ref;
|
|
231
168
|
}
|
|
232
169
|
else if (idOrCanvasRef instanceof HTMLCanvasElement) {
|
|
233
170
|
this.canvasRef = idOrCanvasRef;
|
|
234
171
|
}
|
|
235
|
-
else
|
|
172
|
+
else
|
|
236
173
|
throw logger.error(`Canvas ref/id provided is invalid`);
|
|
237
|
-
}
|
|
238
174
|
const parent = this.canvasRef.parentElement;
|
|
239
175
|
if (sceneCamera) {
|
|
240
176
|
camera = sceneCamera;
|
|
@@ -247,6 +183,8 @@ export class Simulation extends Settings {
|
|
|
247
183
|
});
|
|
248
184
|
this.frameRateView = new FrameRateView(showFrameRate);
|
|
249
185
|
this.frameRateView.updateFrameRate(1);
|
|
186
|
+
this.transparentElements = new CachedArray();
|
|
187
|
+
this.vertexBuffer = new MemoBuffer(GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, 0);
|
|
250
188
|
}
|
|
251
189
|
handleCanvasResize(parent) {
|
|
252
190
|
if (this.fittingElement) {
|
|
@@ -325,13 +263,26 @@ export class Simulation extends Settings {
|
|
|
325
263
|
throw logger.error('Context is null');
|
|
326
264
|
const device = await adapter.requestDevice();
|
|
327
265
|
globalInfo.setDevice(device);
|
|
266
|
+
const screenSize = vector2(this.canvasRef.width, this.canvasRef.height);
|
|
267
|
+
camera.setScreenSize(screenSize);
|
|
268
|
+
const canvas = this.canvasRef;
|
|
269
|
+
canvas.width = canvas.clientWidth * devicePixelRatio;
|
|
270
|
+
canvas.height = canvas.clientHeight * devicePixelRatio;
|
|
271
|
+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
328
272
|
ctx.configure({
|
|
329
273
|
device,
|
|
330
|
-
format:
|
|
274
|
+
format: presentationFormat,
|
|
275
|
+
alphaMode: 'opaque'
|
|
331
276
|
});
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
277
|
+
this.pipelines = createDefaultPipelines(defaultShader);
|
|
278
|
+
const instanceBuffer = device.createBuffer({
|
|
279
|
+
size: 10 * 4 * 16,
|
|
280
|
+
usage: GPUBufferUsage.STORAGE
|
|
281
|
+
});
|
|
282
|
+
this.renderInfo = {
|
|
283
|
+
instanceBuffer
|
|
284
|
+
};
|
|
285
|
+
this.render(device, ctx, canvas);
|
|
335
286
|
})();
|
|
336
287
|
}
|
|
337
288
|
stop() {
|
|
@@ -346,35 +297,7 @@ export class Simulation extends Settings {
|
|
|
346
297
|
getSceneObjects() {
|
|
347
298
|
return this.scene.map((item) => item.getObj());
|
|
348
299
|
}
|
|
349
|
-
render(ctx) {
|
|
350
|
-
const device = globalInfo.getDevice();
|
|
351
|
-
if (this.canvasRef === null || device === null)
|
|
352
|
-
return;
|
|
353
|
-
const canvas = this.canvasRef;
|
|
354
|
-
canvas.width = canvas.clientWidth * devicePixelRatio;
|
|
355
|
-
canvas.height = canvas.clientHeight * devicePixelRatio;
|
|
356
|
-
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
357
|
-
const shaderModule = device.createShaderModule({ code: shader });
|
|
358
|
-
ctx.configure({
|
|
359
|
-
device,
|
|
360
|
-
format: presentationFormat,
|
|
361
|
-
alphaMode: 'premultiplied'
|
|
362
|
-
});
|
|
363
|
-
const instanceBuffer = device.createBuffer({
|
|
364
|
-
size: 10 * 4 * 16,
|
|
365
|
-
usage: GPUBufferUsage.STORAGE
|
|
366
|
-
});
|
|
367
|
-
const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
|
|
368
|
-
this.renderInfo = {
|
|
369
|
-
bindGroupLayout,
|
|
370
|
-
instanceBuffer,
|
|
371
|
-
vertexBuffer: null
|
|
372
|
-
};
|
|
373
|
-
this.pipelines = {
|
|
374
|
-
triangleList: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list'),
|
|
375
|
-
triangleStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip'),
|
|
376
|
-
lineStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip')
|
|
377
|
-
};
|
|
300
|
+
render(device, ctx, canvas) {
|
|
378
301
|
const colorAttachment = {
|
|
379
302
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
380
303
|
// @ts-ignore
|
|
@@ -414,12 +337,10 @@ export class Simulation extends Settings {
|
|
|
414
337
|
const diff = Math.max(now - prev, 1);
|
|
415
338
|
prev = now;
|
|
416
339
|
const fps = 1000 / diff;
|
|
417
|
-
if (
|
|
340
|
+
if (this.frameRateView.isActive() && fps === prevFps) {
|
|
418
341
|
this.frameRateView.updateFrameRate(fps);
|
|
419
342
|
}
|
|
420
343
|
prevFps = fps;
|
|
421
|
-
canvas.width = canvas.clientWidth * devicePixelRatio;
|
|
422
|
-
canvas.height = canvas.clientHeight * devicePixelRatio;
|
|
423
344
|
const screenSize = camera.getScreenSize();
|
|
424
345
|
if (screenSize[0] !== canvas.width || screenSize[1] !== canvas.height) {
|
|
425
346
|
camera.setScreenSize(vector2(canvas.width, canvas.height));
|
|
@@ -444,23 +365,18 @@ export class Simulation extends Settings {
|
|
|
444
365
|
}
|
|
445
366
|
const commandEncoder = device.createCommandEncoder();
|
|
446
367
|
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
447
|
-
passEncoder.setPipeline(this.pipelines.triangleList);
|
|
448
368
|
const totalVertices = getTotalVertices(this.scene);
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
this.renderScene(device, passEncoder, this.renderInfo.vertexBuffer, this.scene, 0, diff);
|
|
369
|
+
this.vertexBuffer.setSize(totalVertices * 4 * BUF_LEN);
|
|
370
|
+
this.transparentElements.reset();
|
|
371
|
+
const opaqueOffset = this.renderScene(device, passEncoder, this.vertexBuffer.getBuffer(), this.scene, 0, diff, false);
|
|
372
|
+
this.renderScene(device, passEncoder, this.vertexBuffer.getBuffer(), this.transparentElements.toArray(), opaqueOffset, diff, true);
|
|
457
373
|
camera.updateConsumed();
|
|
458
374
|
passEncoder.end();
|
|
459
375
|
device.queue.submit([commandEncoder.finish()]);
|
|
460
376
|
};
|
|
461
377
|
requestAnimationFrame(frame);
|
|
462
378
|
}
|
|
463
|
-
renderScene(device, passEncoder, vertexBuffer, scene, startOffset, diff, shaderInfo) {
|
|
379
|
+
renderScene(device, passEncoder, vertexBuffer, scene, startOffset, diff, transparent, shaderInfo) {
|
|
464
380
|
if (this.pipelines === null)
|
|
465
381
|
return 0;
|
|
466
382
|
let currentOffset = startOffset;
|
|
@@ -476,6 +392,10 @@ export class Simulation extends Settings {
|
|
|
476
392
|
scene[i].traverseLife(diff);
|
|
477
393
|
}
|
|
478
394
|
const obj = scene[i].getObj();
|
|
395
|
+
if (!transparent && obj.isTransparent()) {
|
|
396
|
+
this.transparentElements.add(scene[i]);
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
479
399
|
if (obj.hasChildren()) {
|
|
480
400
|
let shaderInfo = undefined;
|
|
481
401
|
if (obj instanceof ShaderGroup) {
|
|
@@ -493,7 +413,7 @@ export class Simulation extends Settings {
|
|
|
493
413
|
};
|
|
494
414
|
}
|
|
495
415
|
}
|
|
496
|
-
currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getChildrenInfos(), currentOffset, diff, shaderInfo);
|
|
416
|
+
currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getChildrenInfos(), currentOffset, diff, transparent, shaderInfo);
|
|
497
417
|
}
|
|
498
418
|
if (obj.isEmpty)
|
|
499
419
|
continue;
|
|
@@ -511,15 +431,25 @@ export class Simulation extends Settings {
|
|
|
511
431
|
passEncoder.setPipeline(shaderInfo.pipeline);
|
|
512
432
|
}
|
|
513
433
|
else if (obj.isWireframe()) {
|
|
514
|
-
|
|
434
|
+
if (obj.isTransparent())
|
|
435
|
+
passEncoder.setPipeline(this.pipelines.lineStripTransparent);
|
|
436
|
+
else
|
|
437
|
+
passEncoder.setPipeline(this.pipelines.lineStrip);
|
|
515
438
|
}
|
|
516
439
|
else {
|
|
517
440
|
const type = obj.getGeometryType();
|
|
441
|
+
// must be exhaustive
|
|
518
442
|
if (type === 'strip') {
|
|
519
|
-
|
|
443
|
+
if (obj.isTransparent())
|
|
444
|
+
passEncoder.setPipeline(this.pipelines.triangleStripTransparent);
|
|
445
|
+
else
|
|
446
|
+
passEncoder.setPipeline(this.pipelines.triangleStrip);
|
|
520
447
|
}
|
|
521
448
|
else if (type === 'list') {
|
|
522
|
-
|
|
449
|
+
if (obj.isTransparent())
|
|
450
|
+
passEncoder.setPipeline(this.pipelines.triangleListTransparent);
|
|
451
|
+
else
|
|
452
|
+
passEncoder.setPipeline(this.pipelines.triangleList);
|
|
523
453
|
}
|
|
524
454
|
}
|
|
525
455
|
let instances = 1;
|
|
@@ -533,23 +463,7 @@ export class Simulation extends Settings {
|
|
|
533
463
|
else {
|
|
534
464
|
instanceBuffer = this.renderInfo.instanceBuffer;
|
|
535
465
|
}
|
|
536
|
-
const uniformBindGroup =
|
|
537
|
-
layout: this.renderInfo.bindGroupLayout,
|
|
538
|
-
entries: [
|
|
539
|
-
{
|
|
540
|
-
binding: 0,
|
|
541
|
-
resource: {
|
|
542
|
-
buffer: uniformBuffer
|
|
543
|
-
}
|
|
544
|
-
},
|
|
545
|
-
{
|
|
546
|
-
binding: 1,
|
|
547
|
-
resource: {
|
|
548
|
-
buffer: instanceBuffer
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
]
|
|
552
|
-
});
|
|
466
|
+
const uniformBindGroup = createUniformBindGroup(defaultShader, [uniformBuffer, instanceBuffer]);
|
|
553
467
|
passEncoder.setBindGroup(0, uniformBindGroup);
|
|
554
468
|
}
|
|
555
469
|
if (shaderInfo && shaderInfo.bufferInfo) {
|
|
@@ -623,7 +537,7 @@ export class ShaderGroup extends EmptyElement {
|
|
|
623
537
|
const device = globalInfo.errorGetDevice();
|
|
624
538
|
this.module = device.createShaderModule({ code: this.code });
|
|
625
539
|
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
626
|
-
const bindGroupLayout =
|
|
540
|
+
const bindGroupLayout = defaultShader.getBindGroupLayout();
|
|
627
541
|
const bindGroups = [bindGroupLayout];
|
|
628
542
|
if (this.bindGroup !== null) {
|
|
629
543
|
const entryValues = this.bindGroup.bindings.map((binding, index) => ({
|
|
@@ -636,7 +550,9 @@ export class ShaderGroup extends EmptyElement {
|
|
|
636
550
|
});
|
|
637
551
|
bindGroups.push(this.bindGroupLayout);
|
|
638
552
|
}
|
|
639
|
-
this.pipeline = createPipeline(device, this.module, bindGroups, presentationFormat, this.topology,
|
|
553
|
+
this.pipeline = createPipeline(device, this.module, bindGroups, presentationFormat, this.topology,
|
|
554
|
+
// TODO possibly make transparent materials
|
|
555
|
+
false, this.vertexParams);
|
|
640
556
|
}
|
|
641
557
|
getBindGroupLayout() {
|
|
642
558
|
return this.bindGroupLayout;
|
package/dist/types.d.ts
CHANGED
|
@@ -73,11 +73,12 @@ export type PipelineGroup = {
|
|
|
73
73
|
triangleList: GPURenderPipeline;
|
|
74
74
|
triangleStrip: GPURenderPipeline;
|
|
75
75
|
lineStrip: GPURenderPipeline;
|
|
76
|
+
triangleListTransparent: GPURenderPipeline;
|
|
77
|
+
triangleStripTransparent: GPURenderPipeline;
|
|
78
|
+
lineStripTransparent: GPURenderPipeline;
|
|
76
79
|
};
|
|
77
80
|
export type RenderInfo = {
|
|
78
81
|
instanceBuffer: GPUBuffer;
|
|
79
|
-
bindGroupLayout: GPUBindGroupLayout;
|
|
80
|
-
vertexBuffer: GPUBuffer | null;
|
|
81
82
|
};
|
|
82
83
|
export type VertexParamGeneratorInfo = {
|
|
83
84
|
bufferSize: number;
|