1#import bevy_hanabi::vfx_common::{ 2 ChildInfo, ChildInfoBuffer, EventBuffer, DispatchIndirectArgs, IndirectBuffer, 3 EffectMetadata, RenderGroupIndirect, SimParams, Spawner, BatchInfo, 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>, 32struct EffectLocation { 51fn find_location_from_particle(slab_particle_index: u32) -> EffectLocation { 52 var lo = batch_info.prefix_sum_offset; 53 var hi = lo + batch_info.prefix_sum_count; 56 let mid = (hi + lo) >> 1u; 57 let base_particle = prefix_sum[mid]; 58 if (slab_particle_index >= base_particle) { 60 } else if (slab_particle_index < base_particle) { 64 if (num_iter >= 100) { 65 return EffectLocation(0xDEADBEEFu, 0xDEADBEEFu, 0xDEADBEEFu); 68 let base_particle = prefix_sum[lo - 1u]; 69 let effect_index = lo - 1u - batch_info.prefix_sum_offset; 70 let update_index = slab_particle_index - base_particle; 71 return EffectLocation(effect_index, base_particle, update_index); 74@group(0) @binding(0) var<uniform> sim_params : SimParams; 77@group(1) @binding(0) var<storage, read_write> particle_buffer : ParticleBuffer; 78@group(1) @binding(1) var<storage, read_write> indirect_buffer : IndirectBuffer; 79#ifdef READ_PARENT_PARTICLE 80@group(1) @binding(2) var<storage, read> parent_particle_buffer : ParentParticleBuffer; 84@group(2) @binding(0) var<storage, read> spawners : array<Spawner>; 85@group(2) @binding(1) var<storage, read> prefix_sum : array<u32>; 86@group(2) @binding(2) var<storage, read> batch_info : BatchInfo; 90@group(3) @binding(0) var<storage, read_write> effect_metadatas : array<EffectMetadata>; 91#ifdef CONSUME_GPU_SPAWN_EVENTS 92@group(3) @binding(1) var<storage, read> child_info_buffer : ChildInfoBuffer; 93@group(3) @binding(2) var<storage, read> event_buffer : EventBuffer; 98var<private> effect_metadata_index: u32; 99var<private> properties_array_index: u32; 101@compute @workgroup_size(64) 102fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) { 106 let slab_particle_index = batch_info.base_particle + global_invocation_id.x; 109 let location = find_location_from_particle(slab_particle_index); 110 let spawner = &spawners[batch_info.base_effect + location.effect_index]; 111 effect_metadata_index = (*spawner).effect_metadata_index; 112 let base_particle = location.base_particle; 116 let effect_metadata = &effect_metadatas[(*spawner).effect_metadata_index]; 117 let max_spawn = atomicLoad(&(*effect_metadata).max_spawn); 118 if (location.update_index >= max_spawn) { 121 properties_array_index = (*effect_metadata).properties_array_index; 125#ifdef CONSUME_GPU_SPAWN_EVENTS 126 let event_index = location.update_index; 127 let global_child_index = (*effect_metadata).global_child_index; 128 let event_count = child_info_buffer.rows[global_child_index].event_count; 129 if (event_index >= u32(event_count)) { 136 let spawn_count: u32 = u32((*spawner).spawn); 137 if (location.update_index >= spawn_count) { 143 let alive_index = atomicAdd(&(*effect_metadata).alive_count, 1u); 144 let slab_particle_dead_index = indirect_buffer.rows[base_particle + alive_index].dead_index; 145 let particle_index = slab_particle_dead_index - base_particle; 153 let particle_counter = atomicAdd(&(*effect_metadata).particle_counter, 1u); 156 seed = pcg_hash(particle_index ^ (*spawner).seed); 159 let transform = transpose( 161 (*spawner).transform[0], 162 (*spawner).transform[1], 163 (*spawner).transform[2], 164 vec4<f32>(0.0, 0.0, 0.0, 1.0) 168#ifdef READ_PARENT_PARTICLE 170 let parent_base_particle = (*spawner).parent_slab_offset; 171 let parent_particle_index = event_buffer.spawn_events[event_index].particle_index; 172 let parent_particle = parent_particle_buffer.particles[parent_base_particle + parent_particle_index]; 176 var particle = Particle(); 179 particle.prev = 0xffffffffu; 180#endif // ATTRIBUTE_PREV 182 particle.next = 0xffffffffu; 183#endif // ATTRIBUTE_NEXT 188#ifndef CONSUME_GPU_SPAWN_EVENTS 189 {{SIMULATION_SPACE_TRANSFORM_PARTICLE}} 193 let write_index = (*effect_metadata).indirect_write_index; 194 indirect_buffer.rows[base_particle + alive_index].particle_index[write_index] = particle_index; 197 particle_buffer.particles[base_particle + particle_index] = particle;