Skip to content

Commit ed3875e

Browse files
committed
wip
1 parent be0f4f2 commit ed3875e

File tree

6 files changed

+812
-91
lines changed

6 files changed

+812
-91
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
struct Config {
2+
binWidth: f32,
3+
binHeight: f32,
4+
widthDivisions: u32,
5+
binCount: u32,
6+
particleCount: u32,
7+
}
8+
9+
@group(0) @binding(0) var<uniform> config: Config;
10+
@group(1) @binding(0) var<storage, read_write> binSize: array<atomic<u32>>;
11+
@group(1) @binding(1) var<storage, read_write> binOffset: array<u32>;
12+
@group(1) @binding(2) var<storage, read_write> binCursor: array<atomic<u32>>;
13+
@group(1) @binding(3) var<storage, read_write> binContents: array<u32>;
14+
@group(2) @binding(0) var<storage, read> particlePositions: array<vec2f>;
15+
16+
@compute @workgroup_size(256)
17+
fn clear(
18+
@builtin(global_invocation_id) id: vec3u,
19+
) {
20+
let i = id.x;
21+
if (i >= config.binCount) {
22+
return;
23+
}
24+
atomicStore(&binSize[i], 0u);
25+
binOffset[i] = 0u;
26+
atomicStore(&binCursor[i], 0u);
27+
}
28+
29+
@compute @workgroup_size(256)
30+
fn size(
31+
@builtin(global_invocation_id) id: vec3u,
32+
) {
33+
let i = id.x;
34+
if (i >= config.particleCount) {
35+
return;
36+
}
37+
38+
let position = particlePositions[i];
39+
let bin_x = u32(position.x / config.binWidth);
40+
let bin_y = u32(position.y / config.binHeight);
41+
let index = bin_y * config.widthDivisions + bin_x;
42+
43+
atomicAdd(&binSize[index], 1u);
44+
}
45+
46+
@compute @workgroup_size(256)
47+
fn prepare(
48+
@builtin(global_invocation_id) id: vec3u,
49+
) {
50+
let i = id.x;
51+
if (i >= config.binCount) {
52+
return;
53+
}
54+
var offset = 0u;
55+
for (var j: u32 = 0u; j < i; j = j + 1u) {
56+
offset = offset + atomicLoad(&binSize[j]);
57+
}
58+
binOffset[i] = offset;
59+
}
60+
61+
@compute @workgroup_size(256)
62+
fn fill(
63+
@builtin(global_invocation_id) id: vec3u,
64+
) {
65+
let i = id.x;
66+
if (i >= config.particleCount) {
67+
return;
68+
}
69+
70+
let position = particlePositions[i];
71+
let bin_x = u32(position.x / config.binWidth);
72+
let bin_y = u32(position.y / config.binHeight);
73+
let index = bin_y * config.widthDivisions + bin_x;
74+
75+
let offset = atomicAdd(&binCursor[index], 1u);
76+
let writeIndex = binOffset[index] + offset;
77+
binContents[writeIndex] = i;
78+
}

src/pages/particle-life-gpu/compute.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@group(0) @binding(0) var<storage, read_write> data: array<f32>;
2-
1+
@group(0) @binding(0) var<storage, read_write> data: array<f32>;
2+
33
@compute @workgroup_size(1) fn computeSomething(
44
@builtin(global_invocation_id) id: vec3u
55
) {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
struct Config {
2+
width: f32,
3+
height: f32,
4+
}
5+
6+
@group(0) @binding(0) var<uniform> config: Config;
7+
@group(1) @binding(0) var<storage, read> particlePositions: array<vec2f>;
8+
@group(1) @binding(1) var<storage, read> particleColors: array<u32>;
9+
10+
const size = 1.0;
11+
const positions = array<vec2f, 6>(
12+
vec2f(-1, -1),
13+
vec2f( 1, -1),
14+
vec2f( 1, 1),
15+
vec2f(-1, -1),
16+
vec2f( 1, 1),
17+
vec2f(-1, 1),
18+
);
19+
20+
const colors = array<vec4f, 6>(
21+
vec4f(1.0, 0.0, 0.0, 1.0), // red
22+
vec4f(0.0, 1.0, 0.0, 1.0), // green
23+
vec4f(0.0, 0.0, 1.0, 1.0), // blue
24+
vec4f(1.0, 1.0, 0.0, 1.0), // yellow
25+
vec4f(1.0, 0.0, 1.0, 1.0), // magenta
26+
vec4f(0.0, 1.0, 1.0, 1.0), // cyan
27+
);
28+
29+
struct VertexOutput {
30+
// corner of the square (clip space)
31+
@builtin(position) position: vec4f,
32+
// color of the particle
33+
@location(1) color: vec4f,
34+
}
35+
36+
37+
// for each particle, draw a square centered at its position (i.e. 6 vertices per particle to make a square)
38+
@vertex fn vs(
39+
@builtin(instance_index) instanceID: u32
40+
) -> VertexOutput {
41+
let pos = particlePositions[instanceID]; // screen space
42+
let vertex_pos = pos; // screen space
43+
let clip_vertex_pos = vec4f(
44+
(vertex_pos.x / (config.width / 2.0)) - 1.0,
45+
-((vertex_pos.y / (config.height / 2.0)) - 1.0),
46+
0.0,
47+
1.0
48+
);
49+
let color = colors[particleColors[instanceID]];
50+
return VertexOutput(clip_vertex_pos, color);
51+
}
52+
53+
// paint a circle centered at offset
54+
@fragment fn fs(data: VertexOutput) -> @location(0) vec4f {
55+
return data.color;
56+
}

0 commit comments

Comments
 (0)