Files
UnrealEngine/Engine/Plugins/FX/Niagara/Shaders/Private/NiagaraParticleAccess.ush
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

276 lines
7.6 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
// NiagaraParticleAccess
// ---------------------
// This header provides helpers for accessing Niagara data from any shader type. By default, it declares the data buffers as globals,
// but can be altered with some #defines to re-use with buffers that come from a non-global source (such as Vertex Factory params or
// static uniform buffers).
//
// To provide a custom interface to power these functions, add #define USE_GLOBAL_NIAGARA_DATA_BUFFERS 0 and declare the following global
// functions before including this header:
// * NiagaraGetFloatBuffer - Gets a Buffer<float> that points to the full 32-bit float particle data
// * NiagaraGetHalfBuffer - Gets a Buffer<float> that points to the 16-bit float particle data
// * NiagaraGetFloatDataStride - Gets a uint32 that describes the stride between float registers (assumed to be the same for both float and half)
// * NiagaraGetIntBuffer - Gets a Buffer<int> that points to the int particle data (Optional, see below)
// * NiagaraGetIntDataStride - Gets a uint32 that describes the stride between int registers (Optional, see below)
//
// You can may opt out of providing or declaring the integer data buffer by adding #define ENABLE_NIAGARA_INTDATA_ACCESS 0 before
// including this header. If you are not using global Niagara data buffers, you do not need to define the integer data accessors.
#ifndef USE_GLOBAL_NIAGARA_DATA_BUFFERS
#define USE_GLOBAL_NIAGARA_DATA_BUFFERS 1
#endif
#ifndef ENABLE_NIAGARA_INT_DATA_ACCESS
#define ENABLE_NIAGARA_INT_DATA_ACCESS 1
#endif
#if USE_GLOBAL_NIAGARA_DATA_BUFFERS
Buffer<float> NiagaraParticleDataFloat;
Buffer<float> NiagaraParticleDataHalf;
uint NiagaraFloatDataStride;
// NOTE: NiagarGet*Buffer have to be macros (not functions) to appease certain shader platforms
#define NiagaraGetFloatBuffer() (NiagaraParticleDataFloat)
#define NiagaraGetHalfBuffer() (NiagaraParticleDataHalf)
uint NiagaraGetFloatDataStride() { return NiagaraFloatDataStride; }
#if ENABLE_NIAGARA_INT_DATA_ACCESS
Buffer<int> NiagaraParticleDataInt;
uint NiagaraIntDataStride;
#define NiagaraGetIntBuffer() (NiagaraParticleDataInt)
uint NiagaraGetIntDataStride() { return NiagaraIntDataStride; }
#endif
#endif
bool NiagaraGetIsHalfAndFixupRegister(inout int RegisterIdx)
{
// this was originally: bool IsHalf = RegisterIdx & (1 << 31);
// but the glsl comes out as -2147483648 and this appears to be upsetting some old android glsl compilers. Doing this forces an
// unsigned 2147483648u literal into glsl. FORT-286011.
const uint HalfBit = (1 << 31);
const bool bIsHalf = RegisterIdx & HalfBit;
RegisterIdx &= ~HalfBit;
return bIsHalf;
}
float NiagaraGetFloat_Internal(Buffer<float> FloatBuffer, int RegisterIdx, uint ParticleIdx)
{
return FloatBuffer[RegisterIdx * NiagaraGetFloatDataStride() + ParticleIdx];
}
float2 NiagaraGetVec2_Internal(Buffer<float> FloatBuffer, int RegisterIdx, uint ParticleIdx)
{
return float2(NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 0, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 1, ParticleIdx));
}
float3 NiagaraGetVec3_Internal(Buffer<float> FloatBuffer, int RegisterIdx, uint ParticleIdx)
{
return float3(NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 0, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 1, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 2, ParticleIdx));
}
float4 NiagaraGetVec4_Internal(Buffer<float> FloatBuffer, int RegisterIdx, uint ParticleIdx)
{
return float4(NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 0, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 1, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 2, ParticleIdx),
NiagaraGetFloat_Internal(FloatBuffer, RegisterIdx + 3, ParticleIdx));
}
float NiagaraGetFloat(int RegisterIdx, uint ParticleIdx)
{
BRANCH
if (NiagaraGetIsHalfAndFixupRegister(RegisterIdx))
{
return NiagaraGetFloat_Internal(NiagaraGetHalfBuffer(), RegisterIdx, ParticleIdx);
}
else
{
return NiagaraGetFloat_Internal(NiagaraGetFloatBuffer(), RegisterIdx, ParticleIdx);
}
}
float2 NiagaraGetVec2(int RegisterIdx, uint ParticleIdx)
{
BRANCH
if (NiagaraGetIsHalfAndFixupRegister(RegisterIdx))
{
return NiagaraGetVec2_Internal(NiagaraGetHalfBuffer(), RegisterIdx, ParticleIdx);
}
else
{
return NiagaraGetVec2_Internal(NiagaraGetFloatBuffer(), RegisterIdx, ParticleIdx);
}
}
float3 NiagaraGetVec3(int RegisterIdx, uint ParticleIdx)
{
BRANCH
if (NiagaraGetIsHalfAndFixupRegister(RegisterIdx))
{
return NiagaraGetVec3_Internal(NiagaraGetHalfBuffer(), RegisterIdx, ParticleIdx);
}
else
{
return NiagaraGetVec3_Internal(NiagaraGetFloatBuffer(), RegisterIdx, ParticleIdx);
}
}
float4 NiagaraGetVec4(int RegisterIdx, uint ParticleIdx)
{
BRANCH
if (NiagaraGetIsHalfAndFixupRegister(RegisterIdx))
{
return NiagaraGetVec4_Internal(NiagaraGetHalfBuffer(), RegisterIdx, ParticleIdx);
}
else
{
return NiagaraGetVec4_Internal(NiagaraGetFloatBuffer(), RegisterIdx, ParticleIdx);
}
}
float NiagaraSafeGetFloat(int RegisterIdx, uint ParticleIdx, float Default)
{
// NOTE: Branch to prevent unnecessary loads
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetFloat(RegisterIdx, ParticleIdx);
}
}
float2 NiagaraSafeGetVec2(int RegisterIdx, uint ParticleIdx, float2 Default)
{
// NOTE: Branch to prevent unnecessary loads
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetVec2(RegisterIdx, ParticleIdx);
}
}
float3 NiagaraSafeGetVec3(int RegisterIdx, uint ParticleIdx, float3 Default)
{
// NOTE: Branch to prevent unnecessary loads
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetVec3(RegisterIdx, ParticleIdx);
}
}
float4 NiagaraSafeGetVec4(int RegisterIdx, uint ParticleIdx, float4 Default)
{
// NOTE: Branch to prevent unnecessary loads
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetVec4(RegisterIdx, ParticleIdx);
}
}
#if ENABLE_NIAGARA_INT_DATA_ACCESS
int NiagaraGetInt(int RegisterIdx, uint ParticleIdx)
{
return NiagaraGetIntBuffer()[RegisterIdx * NiagaraGetIntDataStride() + ParticleIdx];
}
int2 NiagaraGetInt2(int RegisterIdx, uint ParticleIdx)
{
return int2(NiagaraGetInt(RegisterIdx + 0, ParticleIdx),
NiagaraGetInt(RegisterIdx + 1, ParticleIdx));
}
int3 NiagaraGetInt3(int RegisterIdx, uint ParticleIdx)
{
return int3(NiagaraGetInt(RegisterIdx + 0, ParticleIdx),
NiagaraGetInt(RegisterIdx + 1, ParticleIdx),
NiagaraGetInt(RegisterIdx + 2, ParticleIdx));
}
int4 NiagaraGetInt4(int RegisterIdx, uint ParticleIdx)
{
return int4(NiagaraGetInt(RegisterIdx + 0, ParticleIdx),
NiagaraGetInt(RegisterIdx + 1, ParticleIdx),
NiagaraGetInt(RegisterIdx + 2, ParticleIdx),
NiagaraGetInt(RegisterIdx + 3, ParticleIdx));
}
int NiagaraSafeGetInt(int RegisterIdx, uint ParticleIdx, int Default)
{
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetInt(RegisterIdx, ParticleIdx);
}
}
int2 NiagaraSafeGetInt2(int RegisterIdx, uint ParticleIdx, int2 Default)
{
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetInt2(RegisterIdx, ParticleIdx);
}
}
int3 NiagaraSafeGetInt3(int RegisterIdx, uint ParticleIdx, int3 Default)
{
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetInt3(RegisterIdx, ParticleIdx);
}
}
int4 NiagaraSafeGetInt4(int RegisterIdx, uint ParticleIdx, int4 Default)
{
BRANCH
if (RegisterIdx == -1)
{
return Default;
}
else
{
return NiagaraGetInt4(RegisterIdx, ParticleIdx);
}
}
#endif // ENABLE_NIAGARA_INT_DATA_ACCESS