public override bool Scatter(Ray r, HitRecord hitRecord, out Vector3 attenuation, out Ray scattered) { Vector3 reflected = VectorHelpers.Reflect(r.Direction.GetUnitVector(), hitRecord.SurfaceNormal); scattered = new Ray(hitRecord.HitPoint, reflected + Fuzz * VectorHelpers.GetRandomInUnitSphere()); attenuation = Albedo; return(Vector3.Dot(scattered.Direction, hitRecord.SurfaceNormal) > 0); }
public override bool Scatter(Ray r, HitRecord hitRecord, out Vector3 attenuation, out Ray scattered) { attenuation = Vector3.One; Vector3 reflected = VectorHelpers.Reflect(r.Direction, hitRecord.SurfaceNormal); Vector3 outwardNormal; float niOverNt; float cosine; if (Vector3.Dot(r.Direction, hitRecord.SurfaceNormal) > 0) { outwardNormal = -hitRecord.SurfaceNormal; niOverNt = RefractiveIndex; cosine = RefractiveIndex * Vector3.Dot(r.Direction, hitRecord.SurfaceNormal) / r.Direction.Length(); } else { outwardNormal = hitRecord.SurfaceNormal; niOverNt = 1.0f / RefractiveIndex; cosine = -Vector3.Dot(r.Direction, hitRecord.SurfaceNormal) / r.Direction.Length(); } float reflectProb = 1.0f; if (Refract(r.Direction, outwardNormal.GetUnitVector(), niOverNt, out Vector3 refracted)) { reflectProb = Schlick(cosine); } if (VectorHelpers.RandomFloat() < reflectProb) { scattered = new Ray(hitRecord.HitPoint, reflected); } else { scattered = new Ray(hitRecord.HitPoint, refracted); } return(true); }