Files
FlaxEngine/Source/Shaders/Math.hlsl
2022-06-28 14:41:29 +02:00

259 lines
4.0 KiB
HLSL

// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#ifndef __MATH__
#define __MATH__
uint NextPow2(uint value)
{
uint mask = (1 << firstbithigh(value)) - 1;
return (value + mask) & ~mask;
}
float3 SafeNormalize(float3 v)
{
return v / sqrt(max(dot(v, v), 0.01));
}
float3 ExtractLargestComponent(float3 v)
{
float3 a = abs(v);
if (a.x > a.y)
{
if (a.x > a.z)
{
return float3(v.x > 0 ? 1 : -1, 0, 0);
}
}
else
{
if (a.y > a.z)
{
return float3(0, v.y > 0 ? 1 : -1, 0);
}
}
return float3(0, 0, v.z > 0 ? 1 : -1);
}
float Square(float x)
{
return x * x;
}
float2 Square(float2 x)
{
return x * x;
}
float3 Square(float3 x)
{
return x * x;
}
float4 Square(float4 x)
{
return x * x;
}
float Min2(float2 x)
{
return min(x.x, x.y);
}
float Min3(float3 x)
{
return min(x.x, min(x.y, x.z));
}
float Min4(float4 x)
{
return min(x.x, min(x.y, min(x.z, x.w)));
}
float Max2(float2 x)
{
return max(x.x, x.y);
}
float Max3(float3 x)
{
return max(x.x, max(x.y, x.z));
}
float Max4(float4 x)
{
return max(x.x, max(x.y, max(x.z, x.w)));
}
float Pow2(float x)
{
return x * x;
}
float2 Pow2(float2 x)
{
return x * x;
}
float3 Pow2(float3 x)
{
return x * x;
}
float4 Pow2(float4 x)
{
return x * x;
}
float Pow3(float x)
{
return x * x * x;
}
float2 Pow3(float2 x)
{
return x * x * x;
}
float3 Pow3(float3 x)
{
return x * x * x;
}
float4 Pow3(float4 x)
{
return x * x * x;
}
float Pow4(float x)
{
float xx = x * x;
return xx * xx;
}
float2 Pow4(float2 x)
{
float2 xx = x * x;
return xx * xx;
}
float3 Pow4(float3 x)
{
float3 xx = x * x;
return xx * xx;
}
float4 Pow4(float4 x)
{
float4 xx = x * x;
return xx * xx;
}
float Pow5(float x)
{
float xx = x * x;
return xx * xx * x;
}
float2 Pow5(float2 x)
{
float2 xx = x * x;
return xx * xx * x;
}
float3 Pow5(float3 x)
{
float3 xx = x * x;
return xx * xx * x;
}
float4 Pow5(float4 x)
{
float4 xx = x * x;
return xx * xx * x;
}
float Pow6(float x)
{
float xx = x * x;
return xx * xx * xx;
}
float2 Pow6(float2 x)
{
float2 xx = x * x;
return xx * xx * xx;
}
float3 Pow6(float3 x)
{
float3 xx = x * x;
return xx * xx * xx;
}
float4 Pow6(float4 x)
{
float4 xx = x * x;
return xx * xx * xx;
}
float ClampedPow(float x, float y)
{
return pow(max(abs(x), 0.000001f), y);
}
float2 ClampedPow(float2 x, float2 y)
{
return pow(max(abs(x), float2(0.000001f, 0.000001f)), y);
}
float3 ClampedPow(float3 x, float3 y)
{
return pow(max(abs(x), float3(0.000001f, 0.000001f, 0.000001f)), y);
}
float4 ClampedPow(float4 x, float4 y)
{
return pow(max(abs(x), float4(0.000001f, 0.000001f, 0.000001f, 0.000001f)), y);
}
float4 FindQuatBetween(float3 from, float3 to)
{
float normAB = 1.0f;
float w = normAB + dot(from, to);
float4 result;
if (w >= 1e-6f * normAB)
{
result = float4
(
from.y * to.z - from.z * to.y,
from.z * to.x - from.x * to.z,
from.x * to.y - from.y * to.x,
w
);
}
else
{
w = 0.f;
result = abs(from.x) > abs(from.y)
? float4(-from.z, 0.f, from.x, w)
: float4(0.f, -from.z, from.y, w);
}
return normalize(result);
}
// Rotates Position about the given axis by the given angle, in radians, and returns the offset to position
float3 RotateAboutAxis(float4 normalizedRotationAxisAndAngle, float3 positionOnAxis, float3 position)
{
float3 pointOnAxis = positionOnAxis + normalizedRotationAxisAndAngle.xyz * dot(normalizedRotationAxisAndAngle.xyz, position - positionOnAxis);
float3 axisU = position - pointOnAxis;
float3 axisV = cross(normalizedRotationAxisAndAngle.xyz, axisU);
float cosAngle, sinAngle;
sincos(normalizedRotationAxisAndAngle.w, sinAngle, cosAngle);
float3 rotation = axisU * cosAngle + axisV * sinAngle;
return pointOnAxis + rotation - position;
}
#endif