Files
project-reset/Assets/Plugins/HTraceSSGI/Resources/HTraceSSGI/Headers/HMath.hlsl
2025-12-31 12:44:11 -05:00

155 lines
3.5 KiB
HLSL

#pragma once
#define FLT_MIN 1.175494351e-38
#define FLT_MAX 3.402823466e+38
float3 HSafeNormalize(float3 inVec)
{
float dp3 = max(FLT_MIN, dot(inVec, inVec));
return inVec * rsqrt(dp3);
}
float HSinFromCos(float cosX)
{
return sqrt(saturate(1 - cosX * cosX));
}
float HFastSqrt(float x)
{
return (asfloat(0x1fbd1df5 + (asint(x) >> 1)));
}
float HFastACos( float inX )
{
float pi = 3.141593;
float half_pi = 1.570796;
float x = abs(inX);
float res = -0.156583 * x + half_pi;
res *= HFastSqrt(1.0 - x);
return (inX >= 0) ? res : pi - res;
}
float3x3 HGetLocalFrame(float3 localZ)
{
float x = localZ.x;
float y = localZ.y;
float z = localZ.z;
float sz = FastSign(z);
float a = 1 / (sz + z);
float ya = y * a;
float b = x * ya;
float c = x * sz;
float3 localX = float3(c * x * a - 1, sz * b, c);
float3 localY = float3(b, y * ya - sz, y);
return float3x3(localX, localY, localZ);
}
float2 HSampleDiskCubic(float u1, float u2)
{
float r = u1;
float phi = 6.28318530718f * u2;
float sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return r * float2(cosPhi, sinPhi);
}
float3 HSphericalToCartesian(float cosPhi, float sinPhi, float cosTheta)
{
float sinTheta = HSinFromCos(cosTheta);
return float3(float2(cosPhi, sinPhi) * sinTheta, cosTheta);
}
float3 HSphericalToCartesian(float phi, float cosTheta)
{
float sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return HSphericalToCartesian(cosPhi, sinPhi, cosTheta);
}
float3 HSampleSphereUniform(float u1, float u2)
{
float phi = 6.28318530718f * u2;
float cosTheta = 1.0 - 2.0 * u1;
return HSphericalToCartesian(phi, cosTheta);
}
float3 HSampleHemisphereCosine(float u1, float u2, float3 normal)
{
float3 pointOnSphere = HSampleSphereUniform(u1, u2);
return HSafeNormalize(normal + pointOnSphere);
}
float2 HLineBoxIntersect(float3 RayOrigin, float3 RayEnd, float3 BoxMin, float3 BoxMax)
{
float3 InvRayDir = 1.0f / (RayEnd - RayOrigin);
float3 FirstPlaneIntersections = (BoxMin - RayOrigin) * InvRayDir;
float3 SecondPlaneIntersections = (BoxMax - RayOrigin) * InvRayDir;
float3 ClosestPlaneIntersections = min(FirstPlaneIntersections, SecondPlaneIntersections);
float3 FurthestPlaneIntersections = max(FirstPlaneIntersections, SecondPlaneIntersections);
float2 BoxIntersections;
BoxIntersections.x = max(ClosestPlaneIntersections.x, max(ClosestPlaneIntersections.y, ClosestPlaneIntersections.z));
BoxIntersections.y = min(FurthestPlaneIntersections.x, min(FurthestPlaneIntersections.y, FurthestPlaneIntersections.z));
return saturate(BoxIntersections);
}
float HUintToFloat01(uint h)
{
static const uint MantissaMask = 0x007FFFFFu;
static const uint One = 0x3F800000u;
h &= MantissaMask;
h |= One;
float r2 = asfloat(h);
return r2 - 1.0;
}
uint Hash_Combine(uint x, uint y)
{
static const uint M = 1664525u, C = 1013904223u;
uint seed = (x * M + y + C) * M;
seed ^= (seed >> 11u);
seed ^= (seed << 7u) & 0x9d2c5680u;
seed ^= (seed << 15u) & 0xefc60000u;
seed ^= (seed >> 18u);
return seed;
}
uint Hash1(uint x)
{
x += (x << 10u);
x ^= (x >> 6u);
x += (x << 3u);
x ^= (x >> 11u);
x += (x << 15u);
return x;
}
uint Hash2(uint2 v)
{
return Hash_Combine(v.x, Hash1(v.y));
}
uint Hash3(uint3 v)
{
return Hash_Combine(v.x, Hash2(v.yz));
}
uint Hash1Mutate(inout uint h)
{
uint Res = h;
h = Hash1(h);
return Res;
}