Skip to main content

PARTICLE_EMIT_GLSL

Constant PARTICLE_EMIT_GLSL 

Source
pub const PARTICLE_EMIT_GLSL: &str = r#"
#version 430 core

layout(local_size_x = 64) in;

struct Particle {
    vec4 position;
    vec4 velocity;
    vec4 color;
    float size;
    float mass;
    uint flags;
    uint attractor;
};

layout(std430, binding = 0) buffer ParticleBuffer { Particle particles[]; };
layout(std430, binding = 1) buffer DeadList       { uint dead_count; uint dead_indices[]; };
layout(std430, binding = 2) readonly buffer EmitBuffer { uint emit_count; uvec4 emit_data[]; };

layout(std140, binding = 0) uniform EmitParams {
    vec3 origin;
    float spread;
    vec4 color_a;
    vec4 color_b;
    float lifetime_min;
    float lifetime_max;
    float speed_min;
    float speed_max;
    float size_min;
    float size_max;
    float time;
    uint seed;
};

// Simple hash function for pseudo-randomness
float hash(uint n) {
    n = (n ^ 61u) ^ (n >> 16u);
    n *= 9u; n ^= n >> 4u;
    n *= 0x27d4eb2du; n ^= n >> 15u;
    return float(n) / float(0xFFFFFFFFu);
}

vec3 random_dir(uint seed) {
    float theta = hash(seed)       * 6.2831853;
    float phi   = hash(seed + 1u)  * 3.1415927;
    return vec3(sin(phi)*cos(theta), cos(phi), sin(phi)*sin(theta));
}

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

    // Claim a dead particle slot
    uint dead_idx_pos = atomicAdd(dead_count, uint(-1));
    if (dead_idx_pos == 0u) return; // No dead particles available
    uint slot = dead_indices[dead_idx_pos - 1u];

    uint s = seed + idx * 7u;
    float lifetime = mix(lifetime_min, lifetime_max, hash(s));
    float speed    = mix(speed_min,    speed_max,    hash(s + 2u));
    float psize    = mix(size_min,     size_max,     hash(s + 3u));
    vec3 dir = random_dir(s + 4u);
    vec3 pos = origin + dir * spread * hash(s + 5u);

    particles[slot].position = vec4(pos, lifetime);
    particles[slot].velocity = vec4(dir * speed, 0.0);
    particles[slot].color    = mix(color_a, color_b, hash(s + 6u));
    particles[slot].size     = psize;
    particles[slot].mass     = 1.0;
    particles[slot].flags    = 1u;
    particles[slot].attractor = 0u;
}
"#;
Expand description

Particle emit compute shader — spawns new particles from dead list.