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.

88 lines
2.4 KiB
HLSL

/******************************************************************************/
/*
Project - MudBun
Publisher - Long Bunny Labs
http://LongBunnyLabs.com
Author - Ming-Lun "Allen" Chou
http://AllenChou.net
*/
/******************************************************************************/
#ifndef MUDBUN_GEOMETRY
#define MUDBUN_GEOMETRY
#include "MathConst.cginc"
#include "Vector.cginc"
float ray_plane_intersect(float3 ro, float3 rd, float3 n)
{
float rdn = dot(rd, n);
return (abs(rdn) > kEpsilon) ? (dot(-ro, n) / rdn) : -1.0f;
}
float3 plane_gradient(float3 p, float3 n)
{
return sign(dot(p, n)) * n;
}
// https://link.springer.com/content/pdf/10.1007%2F978-1-4842-4427-2_7.pdf
float2 ray_sphere_intersect(float3 ro, float3 rd, float r)
{
float b = dot(ro, rd); b += b;
float3 v = ro - dot(ro, rd) * rd;
float d = 4.0f * dot(rd, rd) * (r * r - dot(v, v));
if (d <= 0.0f)
return float2(-1.0f, -1.0f);
float2 t = 0.5f * (-b + float2(1.0f, -1.0f) * sqrt(d));
return (t.x <= t.y) ? t : t.yx;
}
float3 sphere_gradient(float3 ro)
{
return normalize(ro);
}
// https://www.iquilezles.org/www/articles/boxfunctions/boxfunctions.htm
float2 ray_box_intersect_fast_raw(float3 ro, float3 m, float3 k, float3 boxCenter)
{
ro -= boxCenter;
float3 n = m * ro;
bool3 mValid = (m < kFltMax);
float3 tMin = mValid ? (-n - k) : -kFltMax;
float3 tMax = mValid ? (-n + k) : kFltMax;
float tNear = max_comp(tMin);
float tFar = min_comp(tMax);
return float2(tNear, tFar);
}
float2 ray_box_intersect_fast(float3 ro, float3 m, float3 k, float3 boxCenter)
{
ro -= boxCenter;
float3 n = m * ro;
bool3 mValid = (m < kFltMax);
float3 tMin = mValid ? (-n - k) : -kFltMax;
float3 tMax = mValid ? (-n + k) : kFltMax;
float tNear = max_comp(tMin);
float tFar = min_comp(tMax);
return (tNear <= tFar && tFar >= 0.0f) ? float2(tNear, tFar) : float2(-1.0f, -1.0f);
}
float2 ray_box_intersect(float3 ro, float3 rd, float3 boxCenter, float3 boxExtents)
{
float3 m = 1.0f / rd;
float3 k = abs(m) * boxExtents;
return ray_box_intersect_fast(ro, m, k, boxCenter);
}
float3 box_gradient(float3 p, float3 boxCenter, float3 boxExtents)
{
p -= boxCenter;
float3 d = abs(p) - boxExtents;
float3 s = p >= 0.0f ? float3(1.0f, 1.0f, 1.0f) : float3(-1.0f, -1.0f, -1.0f);
float g = max_comp(d);
return s * ((g > 0.0) ? normalize(max(d, 0.0f)) : step(d.yzx, d.xyz) * step(d.zxy, d.xyz));
}
#endif