LordXido commited on
Commit
f672c5a
·
verified ·
1 Parent(s): bc345be

Update world.js

Browse files
Files changed (1) hide show
  1. world.js +40 -29
world.js CHANGED
@@ -9,36 +9,37 @@ export class World {
9
 
10
  this.size = 512;
11
  this.time = 0;
 
12
  this.ready = false;
13
 
14
  this.field = new Float32Array(this.size);
15
 
16
- if (gpu.mode === "gpu") {
17
- this.initGPU();
18
- } else {
19
- this.ready = true;
20
- }
21
  }
22
 
23
  async initGPU() {
24
  try {
25
- const device = this.gpu.device;
26
 
27
- this.buffer = device.createBuffer({
28
  size: this.field.byteLength,
29
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
30
  });
31
 
32
- this.readback = device.createBuffer({
 
 
 
 
 
33
  size: this.field.byteLength,
34
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
35
  });
36
 
37
- this.pipeline = await createCompute(device, wgsl);
38
-
39
  this.ready = true;
40
- } catch (e) {
41
- console.warn("GPU init failed, falling back to CPU");
42
  this.gpu.mode = "cpu";
43
  this.ready = true;
44
  }
@@ -46,31 +47,34 @@ export class World {
46
 
47
  update(dt) {
48
  if (!this.ready) return;
49
-
50
  this.time += dt;
51
 
52
  if (this.gpu.mode === "gpu") {
53
- const device = this.gpu.device;
54
- const encoder = device.createCommandEncoder();
55
 
 
 
 
 
 
 
 
56
  const pass = encoder.beginComputePass();
 
57
  pass.setPipeline(this.pipeline);
58
- pass.setBindGroup(0, device.createBindGroup({
59
  layout: this.pipeline.getBindGroupLayout(0),
60
- entries: [{ binding: 0, resource: { buffer: this.buffer } }]
 
 
 
61
  }));
 
62
  pass.dispatchWorkgroups(Math.ceil(this.size / 64));
63
  pass.end();
64
 
65
- encoder.copyBufferToBuffer(
66
- this.buffer,
67
- 0,
68
- this.readback,
69
- 0,
70
- this.field.byteLength
71
- );
72
-
73
- device.queue.submit([encoder.finish()]);
74
  } else {
75
  for (let i = 0; i < this.size; i++) {
76
  this.field[i] = Math.sin(this.time + i * 0.02) * 0.5 + 0.5;
@@ -78,15 +82,20 @@ export class World {
78
  }
79
  }
80
 
81
- render() {
82
  if (!this.ready) return;
83
 
 
 
 
 
 
 
84
  const w = this.canvas.width = this.canvas.clientWidth;
85
  const h = this.canvas.height = this.canvas.clientHeight;
86
 
87
  this.ctx.fillStyle = "#000";
88
  this.ctx.fillRect(0, 0, w, h);
89
-
90
  this.ctx.fillStyle = "#00ffd0";
91
 
92
  for (let i = 0; i < this.size; i += 4) {
@@ -99,6 +108,8 @@ export class World {
99
  }
100
 
101
  apply(cmd) {
102
- // PLME hooks here
 
 
103
  }
104
  }
 
9
 
10
  this.size = 512;
11
  this.time = 0;
12
+ this.power = 8.0;
13
  this.ready = false;
14
 
15
  this.field = new Float32Array(this.size);
16
 
17
+ if (gpu.mode === "gpu") this.initGPU();
18
+ else this.ready = true;
 
 
 
19
  }
20
 
21
  async initGPU() {
22
  try {
23
+ const d = this.gpu.device;
24
 
25
+ this.buffer = d.createBuffer({
26
  size: this.field.byteLength,
27
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
28
  });
29
 
30
+ this.paramBuffer = d.createBuffer({
31
+ size: 8,
32
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
33
+ });
34
+
35
+ this.readback = d.createBuffer({
36
  size: this.field.byteLength,
37
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
38
  });
39
 
40
+ this.pipeline = createCompute(d, wgsl);
 
41
  this.ready = true;
42
+ } catch {
 
43
  this.gpu.mode = "cpu";
44
  this.ready = true;
45
  }
 
47
 
48
  update(dt) {
49
  if (!this.ready) return;
 
50
  this.time += dt;
51
 
52
  if (this.gpu.mode === "gpu") {
53
+ const d = this.gpu.device;
 
54
 
55
+ d.queue.writeBuffer(
56
+ this.paramBuffer,
57
+ 0,
58
+ new Float32Array([this.power, this.time])
59
+ );
60
+
61
+ const encoder = d.createCommandEncoder();
62
  const pass = encoder.beginComputePass();
63
+
64
  pass.setPipeline(this.pipeline);
65
+ pass.setBindGroup(0, d.createBindGroup({
66
  layout: this.pipeline.getBindGroupLayout(0),
67
+ entries: [
68
+ { binding: 0, resource: { buffer: this.buffer } },
69
+ { binding: 1, resource: { buffer: this.paramBuffer } }
70
+ ]
71
  }));
72
+
73
  pass.dispatchWorkgroups(Math.ceil(this.size / 64));
74
  pass.end();
75
 
76
+ encoder.copyBufferToBuffer(this.buffer, 0, this.readback, 0, this.field.byteLength);
77
+ d.queue.submit([encoder.finish()]);
 
 
 
 
 
 
 
78
  } else {
79
  for (let i = 0; i < this.size; i++) {
80
  this.field[i] = Math.sin(this.time + i * 0.02) * 0.5 + 0.5;
 
82
  }
83
  }
84
 
85
+ async render() {
86
  if (!this.ready) return;
87
 
88
+ if (this.gpu.mode === "gpu") {
89
+ await this.readback.mapAsync(GPUMapMode.READ);
90
+ this.field.set(new Float32Array(this.readback.getMappedRange()));
91
+ this.readback.unmap();
92
+ }
93
+
94
  const w = this.canvas.width = this.canvas.clientWidth;
95
  const h = this.canvas.height = this.canvas.clientHeight;
96
 
97
  this.ctx.fillStyle = "#000";
98
  this.ctx.fillRect(0, 0, w, h);
 
99
  this.ctx.fillStyle = "#00ffd0";
100
 
101
  for (let i = 0; i < this.size; i += 4) {
 
108
  }
109
 
110
  apply(cmd) {
111
+ if (cmd.lane === "world" && cmd.payload.power) {
112
+ this.power = cmd.payload.power;
113
+ }
114
  }
115
  }