276 lines
7.6 KiB
HLSL
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 |