public override zwischenSpeicher scatter(ray r_in, hit_record rec, Vektor attenuation, ray scattered) { zwischenSpeicher zw = new zwischenSpeicher(); attenuation = new Vektor(1, 1, 1); double refraction_ratio = rec.front_face ? (1 / ir) : ir; Vektor unit_direction = Vektor.unit_Vektor(r_in.Direction); double cos_theta = Math.Min(Vektor.dot(unit_direction * -1, rec.normal), 1); double sin_theta = Math.Sqrt(1 - cos_theta * cos_theta); bool cannot_refract = refraction_ratio * sin_theta > 1; Vektor direction; if (cannot_refract) { direction = Vektor.reflect(unit_direction, rec.normal); } else { direction = Vektor.refract(unit_direction, rec.normal, refraction_ratio); } scattered = new ray(rec.p, direction); zw.attenuation = attenuation; zw.scattered = scattered; zw.IsTrue = true; return(zw); }
public static Vektor refract(Vektor uv, Vektor n, double etai_over_etat) { var cos_theta = Math.Min(Vektor.dot(uv * -1, n), 1); Vektor r_out_perp = etai_over_etat * (uv + cos_theta * n); Vektor r_out_parallel = -Math.Sqrt(Math.Abs(1 - r_out_perp.length_squared())) * n; return(r_out_perp + r_out_parallel); }
public static double hit_sphere(Vektor center, double radius, ray r) { Vektor oc = r.Origin - center; var a = r.Direction.length_squared(); var half_b = Vektor.dot(oc, r.Direction); var c = oc.length_squared() - radius * radius; var discriminant = half_b * half_b - a * c; if (discriminant < 0) { return(-1); } else { return((-half_b - Math.Sqrt(discriminant)) / a); } }
public override zwischenSpeicher Hit(ray r, double t_min, double t_max, hit_record rec) { zwischenSpeicher zw = new zwischenSpeicher(); Vektor oc = r.Origin - center; var a = r.Direction.length_squared(); var half_b = Vektor.dot(oc, r.Direction); var c = oc.length_squared() - radius * radius; var discriminant = half_b * half_b - a * c; if (discriminant < 0) { zw.IsTrue = false; return(zw); } var sqrtd = Math.Sqrt(discriminant); var root = (-half_b - sqrtd) / a; if (root < t_min || t_max < root) { root = (-half_b + sqrtd) / a; if (root < t_min || t_max < root) { zw.IsTrue = false; return(zw); } } rec.t = root; rec.p = r.at(rec.t); Vektor outward_normal = (rec.p - center) / radius; rec.set_face_normal(r, outward_normal); rec.mat_ptr = mat_ptr; zw.rec = rec; zw.IsTrue = true; return(zw); }