1#import bevy_hanabi::vfx_common::{ 2 ChildInfo, ChildInfoBuffer, EventBuffer, DispatchIndirectArgs, IndirectBuffer, 3 EffectMetadata, RenderGroupIndirect, SimParams, Spawner, 4 seed, tau, pcg_hash, to_float01, frand, frand2, frand3, frand4, 5 rand_uniform_f, rand_uniform_vec2, rand_uniform_vec3, rand_uniform_vec4, 6 rand_normal_f, rand_normal_vec2, rand_normal_vec3, rand_normal_vec4, proj 13struct ParticleBuffer { 14 particles: array<Particle>, 17#ifdef READ_PARENT_PARTICLE 19struct ParentParticle { 23struct ParentParticleBuffer { 24 particles: array<ParentParticle>, 31@group(0) @binding(0) var<uniform> sim_params : SimParams; 34@group(1) @binding(0) var<storage, read_write> particle_buffer : ParticleBuffer; 35@group(1) @binding(1) var<storage, read_write> indirect_buffer : IndirectBuffer; 36#ifdef READ_PARENT_PARTICLE 37@group(1) @binding(2) var<storage, read> parent_particle_buffer : ParentParticleBuffer; 41@group(2) @binding(0) var<storage, read> spawner : Spawner; 45@group(3) @binding(0) var<storage, read_write> effect_metadatas : array<EffectMetadata>; 46#ifdef CONSUME_GPU_SPAWN_EVENTS 47@group(3) @binding(1) var<storage, read> child_info_buffer : ChildInfoBuffer; 48@group(3) @binding(2) var<storage, read> event_buffer : EventBuffer; 53@compute @workgroup_size(64) 54fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) { 55 let thread_index = global_invocation_id.x; 59 let effect_metadata = &effect_metadatas[spawner.effect_metadata_index]; 60 let max_spawn = atomicLoad(&(*effect_metadata).max_spawn); 61 if (thread_index >= max_spawn) { 67#ifdef CONSUME_GPU_SPAWN_EVENTS 68 let event_index = thread_index; 69 let global_child_index = (*effect_metadata).global_child_index; 70 let event_count = child_info_buffer.rows[global_child_index].event_count; 71 if (event_index >= u32(event_count)) { 78 let spawn_count: u32 = u32(spawner.spawn); 79 if (thread_index >= spawn_count) { 84 let base_particle = spawner.slab_offset; 87 let alive_index = atomicAdd(&(*effect_metadata).alive_count, 1u); 88 let slab_particle_index = indirect_buffer.rows[base_particle + alive_index].dead_index; 89 let particle_index = slab_particle_index - base_particle; 97 let particle_counter = atomicAdd(&(*effect_metadata).particle_counter, 1u); 100 seed = pcg_hash(particle_index ^ spawner.seed); 103 let transform = transpose( 105 spawner.transform[0], 106 spawner.transform[1], 107 spawner.transform[2], 108 vec4<f32>(0.0, 0.0, 0.0, 1.0) 112#ifdef READ_PARENT_PARTICLE 114 let parent_base_particle = spawner.parent_slab_offset; 115 let parent_particle_index = event_buffer.spawn_events[event_index].particle_index; 116 let parent_particle = parent_particle_buffer.particles[parent_base_particle + parent_particle_index]; 120 var particle = Particle(); 123 particle.prev = 0xffffffffu; 124#endif // ATTRIBUTE_PREV 126 particle.next = 0xffffffffu; 127#endif // ATTRIBUTE_NEXT 132#ifndef CONSUME_GPU_SPAWN_EVENTS 133 {{SIMULATION_SPACE_TRANSFORM_PARTICLE}} 137 let write_index = (*effect_metadata).indirect_write_index; 138 indirect_buffer.rows[base_particle + alive_index].particle_index[write_index] = particle_index; 141 particle_buffer.particles[base_particle + particle_index] = particle;