@compute @workgroup_size(256)
fn compute_forces(
@builtin(global_invocation_id) id: vec3<u32>
) {
let node_idx = id.x;
if (node_idx >= uniforms.node_count) { return; }
var force = vec3<f32>(0.0);
// Repulsion from all nodes
for (var i = 0u; i < uniforms.node_count; i++) {
if (i == node_idx) { continue; }
let delta = positions[node_idx] - positions[i];
let dist = max(length(delta), 0.001);
force += normalize(delta) * (uniforms.repulsion / (dist * dist));
}
// Attraction to connected nodes
// ... edge traversal ...
// Gravity toward center
force -= positions[node_idx] * uniforms.gravity;
forces[node_idx] = force;
}