#pragma kernel UpdateParticleStrip #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch glcore gles3 webgpu #include "HLSLSupport.cginc" #define NB_THREADS_PER_GROUP 64 #define VFX_USE_INSTANCING 1 #define VFX_INSTANCING_BATCH_INDIRECTION 1 #define VFX_INSTANCING_FIXED_SIZE stripCount #define STRIP_COUNT stripCount CBUFFER_START(params) uint dispatchWidth; uint stripCount; uint particlePerStripCount; float4 instancingConstants; CBUFFER_END #include "VFXInstancing.hlsl" RWStructuredBuffer stripDataBuffer; #include "Packages/com.unity.visualeffectgraph/Shaders/VFXParticleStripCommon.hlsl" [numthreads(NB_THREADS_PER_GROUP,1,1)] void UpdateParticleStrip(uint3 groupId : SV_GroupID, uint3 groupThreadId : SV_GroupThreadID) { uint index = groupThreadId.x + groupId.x * NB_THREADS_PER_GROUP + groupId.y * dispatchWidth * NB_THREADS_PER_GROUP; if (index < stripCount * (uint)instancingActiveCount) { uint instanceIndex, instanceActiveIndex, instanceCurrentIndex; uint stripIndex = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex); uint bufferIndex = STRIP_DATA_INDEX(instanceIndex, stripIndex); bool isEmpty = (STRIP_DATA(STRIP_MIN_ALIVE, bufferIndex) & ~1) == ~1; uint particleCount = isEmpty ? 0 : STRIP_DATA(STRIP_MAX_ALIVE, bufferIndex) - STRIP_DATA(STRIP_MIN_ALIVE, bufferIndex) + 1; STRIP_DATA(STRIP_FIRST_INDEX, bufferIndex) = isEmpty ? 0 : (STRIP_DATA(STRIP_FIRST_INDEX, bufferIndex) + STRIP_DATA(STRIP_MIN_ALIVE, bufferIndex)) % particlePerStripCount; STRIP_DATA(STRIP_NEXT_INDEX, bufferIndex) = particleCount; STRIP_DATA(STRIP_PREV_NEXT_INDEX, bufferIndex) = particleCount; // Store particle count twice so that it can be read consistenly in next Init (as next index will be atomically incremented in init) STRIP_DATA(STRIP_MIN_ALIVE, bufferIndex) = isEmpty ? ~1 : ~0; STRIP_DATA(STRIP_MAX_ALIVE, bufferIndex) = 0; InterlockedAdd(STRIP_PARTICLE_COUNTER(instanceIndex), particleCount); } }