Skip to main content

KERNEL_PARTICLE_INTEGRATE

Constant KERNEL_PARTICLE_INTEGRATE 

Source
pub const KERNEL_PARTICLE_INTEGRATE: &str = r#"
// Particle integration kernel
// Reads from SSBO binding 0, writes to SSBO binding 1 (ping-pong).
// Each particle: vec4 position (xyz + age), vec4 velocity (xyz + lifetime).

layout(local_size_x = 256) in;

struct Particle {
    vec4 pos_age;    // xyz = position, w = age
    vec4 vel_life;   // xyz = velocity, w = lifetime
};

layout(std430, binding = 0) readonly buffer ParticlesIn {
    Particle particles_in[];
};

layout(std430, binding = 1) writeonly buffer ParticlesOut {
    Particle particles_out[];
};

uniform float u_dt;
uniform vec3 u_gravity;
uniform float u_damping;
uniform uint u_particle_count;
uniform float u_max_age;
uniform vec3 u_wind;
uniform float u_turbulence_strength;
uniform float u_time;

// Simple hash for turbulence
float hash(vec3 p) {
    p = fract(p * vec3(443.897, 441.423, 437.195));
    p += dot(p, p.yzx + 19.19);
    return fract((p.x + p.y) * p.z);
}

vec3 turbulence(vec3 pos, float time) {
    float n1 = hash(pos + vec3(time * 0.3));
    float n2 = hash(pos + vec3(time * 0.7, 0.0, 0.0));
    float n3 = hash(pos + vec3(0.0, time * 0.5, 0.0));
    return vec3(n1 - 0.5, n2 - 0.5, n3 - 0.5) * 2.0;
}

void main() {
    uint idx = gl_GlobalInvocationID.x;
    if (idx >= u_particle_count) return;

    Particle p = particles_in[idx];

    float age = p.pos_age.w;
    float lifetime = p.vel_life.w;

    // Advance age
    age += u_dt;

    // Kill dead particles by setting lifetime to 0
    if (age >= lifetime || age >= u_max_age) {
        p.pos_age.w = lifetime + 1.0; // Mark as dead
        p.vel_life.xyz = vec3(0.0);
        particles_out[idx] = p;
        return;
    }

    // Apply forces
    vec3 vel = p.vel_life.xyz;
    vec3 pos = p.pos_age.xyz;

    // Gravity
    vel += u_gravity * u_dt;

    // Wind
    vel += u_wind * u_dt;

    // Turbulence
    if (u_turbulence_strength > 0.0) {
        vec3 turb = turbulence(pos * 0.1, u_time);
        vel += turb * u_turbulence_strength * u_dt;
    }

    // Damping
    vel *= pow(u_damping, u_dt);

    // Integrate position
    pos += vel * u_dt;

    // Write output
    particles_out[idx].pos_age = vec4(pos, age);
    particles_out[idx].vel_life = vec4(vel, lifetime);
}
"#;
Expand description

Particle integration kernel: advance positions, apply forces, age, kill dead.