LordXido commited on
Commit
5ca276f
·
verified ·
1 Parent(s): 16d758a

Create world.js

Browse files
Files changed (1) hide show
  1. world.js +87 -0
world.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import wgsl from "./world.wgsl?raw";
2
+ import { createCompute } from "./gpu.js";
3
+
4
+ export class World {
5
+ constructor(canvas, gpu) {
6
+ this.ctx = canvas.getContext("2d");
7
+ this.gpu = gpu;
8
+ this.size = 1024;
9
+ this.time = 0;
10
+
11
+ this.field = new Float32Array(this.size);
12
+
13
+ if (gpu.mode === "gpu") {
14
+ this.initGPU();
15
+ }
16
+ }
17
+
18
+ async initGPU() {
19
+ const device = this.gpu.device;
20
+
21
+ this.buffer = device.createBuffer({
22
+ size: this.field.byteLength,
23
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
24
+ });
25
+
26
+ this.readback = device.createBuffer({
27
+ size: this.field.byteLength,
28
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
29
+ });
30
+
31
+ this.pipeline = await createCompute(device, wgsl);
32
+ }
33
+
34
+ update(dt) {
35
+ this.time += dt;
36
+
37
+ if (this.gpu.mode === "gpu") {
38
+ const device = this.gpu.device;
39
+ const encoder = device.createCommandEncoder();
40
+
41
+ const pass = encoder.beginComputePass();
42
+ pass.setPipeline(this.pipeline);
43
+ pass.setBindGroup(0, device.createBindGroup({
44
+ layout: this.pipeline.getBindGroupLayout(0),
45
+ entries: [{ binding: 0, resource: { buffer: this.buffer } }]
46
+ }));
47
+ pass.dispatchWorkgroups(Math.ceil(this.size / 64));
48
+ pass.end();
49
+
50
+ encoder.copyBufferToBuffer(this.buffer, 0, this.readback, 0, this.field.byteLength);
51
+ device.queue.submit([encoder.finish()]);
52
+ }
53
+ }
54
+
55
+ async render() {
56
+ if (this.gpu.mode === "gpu") {
57
+ await this.readback.mapAsync(GPUMapMode.READ);
58
+ new Float32Array(this.readback.getMappedRange()).set(this.field);
59
+ this.readback.unmap();
60
+ } else {
61
+ // CPU fallback
62
+ for (let i = 0; i < this.size; i++) {
63
+ this.field[i] = Math.sin(this.time + i * 0.01) * 0.5 + 0.5;
64
+ }
65
+ }
66
+
67
+ const w = this.ctx.canvas.width = this.ctx.canvas.clientWidth;
68
+ const h = this.ctx.canvas.height = this.ctx.canvas.clientHeight;
69
+
70
+ this.ctx.clearRect(0, 0, w, h);
71
+
72
+ for (let i = 0; i < this.size; i++) {
73
+ const x = (i / this.size) * w;
74
+ const y = h / 2;
75
+ const r = this.field[i] * 20;
76
+
77
+ this.ctx.fillStyle = "#00ffd0";
78
+ this.ctx.beginPath();
79
+ this.ctx.arc(x, y, r, 0, Math.PI * 2);
80
+ this.ctx.fill();
81
+ }
82
+ }
83
+
84
+ apply(cmd) {
85
+ // Language can modulate parameters here
86
+ }
87
+ }