public static bool Disk(Disk d, Ray3f r, float tMin, float tMax, out HitRecord hit) { hit = new HitRecord(); if (Plane(d.Plane, r, tMin, tMax, out hit)) { var offset = (hit.point - d.Plane.Center); if (math.dot(offset, offset) <= d.Radius * d.Radius) { return(true); } } return(false); }
public static bool Plane(Plane p, Ray3f r, float tMin, float tMax, out HitRecord hit) { hit = new HitRecord(); const float eps = 0.0001f; if (math.abs(math.dot(r.direction, p.Normal)) > eps) { float t = math.dot((p.Center - r.origin), p.Normal) / math.dot(r.direction, p.Normal); if (t > eps) { hit.t = t; hit.point = PointOnRay(r, t); hit.normal = p.Normal; return(true); } } return(false); }
public static bool Scatter(Ray3f ray, HitRecord hit, ref Random rng, NativeArray <float3> fibs, out Ray3f scattered) { const float epsEscape = 0.002f; const float refIdx = 1.5f; switch (hit.material.Type) { case MaterialType.Dielectric: { float3 outwardNormal; float nint; float3 reflected = math.reflect(ray.direction, hit.normal); float cosine; if (math.dot(ray.direction, hit.normal) > 0f) { outwardNormal = -hit.normal; nint = refIdx; cosine = refIdx * math.dot(ray.direction, hit.normal); } else { outwardNormal = hit.normal; nint = 1f / refIdx; cosine = -math.dot(ray.direction, hit.normal); } float reflectProb = 1f; float3 refracted; if (Trace.Refract(ray.direction, outwardNormal, nint, out refracted)) { reflectProb = Trace.Schlick(cosine, refIdx); } bool reflect = rng.NextFloat() < reflectProb; scattered = new Ray3f( reflect ? hit.point + outwardNormal * epsEscape : hit.point - outwardNormal * epsEscape, reflect ? reflected : refracted ); return(true); } case MaterialType.Metal: { float3 transmitted = math.reflect(ray.direction, hit.normal); transmitted += fibs[rng.NextInt(0, fibs.Length - 1)] * hit.material.Fuzz; transmitted = math.normalize(transmitted); scattered = new Ray3f(hit.point + hit.normal * epsEscape, transmitted); if (math.dot(scattered.direction, hit.normal) > 0) { return(true); } return(false); } case MaterialType.Lambertian: default: { float3 target = hit.normal + fibs[rng.NextInt(0, fibs.Length - 1)]; float3 transmitted = math.normalize(target - hit.point); scattered = new Ray3f(hit.point + hit.normal * epsEscape, transmitted); return(true); } } }
public static float3 PointOnRay(Ray3f r, float t) { return(r.origin + r.direction * t); }