forked from Rezmason/matrix
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmirrorPass.js
More file actions
106 lines (87 loc) · 2.87 KB
/
mirrorPass.js
File metadata and controls
106 lines (87 loc) · 2.87 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
import { structs } from "../../lib/gpu-buffer.js";
import { makeComputeTarget, makeUniformBuffer, loadShader, makeBindGroup, makePass } from "./utils.js";
export default ({ config, device, canvas, cameraTex, cameraAspectRatio, timeBuffer }) => {
const assets = [loadShader(device, "shaders/wgsl/mirrorPass.wgsl")];
const linearSampler = device.createSampler({
magFilter: "linear",
minFilter: "linear",
});
let start;
const numTouches = 5;
const touches = Array(numTouches)
.fill()
.map((_) => [0, 0, -Infinity, 0]);
let aspectRatio = 1;
let index = 0;
let touchesChanged = true;
canvas.onmousedown = (e) => {
const rect = e.srcElement.getBoundingClientRect();
touches[index][0] = 0 + (e.clientX - rect.x) / rect.width;
touches[index][1] = 1 - (e.clientY - rect.y) / rect.height;
touches[index][2] = (performance.now() - start) / 1000;
index = (index + 1) % numTouches;
touchesChanged = true;
};
let computePipeline;
let configBuffer;
let sceneUniforms;
let sceneBuffer;
let touchUniforms;
let touchBuffer;
let output;
let screenSize;
let computeBindGroup;
const loaded = (async () => {
const [mirrorShader] = await Promise.all(assets);
computePipeline = await device.createComputePipelineAsync({
layout: "auto",
compute: {
module: mirrorShader.module,
entryPoint: "computeMain",
},
});
const mirrorShaderUniforms = structs.from(mirrorShader.code);
const configUniforms = mirrorShaderUniforms.Config;
configBuffer = makeUniformBuffer(device, configUniforms, { unused: 0 });
sceneUniforms = mirrorShaderUniforms.Scene;
sceneBuffer = makeUniformBuffer(device, sceneUniforms);
touchUniforms = mirrorShaderUniforms.Touches;
touchBuffer = makeUniformBuffer(device, touchUniforms);
})();
const build = (size, inputs) => {
output?.destroy();
output = makeComputeTarget(device, size);
screenSize = size;
aspectRatio = size[0] / size[1];
computeBindGroup = makeBindGroup(device, computePipeline, 0, [
configBuffer,
timeBuffer,
sceneBuffer,
touchBuffer,
linearSampler,
inputs.primary.createView(),
inputs.bloom.createView(),
cameraTex.createView(),
output.createView(),
]);
const screenAspectRatio = size[0] / size[1];
device.queue.writeBuffer(sceneBuffer, 0, sceneUniforms.toBuffer({ screenAspectRatio, cameraAspectRatio }));
return { primary: output };
};
const run = (encoder, shouldRender) => {
if (!shouldRender) {
return;
}
if (touchesChanged) {
touchesChanged = false;
device.queue.writeBuffer(touchBuffer, 0, touchUniforms.toBuffer({ touches }));
}
const computePass = encoder.beginComputePass();
computePass.setPipeline(computePipeline);
computePass.setBindGroup(0, computeBindGroup);
computePass.dispatchWorkgroups(Math.ceil(screenSize[0] / 32), screenSize[1], 1);
computePass.end();
};
start = performance.now();
return makePass("Mirror", loaded, build, run);
};