forked from BilalY/Rasagar
205 lines
5.3 KiB
Plaintext
205 lines
5.3 KiB
Plaintext
#pragma kernel CSMain
|
|
${VFXPragmaOnlyRenderers}
|
|
${VFXPragmaRequire}
|
|
|
|
${VFXGlobalInclude}
|
|
${VFXGlobalDeclaration}
|
|
|
|
#define IndirectOutputType uint
|
|
|
|
${VFXInclude("Shaders/VFXParticleCommon.template")}
|
|
|
|
#ifdef VFX_IS_RAYTRACED
|
|
#pragma multi_compile _ VFX_COMPUTE_AABBS
|
|
#endif
|
|
|
|
#define USE_DEAD_LIST (VFX_USE_ALIVE_CURRENT && !HAS_STRIPS)
|
|
|
|
RWByteAddressBuffer attributeBuffer;
|
|
|
|
#if USE_DEAD_LIST
|
|
RWStructuredBuffer<uint> deadList;
|
|
#endif
|
|
|
|
#if VFX_HAS_INDIRECT_DRAW
|
|
RWStructuredBuffer<uint> indirectBuffer;
|
|
#endif
|
|
|
|
#if HAS_STRIPS
|
|
RWStructuredBuffer<uint> stripDataBuffer;
|
|
#endif
|
|
|
|
#if VFX_USE_STRIPALIVE_CURRENT
|
|
StructuredBuffer<uint> attachedStripDataBuffer;
|
|
#endif
|
|
|
|
CBUFFER_START(updateParamsConst)
|
|
uint dispatchWidth;
|
|
${VFXInstancingConstants}
|
|
float3 cameraXRSettings;
|
|
CBUFFER_END
|
|
|
|
${VFXPerPassInclude}
|
|
|
|
#if VFX_HAS_INDIRECT_DRAW
|
|
${VFXDeclareAppendOutputIndirectBuffer}
|
|
#endif
|
|
|
|
${VFXGeneratedBlockFunction}
|
|
|
|
|
|
|
|
[numthreads(NB_THREADS_PER_GROUP,1,1)]
|
|
void CSMain(uint3 groupId : SV_GroupID,
|
|
uint3 groupThreadId : SV_GroupThreadID)
|
|
{
|
|
uint id = GetThreadId(groupId, groupThreadId, dispatchWidth);
|
|
|
|
${VFXInitInstancingCompute}
|
|
|
|
${VFXLoadContextData}
|
|
uint systemSeed = contextData.systemSeed;
|
|
uint nbMax = contextData.maxParticleCount;
|
|
|
|
#if VFX_COMPUTE_BOUNDS
|
|
uint tid = groupThreadId.x;
|
|
#endif
|
|
|
|
if (index < nbMax)
|
|
{
|
|
#if HAS_STRIPS
|
|
if (index == 0)
|
|
{
|
|
STRIP_PARTICLE_COUNTER(instanceIndex) = 0;
|
|
}
|
|
#endif
|
|
|
|
${VFXLoadGraphValues}
|
|
|
|
VFXAttributes attributes = (VFXAttributes)0;
|
|
VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
|
|
|
|
#if VFX_USE_ALIVE_CURRENT
|
|
${VFXLoadAttributes:{alive|stripAlive}}
|
|
if (attributes.alive)
|
|
{
|
|
${VFXLoadAttributes:{(?!(alive|stripAlive))(\b\w)}}
|
|
#if VFX_USE_OLDVELOCITY_CURRENT && VFX_USE_VELOCITY_CURRENT
|
|
attributes.oldVelocity = attributes.velocity;
|
|
#endif
|
|
#if HAS_STRIPS
|
|
const StripData stripData = GetStripDataFromParticleIndex(index, instanceIndex);
|
|
InitStripAttributes(index, attributes, stripData);
|
|
#endif
|
|
|
|
#if VFX_UPDATE_SKIP_ZERO_DELTA_TIME
|
|
${VFXLoadParameter:{deltaTime}}
|
|
if (deltaTime != 0.0f)
|
|
#endif
|
|
{
|
|
${VFXProcessBlocks}
|
|
}
|
|
|
|
${VFXStoreAttributes:{(?!(alive))(\b\w)}}
|
|
if (attributes.alive)
|
|
{
|
|
|
|
#if VFX_HAS_INDIRECT_DRAW
|
|
AppendOutputBuffer(indirectBuffer, index, instanceActiveIndex);
|
|
#endif
|
|
|
|
#if HAS_STRIPS
|
|
uint bufferIndex = STRIP_DATA_INDEX(instanceIndex, stripData.stripIndex);
|
|
uint relativeIndexInStrip = GetRelativeIndex(index, stripData);
|
|
InterlockedMin(STRIP_DATA(STRIP_MIN_ALIVE, bufferIndex), relativeIndexInStrip);
|
|
InterlockedMax(STRIP_DATA(STRIP_MAX_ALIVE, bufferIndex), relativeIndexInStrip);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
${VFXStoreAttributes:{alive}}
|
|
#if USE_DEAD_LIST && !VFX_USE_STRIPALIVE_CURRENT
|
|
uint deadIndex;
|
|
InterlockedAdd(deadList[instanceIndex], 1, deadIndex);
|
|
deadIndex += DEAD_LIST_OFFSET + instanceIndex * RAW_CAPACITY;
|
|
deadList[deadIndex] = index;
|
|
#endif
|
|
}
|
|
}
|
|
#if USE_DEAD_LIST && VFX_USE_STRIPALIVE_CURRENT
|
|
else if (attributes.stripAlive)
|
|
{
|
|
if (STRIP_DATA_X(attachedStripDataBuffer, STRIP_MIN_ALIVE, index) == ~1) // Attached strip is no longer alive, recycle the particle
|
|
{
|
|
uint deadIndex;
|
|
InterlockedAdd(deadList[instanceIndex], 1, deadIndex);
|
|
deadIndex += DEAD_LIST_OFFSET + instanceIndex * RAW_CAPACITY;
|
|
deadList[deadIndex] = index;
|
|
attributes.stripAlive = false;
|
|
${VFXStoreAttributes:{stripAlive}}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// For strips, we still need to render some dead particles if they are in the middle of the strip
|
|
#if HAS_STRIPS && VFX_HAS_INDIRECT_DRAW
|
|
if (!attributes.alive)
|
|
{
|
|
const StripData stripData = GetStripDataFromParticleIndex(index, instanceIndex);
|
|
uint relativeIndexInStrip = GetRelativeIndex(index, stripData);
|
|
if (relativeIndexInStrip > 0 && relativeIndexInStrip < stripData.nextIndex - 1)
|
|
{
|
|
AppendOutputBuffer(indirectBuffer, index, instanceActiveIndex);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#else
|
|
${VFXLoadAttributes}
|
|
#if VFX_USE_OLDVELOCITY_CURRENT && VFX_USE_VELOCITY_CURRENT
|
|
attributes.oldVelocity = attributes.velocity;
|
|
#endif
|
|
#if VFX_USE_CONTINUOUSCOLLISIONCOUNT_CURRENT
|
|
//attributes.continuousCollisionCount = 0;
|
|
#endif
|
|
#if HAS_STRIPS
|
|
const StripData stripData = GetStripDataFromParticleIndex(index, instanceIndex);
|
|
InitStripAttributes(index, attributes, stripData);
|
|
#endif
|
|
|
|
#if VFX_UPDATE_SKIP_ZERO_DELTA_TIME
|
|
${VFXLoadParameter:{deltaTime}}
|
|
if (deltaTime != 0.0f)
|
|
#endif
|
|
{
|
|
${VFXProcessBlocks}
|
|
}
|
|
${VFXStoreAttributes}
|
|
#if VFX_HAS_INDIRECT_DRAW
|
|
AppendOutputBuffer(indirectBuffer, index, instanceActiveIndex);
|
|
#endif
|
|
#endif
|
|
#if VFX_COMPUTE_BOUNDS || VFX_COMPUTE_AABBS
|
|
{
|
|
#if VFX_COMPUTE_BOUNDS
|
|
${VFXLoadSize}
|
|
#if VFX_WORLD_SPACE
|
|
${VFXLoadParameter:{worldToLocal}}
|
|
#else
|
|
float4x4 worldToLocal = (float4x4)0;
|
|
#endif
|
|
InitReduction(attributes, size3, tid, worldToLocal);
|
|
#endif
|
|
}
|
|
#if VFX_COMPUTE_AABBS
|
|
${VFXLoadSizeRT}
|
|
int rayTracingDecimationFactor = VFX_RT_DECIMATION_FACTOR;
|
|
FillAabbBuffer(attributes, size3, index, instanceIndex, rayTracingDecimationFactor);
|
|
#endif
|
|
#endif
|
|
}
|
|
#if VFX_COMPUTE_BOUNDS
|
|
PerformBoundsReduction(index, tid, instanceIndex, nbMax);
|
|
#endif
|
|
}
|