public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { Vector3 oc = r.Origin - this.Center; float a = r.Direction.LengthSquared(); float half_b = Vector3.Dot(oc, r.Direction); float c = oc.LengthSquared() - this.Radius * this.Radius; float discriminant = half_b * half_b - a * c; if (discriminant > 0) { float root = (float)Math.Sqrt(discriminant); float temp = (-half_b - root) / a; if (temp < t_max && temp > t_min) { rec.T = temp; rec.P = r.At(rec.T); Vector3 outward_normal = (rec.P - this.Center) / this.Radius; rec.Set_Face_Normal(r, outward_normal); return(true); } temp = (-half_b + root) / a; if (temp < t_max && temp > t_min) { rec.T = temp; rec.P = r.At(rec.T); Vector3 outward_normal = (rec.P - this.Center) / this.Radius; rec.Set_Face_Normal(r, outward_normal); return(true); } } return(false); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { Hit_Record temp_rec = default; bool hit_anything = false; float closest_so_far = t_max; foreach (var o in this.Objects) { if (o.Hit(r, t_min, closest_so_far, ref temp_rec)) { hit_anything = true; closest_so_far = temp_rec.T; rec = temp_rec; } } return(hit_anything); }
static Vector3 Ray_color(Ray r, HitTable world, int depth) { Hit_Record rec = default; // If we've exceeded the ray bounce limit, no more light is gathered. if (depth <= 0) { return(Vector3.Zero); } if (world.Hit(r, 0, Helpers.Infinity, ref rec)) { Vector3 target = rec.P + rec.Normal + Helpers.Random_in_unit_sphere(); return(0.5f * Ray_color(new Ray(rec.P, target - rec.P), world, depth - 1)); } Vector3 unit_direction = Vector3.Normalize(r.Direction); var t = 0.5f * (unit_direction.Y + 1.0f); return((1.0f - t) * new Vector3(1.0f, 1.0f, 1.0f) + t * new Vector3(0.5f, 0.7f, 1.0f)); }