forked from webgpu/webgpu-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommon.ts
More file actions
116 lines (103 loc) · 2.96 KB
/
common.ts
File metadata and controls
116 lines (103 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { mat4, vec3 } from 'wgpu-matrix';
import commonWGSL from './common.wgsl';
/**
* Common holds the shared WGSL between the shaders, including the common uniform buffer.
*/
export default class Common {
/** The WGSL of the common shader */
readonly wgsl = commonWGSL;
/** The common uniform buffer bind group and layout */
readonly uniforms: {
bindGroupLayout: GPUBindGroupLayout;
bindGroup: GPUBindGroup;
};
private readonly device: GPUDevice;
private readonly uniformBuffer: GPUBuffer;
private frame = 0;
constructor(device: GPUDevice, quads: GPUBuffer) {
this.device = device;
this.uniformBuffer = device.createBuffer({
label: 'Common.uniformBuffer',
size:
0 + //
4 * 16 + // mvp
4 * 16 + // inv_mvp
4 * 4, // seed
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
});
const bindGroupLayout = device.createBindGroupLayout({
label: 'Common.bindGroupLayout',
entries: [
{
// common_uniforms
binding: 0,
visibility: GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE,
buffer: { type: 'uniform' },
},
{
// quads
binding: 1,
visibility: GPUShaderStage.COMPUTE,
buffer: { type: 'read-only-storage' },
},
],
});
const bindGroup = device.createBindGroup({
label: 'Common.bindGroup',
layout: bindGroupLayout,
entries: [
{
// common_uniforms
binding: 0,
resource: this.uniformBuffer,
},
{
// quads
binding: 1,
resource: quads,
},
],
});
this.uniforms = { bindGroupLayout, bindGroup };
}
/** Updates the uniform buffer data */
update(params: { rotateCamera: boolean; aspect: number }) {
const projectionMatrix = mat4.perspective(
(2 * Math.PI) / 8,
params.aspect,
0.5,
100
);
const viewRotation = params.rotateCamera ? this.frame / 1000 : 0;
const viewMatrix = mat4.lookAt(
vec3.fromValues(
Math.sin(viewRotation) * 15,
5,
Math.cos(viewRotation) * 15
),
vec3.fromValues(0, 5, 0),
vec3.fromValues(0, 1, 0)
);
const mvp = mat4.multiply(projectionMatrix, viewMatrix);
const invMVP = mat4.invert(mvp);
const uniformDataF32 = new Float32Array(this.uniformBuffer.size / 4);
const uniformDataU32 = new Uint32Array(uniformDataF32.buffer);
for (let i = 0; i < 16; i++) {
uniformDataF32[i] = mvp[i];
}
for (let i = 0; i < 16; i++) {
uniformDataF32[i + 16] = invMVP[i];
}
uniformDataU32[32] = 0xffffffff * Math.random();
uniformDataU32[33] = 0xffffffff * Math.random();
uniformDataU32[34] = 0xffffffff * Math.random();
this.device.queue.writeBuffer(
this.uniformBuffer,
0,
uniformDataF32.buffer,
uniformDataF32.byteOffset,
uniformDataF32.byteLength
);
this.frame++;
}
}