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.