Rasagar/Library/PackageCache/com.unity.visualeffectgraph/Shaders/VFXParticleStripCommon.hlsl
2024-08-26 23:07:20 +03:00

107 lines
3.8 KiB
HLSL

#define STRIP_FIRST_INDEX 0
#define STRIP_NEXT_INDEX 1
#define STRIP_PREV_NEXT_INDEX 2
#define STRIP_MIN_ALIVE 3
#define STRIP_MAX_ALIVE 4
#if VFX_USE_INSTANCING
#define STRIP_DATA_OFFSET instancingBatchSize
#else
#define STRIP_DATA_OFFSET 1
#endif
#define STRIP_DATA_INDEX(instanceIndex, stripIndex) ((instanceIndex * STRIP_COUNT) + stripIndex)
#define STRIP_DATA_X(buffer,data,bufferIndex) buffer[STRIP_DATA_OFFSET + (bufferIndex * 5) + (data)]
#define STRIP_DATA(data,bufferIndex) STRIP_DATA_X(stripDataBuffer,data,bufferIndex)
#define STRIP_PARTICLE_COUNTER(instanceIndex) stripDataBuffer[instanceIndex]
#define STRIP_PARTICLE_IN_EDGE (id & 1)
struct StripData
{
uint stripIndex;
uint capacity;
uint firstIndex;
uint nextIndex;
uint prevNextIndex;
};
#if HAS_STRIPS
const StripData GetStripDataFromStripIndex(uint stripIndex, uint instanceIndex)
{
StripData stripData = (StripData)0;
stripData.stripIndex = stripIndex;
stripData.capacity = PARTICLE_PER_STRIP_COUNT;
uint bufferIndex = STRIP_DATA_INDEX(instanceIndex, stripIndex);
stripData.firstIndex = STRIP_DATA(STRIP_FIRST_INDEX, bufferIndex);
stripData.nextIndex = STRIP_DATA(STRIP_NEXT_INDEX, bufferIndex);
stripData.prevNextIndex = STRIP_DATA(STRIP_PREV_NEXT_INDEX, bufferIndex);
return stripData;
}
const StripData GetStripDataFromParticleIndex(uint particleIndex, uint instanceIndex)
{
uint stripIndex = particleIndex / PARTICLE_PER_STRIP_COUNT;
return GetStripDataFromStripIndex(stripIndex, instanceIndex);
}
uint GetParticleIndex(uint relativeIndex, const StripData data)
{
return data.stripIndex * data.capacity + (relativeIndex + data.firstIndex) % data.capacity;
}
uint GetRelativeIndex(uint particleIndex, const StripData data)
{
return (data.capacity + particleIndex - data.firstIndex) % data.capacity;
}
bool FindIndexInStrip(inout uint index, uint id, uint instanceIndex, out uint relativeIndexInStrip, out StripData stripData)
{
#if VFX_HAS_INDIRECT_DRAW
// In indirect mode, index is global particle index
uint stripIndex = index / (PARTICLE_PER_STRIP_COUNT);
stripData = GetStripDataFromStripIndex(stripIndex, instanceIndex);
uint relativeParticleIndex = GetRelativeIndex(index, stripData);
#else
// By default, index is the relative particle index (skipping last one per strip as an optimization)
uint stripIndex = index / (PARTICLE_PER_STRIP_COUNT - 1);
stripData = GetStripDataFromStripIndex(stripIndex, instanceIndex);
uint relativeParticleIndex = index - stripIndex * (PARTICLE_PER_STRIP_COUNT - 1);
#endif
relativeIndexInStrip = relativeParticleIndex + STRIP_PARTICLE_IN_EDGE; // vertex index in the strip
index = GetParticleIndex(relativeIndexInStrip, stripData);
uint maxEdgeIndex = relativeParticleIndex + 1;
return maxEdgeIndex < stripData.nextIndex;
}
#if HAS_VFX_ATTRIBUTES
void InitStripAttributes(uint particleIndex, inout VFXAttributes attributes, const StripData data)
{
#if VFX_USE_STRIPINDEX_CURRENT
attributes.stripIndex = data.stripIndex;
#endif
#if VFX_USE_PARTICLEINDEXINSTRIP_CURRENT
attributes.particleIndexInStrip = GetRelativeIndex(particleIndex, data);
#endif
#if VFX_USE_PARTICLECOUNTINSTRIP_CURRENT
attributes.particleCountInStrip = data.nextIndex;
#endif
}
void InitStripAttributesWithSpawn(uint spawnCount, uint particleIndex, inout VFXAttributes attributes, const StripData data)
{
InitStripAttributes(particleIndex, attributes, data);
#if VFX_USE_PARTICLECOUNTINSTRIP_CURRENT
attributes.particleCountInStrip = data.prevNextIndex + spawnCount; // Override particle count in init as nextIndex is not constant accross threads
#endif
#if VFX_USE_SPAWNINDEXINSTRIP_CURRENT
attributes.spawnIndexInStrip = GetRelativeIndex(particleIndex, data) - data.prevNextIndex;
#endif
}
#endif
#endif