152 lines
6.6 KiB
HLSL
152 lines
6.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "NiagaraStatelessCommon.ush"
|
|
#include "/Engine/Private/ComputeShaderUtils.ush"
|
|
//#include "WaveOpUtil.ush"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define PARTICLE_ATTRIBUTE_OUTPUT(TYPE, NAME) int Permutation_##NAME##Component;
|
|
#define PARTICLE_ATTRIBUTE_OUTPUT_IMPLICIT(TYPE, NAME) int Permutation_##NAME##Component;
|
|
#define PARTICLE_ATTRIBUTE_TRANSIENT(TYPE, NAME)
|
|
PARTICLE_ATTRIBUTES
|
|
#undef PARTICLE_ATTRIBUTE
|
|
#undef PARTICLE_ATTRIBUTE_OUTPUT_IMPLICIT
|
|
#undef PARTICLE_ATTRIBUTE_TRANSIENT
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// TBD this might produce sub optimal code, needs investigate and is temporary
|
|
#include "Modules/NiagaraStatelessModule_CalculateAccurateVelocity.ush"
|
|
#include "Modules/NiagaraStatelessModule_CameraOffset.ush"
|
|
#include "Modules/NiagaraStatelessModule_DynamicMaterialParameters.ush"
|
|
#include "Modules/NiagaraStatelessModule_InitializeParticle.ush"
|
|
#include "Modules/NiagaraStatelessModule_InitialMeshOrientation.ush"
|
|
#include "Modules/NiagaraStatelessModule_MeshIndex.ush"
|
|
#include "Modules/NiagaraStatelessModule_MeshRotationRate.ush"
|
|
#include "Modules/NiagaraStatelessModule_RotateAroundPoint.ush"
|
|
#include "Modules/NiagaraStatelessModule_ShapeLocation.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleColor.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleRibbonWidth.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleSpriteSize.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleSpriteSizeBySpeed.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleMeshSize.ush"
|
|
#include "Modules/NiagaraStatelessModule_ScaleMeshSizebySpeed.ush"
|
|
#include "Modules/NiagaraStatelessModule_SolveVelocitiesAndForces.ush"
|
|
#include "Modules/NiagaraStatelessModule_SpriteFacingAndAlignment.ush"
|
|
#include "Modules/NiagaraStatelessModule_SpriteRotationRate.ush"
|
|
#include "Modules/NiagaraStatelessModule_SubUVAnimation.ush"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
uint Common_RandomSeed;
|
|
float Common_SimulationTime;
|
|
float Common_SimulationDeltaTime;
|
|
float Common_SimulationInvDeltaTime;
|
|
|
|
uint Common_GPUCountBufferOffset;
|
|
RWBuffer<int> Common_GPUCountBuffer;
|
|
|
|
DECLARE_SCALAR_ARRAY(uint, SpawnInfo_NumActive, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(uint, SpawnInfo_ParticleOffset, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(uint, SpawnInfo_UniqueOffset, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(float, SpawnInfo_Time, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(float, SpawnInfo_Rate, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(float, SpawnInfo_LifetimeScale, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
DECLARE_SCALAR_ARRAY(float, SpawnInfo_LifetimeBias, NIAGARA_MAX_GPU_SPAWN_INFOS);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Null_Simulate(inout FStatelessParticle Particle)
|
|
{
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
[numthreads(THREADGROUP_SIZE, 1, 1)]
|
|
void StatelessMain(uint3 GroupId : SV_GroupID, int GroupThreadIndex : SV_GroupIndex)
|
|
{
|
|
// Convert thread ID into linear thread
|
|
uint LinearThreadId = GetUnWrappedDispatchThreadId(GroupId, GroupThreadIndex, THREADGROUP_SIZE);
|
|
|
|
// Initialize our particle data
|
|
FStatelessParticle Particle = (FStatelessParticle)0;;
|
|
Particle.Age = -1.0f;
|
|
|
|
// Find which spawn info we belong to and fill out details
|
|
uint ModuleSeedOffset = 0;
|
|
{
|
|
uint SpawnInfoIndex = LinearThreadId;
|
|
for ( int i=0; i < NIAGARA_MAX_GPU_SPAWN_INFOS; ++i )
|
|
{
|
|
const uint SpawnInfoNumActive = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_NumActive, i);
|
|
const uint SpawnInfoParticleOffset = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_ParticleOffset, i);
|
|
const uint SpawnInfoUniqueOffset = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_UniqueOffset, i);
|
|
const float SpawnInfoTime = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_Time, i);
|
|
const float SpawnInfoRate = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_Rate, i);
|
|
const float SpawnInfoLifetimeScale = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_LifetimeScale, i);
|
|
const float SpawnInfoLifetimeBias = GET_SCALAR_ARRAY_ELEMENT(SpawnInfo_LifetimeBias, i);
|
|
if ( SpawnInfoIndex < SpawnInfoNumActive )
|
|
{
|
|
const uint SpawnParticleIndex = SpawnInfoIndex + SpawnInfoParticleOffset;
|
|
Particle.UniqueIndex = SpawnInfoIndex + SpawnInfoUniqueOffset + SpawnInfoParticleOffset;
|
|
Particle.Age = Common_SimulationTime - (SpawnInfoTime + float(SpawnParticleIndex) * SpawnInfoRate);
|
|
GRandomSeedInternal = FNiagaraStatelessDefinitions::MakeRandomSeed(Common_RandomSeed, Particle.UniqueIndex, ModuleSeedOffset++, 0);
|
|
Particle.Lifetime = RandomScaleBiasFloat(0, SpawnInfoLifetimeScale, SpawnInfoLifetimeBias);
|
|
break;
|
|
}
|
|
|
|
SpawnInfoIndex -= SpawnInfoNumActive;
|
|
}
|
|
if ( Particle.Age < 0.0f )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Initialize variables / determine lifetime / etc
|
|
if ( Particle.Lifetime <= 0.0f || Particle.Age >= Particle.Lifetime )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Particle.NormalizedAge = Particle.Age / Particle.Lifetime;
|
|
|
|
Particle.PreviousAge = max(Particle.Age - Common_SimulationDeltaTime, 0.0f);
|
|
Particle.PreviousNormalizedAge = Particle.PreviousAge / Particle.Lifetime;
|
|
|
|
Particle.DeltaTime = Common_SimulationDeltaTime;
|
|
Particle.InvDeltaTime = Common_SimulationInvDeltaTime;
|
|
|
|
Particle.bAlive = true;
|
|
|
|
Particle.MaterialRandom = RandomFloat(1);
|
|
|
|
// Run Particle Simulate
|
|
#define PARTICLE_MODULE(NAME) \
|
|
GRandomSeedInternal = FNiagaraStatelessDefinitions::MakeRandomSeed(Common_RandomSeed, Particle.UniqueIndex, ModuleSeedOffset++, 0); \
|
|
##NAME##_Simulate(Particle);
|
|
|
|
PARTICLE_MODULES
|
|
|
|
#undef PARTICLE_MODULE
|
|
|
|
if ( !Particle.bAlive )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Output Particles that are still alive
|
|
uint OutputIndex;
|
|
|
|
//WaveInterlockedAddScalar_(Common_GPUCountBuffer[Common_GPUCountBufferOffset], 1, Particle.OutputIndex);
|
|
InterlockedAdd(Common_GPUCountBuffer[Common_GPUCountBufferOffset], 1, OutputIndex);
|
|
|
|
#define PARTICLE_ATTRIBUTE_OUTPUT(TYPE, NAME) if ( IsValidComponent(Permutation_##NAME##Component) ) { OutputComponentData(OutputIndex, Permutation_##NAME##Component, Particle.##NAME); }
|
|
#define PARTICLE_ATTRIBUTE_OUTPUT_IMPLICIT(TYPE, NAME) if ( IsValidComponent(Permutation_##NAME##Component) ) { OutputComponentData(OutputIndex, Permutation_##NAME##Component, Particle.##NAME); }
|
|
#define PARTICLE_ATTRIBUTE_TRANSIENT(TYPE, NAME)
|
|
PARTICLE_ATTRIBUTES
|
|
#undef PARTICLE_ATTRIBUTE
|
|
#undef PARTICLE_ATTRIBUTE_OUTPUT_IMPLICIT
|
|
#undef PARTICLE_ATTRIBUTE_TRANSIENT
|
|
}
|