139 lines
3.9 KiB
Plaintext
139 lines
3.9 KiB
Plaintext
#pragma kernel CSMain
|
|
${VFXGlobalInclude}
|
|
${VFXGlobalDeclaration}
|
|
|
|
#define USE_DEAD_LIST (VFX_USE_ALIVE_CURRENT && !HAS_STRIPS)
|
|
|
|
RWByteAddressBuffer attributeBuffer;
|
|
ByteAddressBuffer sourceAttributeBuffer;
|
|
|
|
CBUFFER_START(initParams)
|
|
#if !VFX_USE_SPAWNER_FROM_GPU
|
|
uint nbSpawned; // Numbers of particle spawned
|
|
uint spawnIndex; // Index of the first particle spawned
|
|
uint dispatchWidth;
|
|
#else
|
|
uint offsetInAdditionalOutput;
|
|
uint nbMax;
|
|
#endif
|
|
uint systemSeed;
|
|
CBUFFER_END
|
|
|
|
#if USE_DEAD_LIST
|
|
RWStructuredBuffer<uint> deadListIn;
|
|
ByteAddressBuffer deadListCount; // This is bad to use a SRV to fetch deadList count but Unity API currently prevent from copying to CB
|
|
#endif
|
|
|
|
#if VFX_USE_SPAWNER_FROM_GPU
|
|
StructuredBuffer<uint> eventList;
|
|
ByteAddressBuffer inputAdditional;
|
|
#endif
|
|
|
|
#if HAS_STRIPS
|
|
RWStructuredBuffer<uint> stripDataBuffer;
|
|
#endif
|
|
|
|
${VFXPerPassInclude}
|
|
|
|
${VFXGeneratedBlockFunction}
|
|
|
|
// Due to a bug in HLSL compiler, disable spurious "unitialized variable" due to mid function return statement
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4000)
|
|
#if HAS_STRIPS
|
|
bool GetParticleIndex(inout uint particleIndex, uint stripIndex)
|
|
{
|
|
uint relativeIndex;
|
|
InterlockedAdd(STRIP_DATA(STRIP_NEXT_INDEX, stripIndex), 1, relativeIndex);
|
|
if (relativeIndex >= PARTICLE_PER_STRIP_COUNT) // strip is full
|
|
{
|
|
InterlockedAdd(STRIP_DATA(STRIP_NEXT_INDEX, stripIndex), -1); // Remove previous increment
|
|
return false;
|
|
}
|
|
|
|
particleIndex = stripIndex * PARTICLE_PER_STRIP_COUNT + ((STRIP_DATA(STRIP_FIRST_INDEX, stripIndex) + relativeIndex) % PARTICLE_PER_STRIP_COUNT);
|
|
return true;
|
|
}
|
|
#endif
|
|
#pragma warning(pop)
|
|
|
|
[numthreads(NB_THREADS_PER_GROUP,1,1)]
|
|
void CSMain(uint3 groupId : SV_GroupID,
|
|
uint3 groupThreadId : SV_GroupThreadID)
|
|
{
|
|
uint id = groupThreadId.x + groupId.x * NB_THREADS_PER_GROUP;
|
|
#if !VFX_USE_SPAWNER_FROM_GPU
|
|
id += groupId.y * dispatchWidth * NB_THREADS_PER_GROUP;
|
|
#endif
|
|
|
|
#if VFX_USE_SPAWNER_FROM_GPU
|
|
uint maxThreadId = inputAdditional.Load((offsetInAdditionalOutput * 2 + 0) << 2);
|
|
uint currentSpawnIndex = inputAdditional.Load((offsetInAdditionalOutput * 2 + 1) << 2) - maxThreadId;
|
|
#else
|
|
uint maxThreadId = nbSpawned;
|
|
uint currentSpawnIndex = spawnIndex;
|
|
#endif
|
|
|
|
#if USE_DEAD_LIST
|
|
maxThreadId = min(maxThreadId, deadListCount.Load(0x0));
|
|
#elif VFX_USE_SPAWNER_FROM_GPU
|
|
maxThreadId = min(maxThreadId, nbMax); //otherwise, nbSpawned already clamped on CPU
|
|
#endif
|
|
|
|
if (id < maxThreadId)
|
|
{
|
|
#if VFX_USE_SPAWNER_FROM_GPU
|
|
int sourceIndex = eventList[id];
|
|
#endif
|
|
uint particleIndex = id + currentSpawnIndex;
|
|
|
|
#if !VFX_USE_SPAWNER_FROM_GPU
|
|
${VFXComputeSourceIndex}
|
|
#endif
|
|
|
|
Attributes attributes = (Attributes)0;
|
|
SourceAttributes sourceAttributes = (SourceAttributes)0;
|
|
|
|
${VFXLoadAttributes}
|
|
#if VFX_USE_PARTICLEID_CURRENT
|
|
attributes.particleId = particleIndex;
|
|
#endif
|
|
#if VFX_USE_SEED_CURRENT
|
|
attributes.seed = WangHash(particleIndex ^ systemSeed);
|
|
#endif
|
|
#if VFX_USE_SPAWNINDEX_CURRENT
|
|
attributes.spawnIndex = id;
|
|
#endif
|
|
#if HAS_STRIPS
|
|
#if !VFX_USE_SPAWNER_FROM_GPU
|
|
${VFXLoadParameter:{stripIndex}}
|
|
#else
|
|
uint stripIndex = sourceIndex;
|
|
#endif
|
|
stripIndex = min(stripIndex, STRIP_COUNT);
|
|
|
|
if (!GetParticleIndex(particleIndex, stripIndex))
|
|
return;
|
|
|
|
const StripData stripData = GetStripDataFromStripIndex(stripIndex, PARTICLE_PER_STRIP_COUNT);
|
|
InitStripAttributesWithSpawn(maxThreadId, particleIndex, attributes, stripData);
|
|
// TODO Change seed to be sure we're deterministic on random with strip
|
|
#endif
|
|
|
|
${VFXProcessBlocks}
|
|
|
|
#if VFX_USE_ALIVE_CURRENT
|
|
if (attributes.alive)
|
|
#endif
|
|
{
|
|
#if USE_DEAD_LIST
|
|
uint deadIndex = deadListIn.DecrementCounter();
|
|
uint index = deadListIn[deadIndex];
|
|
#else
|
|
uint index = particleIndex;
|
|
#endif
|
|
${VFXStoreAttributes}
|
|
}
|
|
}
|
|
}
|