@group(0) @binding(0) var positions: array>; @group(0) @binding(1) var gridHashes: array; @group(0) @binding(2) var indices: array; @group(0) @binding(3) var cellCount: u32; @group(0) @binding(4) var gridMin: vec3; @group(0) @binding(5) var gridMax: vec3; fn getHash(gridCoordinate: vec3, cellCount: u32) -> u32 { let maxIndex = i32(cellCount) - 1; let x = max(0, min(gridCoordinate.x, maxIndex)); let y = max(0, min(gridCoordinate.y, maxIndex)); let z = max(0, min(gridCoordinate.z, maxIndex)); return u32(x + y * i32(cellCount) + z * i32(cellCount) * i32(cellCount)); } @compute @workgroup_size(256) fn computeMain(@builtin(global_invocation_id) globalInvocationId: vec3) { let particleIndex = globalInvocationId.x; if ( particleIndex >= arrayLength(&positions) ) { return; } var currentPosition = positions[particleIndex]; let cellSize = (gridMax - gridMin) / f32(cellCount); // 2.0 / 16 = 0.125 let relativePos = currentPosition - gridMin; // currentPosition + 1 let gridCoord = vec3(floor(relativePos / cellSize)); // relativePos divided by cellSize, then floored let hash = getHash(gridCoord, cellCount); gridHashes[ particleIndex ] = hash; indices[ particleIndex ] = particleIndex; }