Files
UnrealEngine/Engine/Shaders/Private/HairStrands/HairStrandsAABBCommon.ush
2025-05-18 13:04:45 +08:00

125 lines
3.8 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#define HAIR_AABB_PRECISION_SCALE 1000.f
struct FHairAABB
{
float3 Min;
float3 Max;
};
float3 GetCenter(const FHairAABB In)
{
return (In.Min + In.Max) * 0.5f;
}
float3 GetExtents(const FHairAABB In)
{
return (In.Max - In.Min) * 0.5f;
}
FHairAABB InitHairAABB()
{
FHairAABB O;
O.Min = float3(2147483647, 2147483647, 2147483647);
O.Max = float3(-2147483647, -2147483647, -2147483647);
return O;
}
FHairAABB Transform(const FHairAABB In, float4x4 T)
{
float4 P00 = float4(In.Min.x, In.Min.y, In.Min.z, 1);
float4 P10 = float4(In.Max.x, In.Min.y, In.Min.z, 1);
float4 P20 = float4(In.Max.x, In.Max.y, In.Min.z, 1);
float4 P30 = float4(In.Min.x, In.Max.y, In.Min.z, 1);
float4 P01 = float4(In.Min.x, In.Min.y, In.Max.z, 1);
float4 P11 = float4(In.Max.x, In.Min.y, In.Max.z, 1);
float4 P21 = float4(In.Max.x, In.Max.y, In.Max.z, 1);
float4 P31 = float4(In.Min.x, In.Max.y, In.Max.z, 1);
P00 = mul(P00, T); P00 /= P00.w;
P10 = mul(P10, T); P10 /= P10.w;
P20 = mul(P20, T); P20 /= P20.w;
P30 = mul(P30, T); P30 /= P30.w;
P01 = mul(P01, T); P01 /= P01.w;
P11 = mul(P11, T); P11 /= P11.w;
P21 = mul(P21, T); P21 /= P21.w;
P31 = mul(P31, T); P31 /= P31.w;
FHairAABB Out;
Out.Min = min(P00.xyz, min(P10.xyz, min(P20.xyz, P30.xyz)));
Out.Min = min(P01.xyz, min(P11.xyz, min(P21.xyz, min(P31.xyz, Out.Min))));
Out.Max = max(P00.xyz, max(P10.xyz, max(P20.xyz, P30.xyz)));
Out.Max = max(P01.xyz, max(P11.xyz, max(P21.xyz, max(P31.xyz, Out.Max))));
return Out;
}
FHairAABB ReadHairAABB(uint Index, RWBuffer<int> InBuffer, float PrecisionScale = HAIR_AABB_PRECISION_SCALE)
{
const uint Index6 = Index * 6;
FHairAABB O;
O.Min.x = InBuffer[Index6 + 0] / PrecisionScale;
O.Min.y = InBuffer[Index6 + 1] / PrecisionScale;
O.Min.z = InBuffer[Index6 + 2] / PrecisionScale;
O.Max.x = InBuffer[Index6 + 3] / PrecisionScale;
O.Max.y = InBuffer[Index6 + 4] / PrecisionScale;
O.Max.z = InBuffer[Index6 + 5] / PrecisionScale;
return O;
}
FHairAABB ReadHairAABB(uint Index, Buffer<int> InBuffer, float PrecisionScale = HAIR_AABB_PRECISION_SCALE)
{
const uint Index6 = Index * 6;
FHairAABB O;
O.Min.x = InBuffer[Index6 + 0] / PrecisionScale;
O.Min.y = InBuffer[Index6 + 1] / PrecisionScale;
O.Min.z = InBuffer[Index6 + 2] / PrecisionScale;
O.Max.x = InBuffer[Index6 + 3] / PrecisionScale;
O.Max.y = InBuffer[Index6 + 4] / PrecisionScale;
O.Max.z = InBuffer[Index6 + 5] / PrecisionScale;
return O;
}
void WriteHairAABB(uint Index, FHairAABB In, RWBuffer<int> OutBuffer, float PrecisionScale = HAIR_AABB_PRECISION_SCALE)
{
const uint Index6 = Index * 6;
OutBuffer[Index6 + 0] = int(In.Min.x * PrecisionScale);
OutBuffer[Index6 + 1] = int(In.Min.y * PrecisionScale);
OutBuffer[Index6 + 2] = int(In.Min.z * PrecisionScale);
OutBuffer[Index6 + 3] = int(In.Max.x * PrecisionScale);
OutBuffer[Index6 + 4] = int(In.Max.y * PrecisionScale);
OutBuffer[Index6 + 5] = int(In.Max.z * PrecisionScale);
}
FHairAABB UnionHairAABB(FHairAABB A, FHairAABB B)
{
FHairAABB O;
O.Min.x = min(A.Min.x, B.Min.x);
O.Min.y = min(A.Min.y, B.Min.y);
O.Min.z = min(A.Min.z, B.Min.z);
O.Max.x = max(A.Max.x, B.Max.x);
O.Max.y = max(A.Max.y, B.Max.y);
O.Max.z = max(A.Max.z, B.Max.z);
return O;
}
void InterlockHairAABB(uint Index, FHairAABB In, RWBuffer<int> OutBuffer, float PrecisionScale = HAIR_AABB_PRECISION_SCALE)
{
const uint Index6 = Index * 6;
InterlockedMin(OutBuffer[Index6 + 0], int(In.Min.x * PrecisionScale));
InterlockedMin(OutBuffer[Index6 + 1], int(In.Min.y * PrecisionScale));
InterlockedMin(OutBuffer[Index6 + 2], int(In.Min.z * PrecisionScale));
InterlockedMax(OutBuffer[Index6 + 3], int(In.Max.x * PrecisionScale));
InterlockedMax(OutBuffer[Index6 + 4], int(In.Max.y * PrecisionScale));
InterlockedMax(OutBuffer[Index6 + 5], int(In.Max.z * PrecisionScale));
}