/******************************************************************************/ /* 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