public override bool Scatter(ref Ray rIn, ref HitRecord rec, ref Point3 attenuation, ref Ray scattered) { attenuation = Colour.One; float refractionRatio = rec.FrontFace ? (1f / IR) : IR; Vector3 unitDirection = Vector3.Normalize(rIn.Direction); float cosTheta = MathF.Min(Vector3.Dot(-unitDirection, rec.Normal), 1f); float sinTheta = MathF.Sqrt(1f - cosTheta * cosTheta); bool cannotRefract = refractionRatio * sinTheta > 1.0; Vector3 direction; if (cannotRefract || Reflectance(cosTheta, refractionRatio) > Program.random.NextDouble()) { direction = Program.VecReflect(unitDirection, rec.Normal); } else { direction = Program.VecRefract(unitDirection, rec.Normal, refractionRatio); } scattered = new Ray(rec.P, direction); return(true); }
public override bool Hit(Ray r, float tMin, float tMax, ref HitRecord rec) { Vector3 oc = r.Origin - Centre; float a = r.Direction.LengthSquared(); float halfB = Vector3.Dot(oc, r.Direction); float c = oc.LengthSquared() - Radius * Radius; float discriminant = halfB * halfB - a * c; if (discriminant < 0) { return(false); } float sqrtd = MathF.Sqrt(discriminant); // Find the nearest root that lies in the acceptable range. float root = (-halfB - sqrtd) / a; if (root < tMin || tMax < root) { root = (-halfB + sqrtd) / a; if (root < tMin || tMax < root) { return(false); } } rec.T = root; rec.P = r.At(rec.T); Vector3 outwardNormal = (rec.P - Centre) / Radius; rec.SetFaceNormal(r, outwardNormal); rec.Mat = Mat; return(true); }
public abstract bool Scatter(ref Ray rIn, ref HitRecord rec, ref Colour attenuation, ref Ray scattered);
public abstract bool Hit(Ray r, float t_min, float t_max, ref HitRecord rec);