LordXido commited on
Commit
4648f7d
·
verified ·
1 Parent(s): e31641a

Update world.js

Browse files
Files changed (1) hide show
  1. world.js +37 -62
world.js CHANGED
@@ -3,46 +3,41 @@ import { createCompute } from "./gpu.js";
3
 
4
  export class World {
5
  constructor(canvas, gpu) {
6
- this.canvas = canvas;
7
  this.ctx = canvas.getContext("2d");
8
  this.gpu = gpu;
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
- }
46
  }
47
 
48
  update(dt) {
@@ -51,60 +46,40 @@ export class World {
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;
81
- }
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) {
102
- const x = (i / this.size) * w;
103
- const r = this.field[i] * 18;
104
- this.ctx.beginPath();
105
- this.ctx.arc(x, h / 2, r, 0, Math.PI * 2);
106
- this.ctx.fill();
107
  }
 
 
 
108
  }
109
 
110
  apply(cmd) {
 
3
 
4
  export class World {
5
  constructor(canvas, gpu) {
 
6
  this.ctx = canvas.getContext("2d");
7
  this.gpu = gpu;
8
 
9
+ this.w = 256;
10
+ this.h = 256;
11
  this.time = 0;
12
  this.power = 8.0;
13
  this.ready = false;
14
 
15
+ this.image = this.ctx.createImageData(this.w, this.h);
16
 
17
  if (gpu.mode === "gpu") this.initGPU();
18
  else this.ready = true;
19
  }
20
 
21
  async initGPU() {
22
+ const d = this.gpu.device;
 
23
 
24
+ this.pixelBuffer = d.createBuffer({
25
+ size: this.w * this.h * 4 * 4,
26
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
27
+ });
28
+
29
+ this.readback = d.createBuffer({
30
+ size: this.w * this.h * 4 * 4,
31
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
32
+ });
33
+
34
+ this.paramBuffer = d.createBuffer({
35
+ size: 8,
36
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
37
+ });
38
+
39
+ this.pipeline = createCompute(d, wgsl);
40
+ this.ready = true;
 
 
 
 
41
  }
42
 
43
  update(dt) {
 
46
 
47
  if (this.gpu.mode === "gpu") {
48
  const d = this.gpu.device;
49
+ d.queue.writeBuffer(this.paramBuffer, 0, new Float32Array([this.time, this.power]));
50
 
51
+ const enc = d.createCommandEncoder();
52
+ const pass = enc.beginComputePass();
 
 
 
 
 
 
53
 
54
  pass.setPipeline(this.pipeline);
55
  pass.setBindGroup(0, d.createBindGroup({
56
  layout: this.pipeline.getBindGroupLayout(0),
57
  entries: [
58
+ { binding: 0, resource: { buffer: this.paramBuffer } },
59
+ { binding: 1, resource: { buffer: this.pixelBuffer } }
60
  ]
61
  }));
62
 
63
+ pass.dispatchWorkgroups(32, 32);
64
  pass.end();
65
 
66
+ enc.copyBufferToBuffer(this.pixelBuffer, 0, this.readback, 0, this.w * this.h * 4 * 4);
67
+ d.queue.submit([enc.finish()]);
 
 
 
 
68
  }
69
  }
70
 
71
  async render() {
72
+ if (!this.ready || this.gpu.mode !== "gpu") return;
 
 
 
 
 
 
 
 
 
73
 
74
+ await this.readback.mapAsync(GPUMapMode.READ);
75
+ const data = new Float32Array(this.readback.getMappedRange());
 
76
 
77
+ for (let i = 0; i < data.length; i++) {
78
+ this.image.data[i] = Math.min(255, data[i] * 255);
 
 
 
 
79
  }
80
+
81
+ this.readback.unmap();
82
+ this.ctx.putImageData(this.image, 0, 0);
83
  }
84
 
85
  apply(cmd) {