public bool Scatter(Ray rayIn, ref HitRecord rec, out color attenuation, out Ray scattered) { attenuation = new color(1.0, 1.0, 1.0); double etai_over_etat = rec.isFrontFace ? 1.0 / ref_idx : ref_idx; var unit_direction = rayIn.Direction.unit_vector(); var cos_theta = Math.Min(Vec3.dot(-unit_direction, rec.normal), 1.0); var sin_theta = Math.Sqrt(1 - cos_theta * cos_theta); if (etai_over_etat * sin_theta > 1) { var reflected = RayTracer.Reflect(unit_direction, rec.normal); scattered = new Ray(rec.p, reflected); return(true); } var reflect_prob = schlick(cos_theta, etai_over_etat); if (RayTracer.RandomDouble() < reflect_prob) { var reflected = RayTracer.Reflect(unit_direction, rec.normal); scattered = new Ray(rec.p, reflected); return(true); } var refracted = RayTracer.Refract(unit_direction, rec.normal, etai_over_etat); scattered = new Ray(rec.p, refracted); return(true); }
public bool Scatter(Ray rayIn, ref HitRecord rec, out color attenuation, out Ray scattered) { Vec3 reflect = RayTracer.Reflect(rayIn.Direction.unit_vector(), rec.normal); scattered = new Ray(rec.p, reflect + roughness * RayTracer.RandomInUnitSphere()); attenuation = albedo; return(Vec3.dot(scattered.Direction, rec.normal) > 0); }