1#import bevy_hanabi::vfx_common::{ 2 ChildInfo, ChildInfoBuffer, EventBuffer, DispatchIndirectArgs, IndirectBuffer, 3 EffectMetadata, RenderGroupIndirect, SimParams, Spawner, DrawIndexedIndirectArgs, 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; 32@group(0) @binding(1) var<storage, read_write> draw_indirect_buffer : array<DrawIndexedIndirectArgs>; 35@group(1) @binding(0) var<storage, read_write> particle_buffer : ParticleBuffer; 36@group(1) @binding(1) var<storage, read_write> indirect_buffer : IndirectBuffer; 37#ifdef READ_PARENT_PARTICLE 38@group(1) @binding(2) var<storage, read> parent_particle_buffer : ParentParticleBuffer; 42@group(2) @binding(0) var<storage, read> spawner : Spawner; 46@group(3) @binding(0) var<storage, read_write> effect_metadatas : array<EffectMetadata>; 47#ifdef EMITS_GPU_SPAWN_EVENTS 48{{EMIT_EVENT_BUFFER_BINDINGS}} 53#ifdef EMITS_GPU_SPAWN_EVENTS 54{{EMIT_EVENT_BUFFER_APPEND_FUNCS}} 57@compute @workgroup_size(64) 58fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) { 59 let thread_index = global_invocation_id.x; 62 let effect_metadata = &effect_metadatas[spawner.effect_metadata_index]; 63 if (thread_index >= (*effect_metadata).max_update) { 67 let base_particle = spawner.slab_offset; 68#ifdef READ_PARENT_PARTICLE 69 let parent_base_particle = spawner.parent_slab_offset; 72 let write_index = effect_metadata.indirect_write_index; 73 let read_index = 1u - write_index; 75 let particle_index = indirect_buffer 76 .rows[base_particle + thread_index] 77 .particle_index[read_index]; 80 seed = pcg_hash(particle_index ^ spawner.seed); 82 var particle: Particle = particle_buffer.particles[base_particle + particle_index]; 92 let alive_index = atomicSub(&((*effect_metadata).alive_count), 1u) - 1u; 93 indirect_buffer.rows[base_particle + alive_index].dead_index = base_particle + particle_index; 102 atomicAdd(&((*effect_metadata).max_spawn), 1u); 106 let indirect_index = atomicAdd(&draw_indirect_buffer[(*effect_metadata).indirect_render_index].instance_count, 1u); 107 indirect_buffer.rows[base_particle + indirect_index].particle_index[write_index] = particle_index;