You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.7 KiB
HLSL
173 lines
4.7 KiB
HLSL
/******************************************************************************/
|
|
/*
|
|
Project - MudBun
|
|
Publisher - Long Bunny Labs
|
|
http://LongBunnyLabs.com
|
|
Author - Ming-Lun "Allen" Chou
|
|
http://AllenChou.net
|
|
*/
|
|
/******************************************************************************/
|
|
|
|
#ifndef MUDBUN_SDF_OPERATORS
|
|
#define MUDBUN_SDF_OPERATORS
|
|
|
|
#include "../Math/MathConst.cginc"
|
|
|
|
// http://www.iquilezles.org/www/articles/smin/smin.htm
|
|
// http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
|
// http://mercury.sexy/hg_sdf
|
|
|
|
#define SQRT_2_INV (0.70710678118f)
|
|
#define ONE_OVER_4 (0.25f)
|
|
#define ONE_OVER_6 (0.16666666666f)
|
|
|
|
// union
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// raw union
|
|
float sdf_uni(float a, float b)
|
|
{
|
|
return min(a, b);
|
|
}
|
|
|
|
// smooth quadratic polynomial union (C1 continuity, order-dependent concatenation)
|
|
float sdf_uni_quad(float a, float b, float k)
|
|
{
|
|
float h = max(k - abs(a - b), 0.0f) / max(k, kEpsilon);
|
|
return min(a, b) - h * h * k * ONE_OVER_4;
|
|
}
|
|
|
|
// smooth cubic polynomial union (C2 continuity, order-dependent concatenation)
|
|
float sdf_uni_cubic(float a, float b, float k)
|
|
{
|
|
float h = max(k - abs(a - b), 0.0f) / max(k, kEpsilon);
|
|
return min(a, b) - h * h * h * k * ONE_OVER_6;
|
|
}
|
|
|
|
float sdf_uni_round(float a, float b, float r)
|
|
{
|
|
float2 u = max(float2(r - a, r - b), float2(0.0f, 0.0f));
|
|
return max(r, min(a, b)) - length(u);
|
|
}
|
|
|
|
float sdf_uni_chamfer(float a, float b, float r)
|
|
{
|
|
return min(min(a, b), (a - r + b) * SQRT_2_INV);
|
|
}
|
|
|
|
// smooth exponential union (infinite continuity, order-independent concatenation)
|
|
// max(k, kEpsilon); = 30.0f is a good default
|
|
#define sdf_uni_exp_concat_term(x, k) (exp2(-(k) * (x)))
|
|
#define sdf_uni_exp_concat_res(sum, k) (-log2(sum) / (k))
|
|
float sdf_uni_exp(float a, float b, float k) // 2-term concatenation
|
|
{
|
|
float sum = sdf_uni_exp_concat_term(a, k) + sdf_uni_exp_concat_term(b, k);
|
|
return sdf_uni_exp_concat_res(sum, k);
|
|
}
|
|
|
|
// smooth power union (infinite continuity, order-independent concatenation)
|
|
// max(k, kEpsilon); = 8.0f is a good default
|
|
#define sdf_uni_pow_concat_term(x, k) (pow((x), (k)))
|
|
#define sdf_uni_pow_concat_res(sum, prod, k) pow((prod) / (sum), 1.0f / (k))
|
|
float sdf_uni_pow(float a, float b, float k) // 2-term concatenation
|
|
{
|
|
a = sdf_uni_pow_concat_term(a, k);
|
|
b = sdf_uni_pow_concat_term(b, k);
|
|
return sdf_uni_pow_concat_res(a + b, a * b, k);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// end: union
|
|
|
|
|
|
// intersection
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// raw intersection
|
|
float sdf_int(float a, float b)
|
|
{
|
|
return max(a, b);
|
|
}
|
|
|
|
// smooth quadratic polynomial intersection (C1 continuity, order-dependent concatenation)
|
|
float sdf_int_quad(float a, float b, float k)
|
|
{
|
|
float h = max(k - abs(a - b), 0.0f) / max(k, kEpsilon);
|
|
return max(a, b) + h * h * k * ONE_OVER_4;
|
|
}
|
|
|
|
// smooth cubic polynomial intersection (C2 continuity, order-dependent concatenation)
|
|
float sdf_int_cubic(float a, float b, float k)
|
|
{
|
|
float h = max(k - abs(a - b), 0.0f) / max(k, kEpsilon);
|
|
return max(a, b) + h * h * h * k * ONE_OVER_6;
|
|
}
|
|
|
|
float sdf_int_round(float a, float b, float r)
|
|
{
|
|
float2 u = max(float2(r + a, r + b), float2(0.0f, 0.0f));
|
|
return min(-r, max(a, b)) + length(u);
|
|
}
|
|
|
|
float sdf_int_chamfer(float a, float b, float r)
|
|
{
|
|
return max(max(a, b), (a + r + b) * SQRT_2_INV);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// end: intersection
|
|
|
|
|
|
// subtraction
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// raw subtraction
|
|
float sdf_sub(float a, float b)
|
|
{
|
|
return max(a, -b);
|
|
}
|
|
|
|
// smooth quadratic polynomial subtraction (C1 continuity, order-dependent concatenation)
|
|
float sdf_sub_quad(float a, float b, float k)
|
|
{
|
|
return sdf_int_quad(a, -b, k);
|
|
}
|
|
|
|
// smooth cubic polynomial subtraction (C2 continuity, order-dependent concatenation)
|
|
float sdf_sub_cubic(float a, float b, float k)
|
|
{
|
|
return sdf_int_cubic(a, -b, k);
|
|
}
|
|
|
|
float sdf_sub_round(float a, float b, float r)
|
|
{
|
|
return sdf_int_round(a, -b, r);
|
|
}
|
|
|
|
float sdf_sub_chamfer(float a, float b, float r)
|
|
{
|
|
return sdf_int_chamfer(a, -b, r);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// end: subtraction
|
|
|
|
|
|
// misc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
float sdf_pipe(float a, float b, float r)
|
|
{
|
|
return length(float2(a, b)) - r;
|
|
}
|
|
|
|
float sdf_engrave(float a, float b, float r)
|
|
{
|
|
return max(a, (a + r - abs(b))) * SQRT_2_INV;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// end: misc.
|
|
|
|
#endif
|