64 lines
1.6 KiB
Plaintext
64 lines
1.6 KiB
Plaintext
[nzsl_version("1.0")]
|
|
module Compute.Particles;
|
|
|
|
[layout(std140)]
|
|
struct Particle
|
|
{
|
|
color: vec3[f32],
|
|
position: vec2[f32],
|
|
targetPosition: vec2[f32],
|
|
velocity: vec2[f32]
|
|
}
|
|
|
|
[layout(std140)]
|
|
struct ParticleData
|
|
{
|
|
particle_count: u32,
|
|
particles: dyn_array[Particle]
|
|
}
|
|
|
|
[layout(std140)]
|
|
struct SceneData
|
|
{
|
|
deltaTime: f32,
|
|
mousePos: vec2[f32],
|
|
effectRadius: f32
|
|
}
|
|
|
|
external
|
|
{
|
|
[binding(0)] data: storage[ParticleData],
|
|
[binding(1)] sceneData: uniform[SceneData]
|
|
}
|
|
|
|
struct Input
|
|
{
|
|
[builtin(global_invocation_indices)] indices: vec3[u32]
|
|
}
|
|
|
|
[entry(compute)]
|
|
[workgroup(64, 1, 1)]
|
|
fn main(input: Input)
|
|
{
|
|
let index = input.indices.x;
|
|
if (index >= data.particle_count)
|
|
return;
|
|
|
|
// Gets pushed by the cursor
|
|
let attract_pos = sceneData.mousePos;
|
|
let dist = length(attract_pos - data.particles[index].position);
|
|
data.particles[index].velocity -= 10000.0 * sceneData.effectRadius / min(dist, sceneData.effectRadius) * sceneData.deltaTime * (attract_pos - data.particles[index].position) / (dist * dist * dist * dist);
|
|
|
|
// But want to return to their original position
|
|
let dist = length(data.particles[index].targetPosition - data.particles[index].position);
|
|
let shouldUseDir = dist < 1.0;
|
|
data.particles[index].velocity += 100.0 * sceneData.deltaTime * select(shouldUseDir, normalize(data.particles[index].targetPosition - data.particles[index].position), vec2[f32](0.0, 0.0));
|
|
|
|
// Lose speed with time
|
|
let damping = pow(0.5, sceneData.deltaTime);
|
|
data.particles[index].velocity *= damping;
|
|
|
|
// Move particle
|
|
data.particles[index].position += data.particles[index].velocity * sceneData.deltaTime;
|
|
}
|