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); }
// if no object is hit, draw a gradient static Vector3 color(Ray r, Hitable world, int depth) { hit_record rec = new hit_record(); // see if an object is hit if (world.hit(r, 0.001f, float.MaxValue, ref rec)) { // shade the indicated point Ray scattered = new Ray(); Vector3 attenuation = new Vector3(); if (depth < 50 && rec.mat.scatter(r, rec, ref attenuation, ref scattered)) { return(attenuation * color(scattered, world, depth + 1)); } else { // reached our max depth, don't render any further return(new Vector3()); } } else { // no object hit, draw the background Vector3 unit_dir = r.direction().unit_vector(); float t = 0.5f * (unit_dir.y() + 1.0f); return((new Vector3(1.0f, 1.0f, 1.0f)) * (1.0f - t) + (new Vector3(0.5f, 0.7f, 1.0f) * t)); } }
public static Vektor ray_color(ray r, hittable world, int depth) { hit_record rec = new hit_record(); if (depth <= 0) { return(new Vektor(0, 0, 0)); } zwischenSpeicher zw = world.Hit(r, 0.0001, Mathe.infinity, rec); if (zw.IsTrue) { rec = zw.rec; ray scattered = new ray(); Vektor attenuation = new Vektor(); zwischenSpeicher zw1 = rec.mat_ptr.scatter(r, rec, attenuation, scattered); if (zw1.IsTrue) { attenuation = zw1.attenuation; scattered = zw1.scattered; return(attenuation * ray_color(scattered, world, depth - 1)); } return(new Vektor(0, 0, 0)); } Vektor unit_direction = Vektor.unit_Vektor(r.Direction); var t = 0.5 * (unit_direction.Y + 1); Vektor col = (1 - t) * new Vektor(1, 1, 1) + t * new Vektor(0.5, 0.7, 1); return(col); }
public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec) { Vector3 oc = r.origin() - center(r._time); float a = Vector3.dot(r.direction(), r.direction()); float b = 2.0f * Vector3.dot(oc, r.direction()); float c = Vector3.dot(oc, oc) - radius * radius; float discriminant = b * b - 4 * a * c; if (discriminant > 0) { // update the hit_record to pass the information back to the calling object float temp = (-b - (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a); // check the roots if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point(rec.t); rec.normal = (rec.p - center(r._time)) / radius; rec.mat = material; return(true); } temp = (-b + (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a); if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point(rec.t); rec.normal = (rec.p - center(r._time)) / radius; rec.mat = material; return(true); } } return(false); }
public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered) { Vector3 target = rec.normal + Utils.random_in_unit_sphere(); scattered = new Ray(rec.p, target); attenuation = abledo.value(0.0f, 0.0f, ref rec.p); return(true); }
public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered) { Vector3 reflected = Utils.reflect(r_in.direction().unit_vector(), rec.normal); scattered = new Ray(rec.p, reflected + fuzz * Utils.random_in_unit_sphere()); attenuation = abledo.value(0.0f, 0.0f, ref rec.p); return(Vector3.dot(scattered.direction(), rec.normal) > 0.0f); }
public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered) { Vector3 outward_norm; Vector3 reflected = Utils.reflect(r_in.direction(), rec.normal); float ni_over_nt; attenuation = new Vector3(1.0f, 1.0f, 1.0f); Vector3 refracted = new Vector3(); float reflect_prob = 0.0f; float cosine = 0.0f; if (Vector3.dot(r_in.direction(), rec.normal) > 0.0f) { outward_norm = -1.0f * rec.normal; ni_over_nt = reflect_index; cosine = reflect_index * Vector3.dot(r_in.direction(), rec.normal) / r_in.direction().length(); } else { outward_norm = rec.normal; ni_over_nt = 1.0f / reflect_index; cosine = -1.0f * Vector3.dot(r_in.direction(), rec.normal) / r_in.direction().length(); } // determine probability for reflecting vs refracting based on if a refraction is possible if (Utils.refract(r_in.direction(), outward_norm, ni_over_nt, ref refracted)) { reflect_prob = Utils.schlick(cosine, reflect_index); } else { scattered = new Ray(rec.p, reflected); reflect_prob = 1.0f; } // decide whether to reflect or refract if (Utils.rnd.NextDouble() < reflect_prob) { scattered = new Ray(rec.p, reflected); } else { scattered = new Ray(rec.p, refracted); } return(true); }
public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec) { hit_record temp_rec = new hit_record(); bool hit_anything = false; float closest = t_max; for (int i = 0; i < hitables.Count; i++) { //cycle through all hitables and return the hit closest to the camera if (((Hitable)hitables [i]).hit(r, t_min, closest, ref temp_rec)) { hit_anything = true; closest = temp_rec.t; rec = temp_rec; } } return(hit_anything); }
public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec) { if (box.hit(r, t_min, t_max)) { hit_record left_rec = new hit_record(); hit_record right_rec = new hit_record(); bool hit_left = left.hit(r, t_min, t_max, ref left_rec); bool hit_right = right.hit(r, t_min, t_max, ref right_rec); if (hit_left && hit_right) { if (left_rec.t < right_rec.t) { rec = left_rec; } else { rec = right_rec; } return(true); } else if (hit_left) { rec = left_rec; return(true); } else if (hit_right) { rec = right_rec; return(true); } else { return(false); } } else { return(false); } }
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); }
public override zwischenSpeicher Hit(ray r, double t_min, double t_max, hit_record rec) { zwischenSpeicher zw = new zwischenSpeicher(); hit_record temp_rec = new hit_record(); bool hit_anything = false; var closest_so_far = t_max; foreach (var Object in objects) { zwischenSpeicher zw1 = Object.Hit(r, t_min, closest_so_far, temp_rec); if (zw1.IsTrue) { temp_rec = zw1.rec; hit_anything = true; closest_so_far = temp_rec.t; rec = temp_rec; } } zw.rec = rec; zw.IsTrue = hit_anything; return(zw); }
public virtual bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered) { return(false); }
public virtual bool hit(Ray r, float t_min, float t_max, ref hit_record rec) { return(false); }