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

144 lines
4.3 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "NiagaraBaryCentricUtils.ush"
#define DISKELMESH_BONE_INFLUENCES_MAX4 0
#define DISKELMESH_BONE_INFLUENCES_MAX8 1
#define DISKELMESH_BONE_INFLUENCES_UNLIMITED 2
#ifndef DISKELMESH_BONE_INFLUENCES
#define DISKELMESH_BONE_INFLUENCES DISKELMESH_BONE_INFLUENCES_UNLIMITED
#endif
#define DISKELMESH_PROBALIAS_FORMAT_64 0 // 64 bits : Float probability : uint alias
#define DISKELMESH_PROBALIAS_FORMAT_24_8 1 // 32 bits : 8 bits probability : 24 bits alias
#define DISKELMESH_PROBALIAS_FORMAT_23_9 2 // 32 bits : 9 bits probability : 23 bits alias
#ifndef DISKELMESH_PROBALIAS_FORMAT
#define DISKELMESH_PROBALIAS_FORMAT DISKELMESH_PROBALIAS_FORMAT_64
#endif
#define DISKELMESH_ADJ_INDEX_FORMAT_FULL 0 // 32 bits
#define DISKELMESH_ADJ_INDEX_FORMAT_HALF 1 // 16 bits
#ifndef DISKELMESH_ADJ_INDEX_FORMAT
#define DISKELMESH_ADJ_INDEX_FORMAT DISKELMESH_ADJ_INDEX_FORMAT_FULL
#endif
#if FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1
#undef DISKELMESH_ALLOW_DEFORMED
#define DISKELMESH_ALLOW_DEFORMED 0
#endif
//-TODO: We need to consolodate the random interface inside NiagaraEmitterInstanceShader.usf it's a bit messy at the moment but should follow what FNDIRandomHelper does
float DISKelMesh_Random(uint S1, uint S2, uint S3)
{
return S3 == 0xffffffff ? NiagaraInternalNoise(S1, S2, S3) : rand(1.0f, S1, S2, S3);
}
struct FDISkelMeshSkinnedVertex
{
float3 Position;
float3 PrevPosition;
float3 TangentX;
float3 TangentY;
float3 TangentZ;
};
float3 DISKelMesh_RandomBarycentricCoord(uint Seed1, uint Seed2, uint Seed3)
{
float r0 = DISKelMesh_Random(Seed1, Seed2, Seed3);
float r1 = DISKelMesh_Random(Seed1, Seed2, Seed3);
float sqrt0 = sqrt(r0);
float sqrt1 = sqrt(r1);
return float3(1.0f - sqrt0, sqrt0 * (1.0 - r1), r1 * sqrt0);
}
int4 DISkelMesh_UnpackIndices4x8(uint Packed)
{
return int4(Packed & 0xff, Packed >> 8 & 0xff, Packed >> 16 & 0xff, Packed >> 24 & 0xff);
}
int4 DISkelMesh_UnpackIndices4x16(uint PackedA, uint PackedB)
{
return int4(PackedA & 0xffff, PackedA >> 16 & 0xffff, PackedB & 0xffff, PackedB >> 16 & 0xffff);
}
float4 DISkelMesh_UnpackWeights4x8(uint Packed)
{
return float4(Packed & 0xff, Packed >> 8 & 0xff, Packed >> 16 & 0xff, Packed >> 24 & 0xff) / 255.0f;
}
float4 DISkelMesh_UnpackWeights4x16(uint PackedA, uint PackedB)
{
return float4(PackedA & 0xffff, PackedA >> 16 & 0xffff, PackedB & 0xffff, PackedB >> 16 & 0xffff) / 65535.0f;
}
// UvMappingBuffer organized as an array of:
//struct FFrozenNode
//{
// int32 ChildOffsets[4]
// int32 ElementCount
// int32 TriangleIndices[]
//};
#define DISkelMesh_ElementCountOffset 4
#define DISkelMesh_TriangleIndexOffset 5
#define DISkelMesh_MinValidUvMappingBufferSize 24 // minimum size (in bytes) for a quadtree to have valid data
bool DISkelMesh_NormalizedAabbTriangleIntersection(float2 A, float2 B, float2 C)
{
float2 TriAabbMin = float2(min3(A.x, B.x, C.x), min3(A.y, B.y, C.y));
float2 TriAabbMax = float2(max3(A.x, B.x, C.x), max3(A.y, B.y, C.y));
if (any(TriAabbMin > 1.0f) || any(TriAabbMax < 0.0f))
{
return false;
}
#define AXIS_COUNT 3
float2 TriangleEdges[AXIS_COUNT] = { C - B, A - C, B - A };
for (int i = 0; i < AXIS_COUNT; ++i)
{
float2 Axis = TriangleEdges[i].yx * (float2(-1.0f, 0.0f));
float AabbSegmentMin = min(0.0f, min3(Axis.x, Axis.y, Axis.x + Axis.y));
float AabbSegmentMax = max(0.0f, max3(Axis.x, Axis.y, Axis.x + Axis.y));
float TriangleSegmentMin = min3(dot(A, Axis), dot(B, Axis), dot(C, Axis));
float TriangleSegmentMax = max3(dot(A, Axis), dot(B, Axis), dot(C, Axis));
if (AabbSegmentMin > TriangleSegmentMax || AabbSegmentMax < TriangleSegmentMin)
{
return false;
}
}
return true;
}
float4 DISKelMesh_QuatSlerp(float4 Quat1, float4 Quat2, float Slerp)
{
const float RawCosom = dot(Quat1, Quat2);
const float Cosom = abs(RawCosom);
float Scale0, Scale1;
if (Cosom < 0.9999f)
{
const float Omega = acos(Cosom);
const float InvSin = 1.f / sin(Omega);
Scale0 = sin((1.f - Slerp) * Omega) * InvSin;
Scale1 = sin(Slerp * Omega) * InvSin;
}
else
{
Scale0 = 1.0f - Slerp;
Scale1 = Slerp;
}
// In keeping with our flipped Cosom:
Scale1 = RawCosom >= 0.0f ? Scale1 : -Scale1;
return (Scale0 * Quat1) + (Scale1 * Quat2);
}