Files
UnrealEngine/Engine/Plugins/FX/NiagaraNanite/Shaders/NiagaraNaniteGPUScene.usf
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

173 lines
5.9 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "/Engine/Private/Common.ush"
#include "/Engine/Private/ComputeShaderUtils.ush"
#include "/Engine/Private/GPUScene/GPUSceneWriter.ush"
#include "/Plugin/FX/Niagara/Private/NiagaraCommon.ush"
#include "/Plugin/FX/Niagara/Private/NiagaraQuaternionUtils.ush"
#include "/Plugin/FX/Niagara/Private/NiagaraTransformUtils.ush"
uint NumAllocatedInstances;
uint ParticleCpuCount;
uint ParticleGpuCountOffset;
uint ParticleBufferStride;
Buffer<float> ParticleFloatData;
Buffer<float> ParticleHalfData;
Buffer<int> ParticleIntData;
Buffer<uint> ParticleCountBuffer;
uint NumCustomFloats;
uint NumCustomFloat4s;
uint4 CustomFloatComponents[MAX_CUSTOM_FLOAT4S];
float4 DefaultCustomFloats[MAX_CUSTOM_FLOAT4S];
uint PositionComponentOffset;
uint RotationComponentOffset;
uint ScaleComponentOffset;
uint PrevPositionComponentOffset;
uint PrevRotationComponentOffset;
uint PrevScaleComponentOffset;
float3 DefaultPosition;
float4 DefaultRotation;
float3 DefaultScale;
float3 DefaultPrevPosition;
float4 DefaultPrevRotation;
float3 DefaultPrevScale;
float3 MeshScale;
float4 MeshRotation;
int MeshIndex;
int RendererVis;
uint MeshIndexComponentOffset;
uint RendererVisComponentOffset;
float3 SimulationToComponent_Translation;
float4 SimulationToComponent_Rotation;
float3 SimulationToComponent_Scale;
float3 PreviousSimulationToComponent_Translation;
float4 PreviousSimulationToComponent_Rotation;
float3 PreviousSimulationToComponent_Scale;
float3 SimulationLWCTile;
uint PrimitiveId;
#define USE_GLOBAL_NIAGARA_DATA_BUFFERS 0
#define ENABLE_NIAGARA_INT_DATA_ACCESS 1
#define NiagaraGetFloatBuffer() ParticleFloatData
#define NiagaraGetHalfBuffer() ParticleHalfData
#define NiagaraGetIntBuffer() ParticleIntData
#define NiagaraGetFloatDataStride() ParticleBufferStride
#define NiagaraGetIntDataStride() ParticleBufferStride
#include "/Plugin/FX/Niagara/Private/NiagaraParticleAccess.ush"
uint GetPayloadDataFlags()
{
uint Flags = 0;
Flags |= NumCustomFloats > 0 ? INSTANCE_SCENE_DATA_FLAG_HAS_CUSTOM_DATA : 0;
Flags |= INSTANCE_SCENE_DATA_FLAG_HAS_DYNAMIC_DATA;
return Flags;
}
void CullInstance(uint InstanceId)
{
// This will minimally initialize the instance data such that it will be ignored and culled
WriteInstancePrimitiveIdAndFlags(InstanceId, PrimitiveId, INSTANCE_SCENE_DATA_FLAG_HIDDEN);
}
[numthreads(THREAD_GROUP_SIZE, 1, 1)]
void UpdateMeshInstancesCS(uint3 GroupId : SV_GroupID, uint GroupIndex : SV_GroupIndex)
{
const uint DispatchId = GetUnWrappedDispatchThreadId(GroupId, GroupIndex, THREAD_GROUP_SIZE);
const uint LocalInstanceId = DispatchId.x;
// Retrieve the primitive data
FPrimitiveSceneData PrimitiveData = GetPrimitiveData(PrimitiveId);
const uint InstanceId = PrimitiveData.InstanceSceneDataOffset + LocalInstanceId;
// In instance count bounds?
if ( LocalInstanceId >= NumAllocatedInstances )
{
return;
}
// Get particle count and cull
uint ParticleCount = ParticleCpuCount;
if (ParticleGpuCountOffset != uint(-1))
{
ParticleCount = ParticleCountBuffer[ParticleGpuCountOffset];
}
if ( LocalInstanceId >= ParticleCount )
{
CullInstance(InstanceId);
return;
}
// Cull on Mesh Index / Renderer Vis
if ( NiagaraSafeGetInt(MeshIndexComponentOffset, LocalInstanceId, MeshIndex) != MeshIndex )
{
CullInstance(InstanceId);
return;
}
if ( NiagaraSafeGetInt(RendererVisComponentOffset, LocalInstanceId, RendererVis) != RendererVis )
{
CullInstance(InstanceId);
return;
}
// Get out transforms
const FNiagaraTransform SimulationToComponent = MakeTransform(SimulationToComponent_Translation, SimulationToComponent_Rotation, SimulationToComponent_Scale);
const FNiagaraTransform PreviousSimulationToComponent = MakeTransform(PreviousSimulationToComponent_Translation, PreviousSimulationToComponent_Rotation, PreviousSimulationToComponent_Scale);
// Read Data In
FNiagaraTransform InstanceTransform = MakeTransform(
NiagaraSafeGetVec3(PositionComponentOffset, LocalInstanceId, DefaultPosition),
MultiplyQuat(NiagaraSafeGetVec4(RotationComponentOffset, LocalInstanceId, DefaultRotation), MeshRotation),
NiagaraSafeGetVec3(ScaleComponentOffset, LocalInstanceId, DefaultScale) * MeshScale
);
FNiagaraTransform InstancePrevTransform = MakeTransform(
NiagaraSafeGetVec3(PrevPositionComponentOffset, LocalInstanceId, DefaultPosition),
MultiplyQuat(NiagaraSafeGetVec4(PrevRotationComponentOffset, LocalInstanceId, DefaultRotation), MeshRotation),
NiagaraSafeGetVec3(PrevScaleComponentOffset, LocalInstanceId, DefaultScale) * MeshScale
);
InstanceTransform = MultiplyTransform(InstanceTransform, SimulationToComponent);
InstancePrevTransform = MultiplyTransform(InstancePrevTransform, PreviousSimulationToComponent);
const float4x4 LocalToWorld = TransformToMatrix44(InstanceTransform);
const float4x4 PrevLocalToWorld = TransformToMatrix44(InstancePrevTransform);
const uint PayloadDataFlags = GetPayloadDataFlags();
InitializeInstanceSceneDataWS(
InstanceId,
PrimitiveId,
LocalInstanceId,
PayloadDataFlags,
NumCustomFloats,
0.0f,
DFFromTileOffset(MakeLWCMatrix(SimulationLWCTile, LocalToWorld))
);
FInstancePayloadDataOffsets PayloadOffsets = GetInstancePayloadDataOffsets(PrimitiveId, PayloadDataFlags, LocalInstanceId);
WriteInstanceDynamicDataWS(PayloadOffsets, PrimitiveId, DFFromTileOffset(MakeLWCMatrix(SimulationLWCTile, PrevLocalToWorld)));
for ( uint i=0; i < NumCustomFloat4s; ++i )
{
float4 CustomFloatData;
CustomFloatData.x = NiagaraSafeGetFloat(CustomFloatComponents[i].x, LocalInstanceId, DefaultCustomFloats[i].x);
CustomFloatData.y = NiagaraSafeGetFloat(CustomFloatComponents[i].y, LocalInstanceId, DefaultCustomFloats[i].y);
CustomFloatData.z = NiagaraSafeGetFloat(CustomFloatComponents[i].z, LocalInstanceId, DefaultCustomFloats[i].z);
CustomFloatData.w = NiagaraSafeGetFloat(CustomFloatComponents[i].w, LocalInstanceId, DefaultCustomFloats[i].w);
WriteInstanceCustomData(PayloadOffsets, i, CustomFloatData);
}
}