public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec) { var t = (k - r.Origin.X) / r.Direction.X; if (t < t0 || t > t1) { return(false); } var y = r.Origin.Y + t * r.Direction.Y; var z = r.Origin.Z + t * r.Direction.Z; if (y < y0 || y > y1 || z < z0 || z > z1) { return(false); } rec.U = (y - y0) / (y1 - y0); rec.V = (z - z0) / (z1 - z0); rec.T = t; var outward_normal = new Vector3(1, 0, 0); rec.Set_Face_Normal(r, outward_normal); rec.Mat_ptr = mp; rec.P = r.At(t); return(true); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { var origin = r.Origin; var direction = r.Direction; origin.X = cos_theta * r.Origin.X - sin_theta * r.Origin.Z; origin.Z = sin_theta * r.Origin.X + cos_theta * r.Origin.Z; direction.X = cos_theta * r.Direction.X - sin_theta * r.Direction.Z; direction.Z = sin_theta * r.Direction.X + cos_theta * r.Direction.Z; Ray rotated_r = new Ray(origin, direction, r.Time); if (!ptr.Hit(rotated_r, t_min, t_max, ref rec)) { return(false); } var p = rec.P; var normal = rec.Normal; p.X = cos_theta * rec.P.X + sin_theta * rec.P.Z; p.Z = -sin_theta * rec.P.X + cos_theta * rec.P.Z; normal.X = cos_theta * rec.Normal.X + sin_theta * rec.Normal.Z; normal.Z = -sin_theta * rec.Normal.X + cos_theta * rec.Normal.Z; rec.P = p; rec.Set_Face_Normal(rotated_r, normal); return(true); }
public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec) { var t = (k - r.Origin.Y) / r.Direction.Y; if (t < t0 || t > t1) { return(false); } var x = r.Origin.X + t * r.Direction.X; var z = r.Origin.Z + t * r.Direction.Z; if (x < x0 || x > x1 || z < z0 || z > z1) { return(false); } rec.U = (x - x0) / (x1 - x0); rec.V = (z - z0) / (z1 - z0); rec.T = t; var outward_normal = new Vector3(0, 1, 0); rec.Set_Face_Normal(r, outward_normal); rec.Mat_ptr = mp; rec.P = r.At(t); return(true); }
static Vector3 Ray_color(Ray r, Vector3 background, 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 the ray hits nothing, return the background color. if (!world.Hit(r, 0.001f, Helpers.Infinity, ref rec)) { return(background); } Ray scattered; Vector3 attenuation; Vector3 emitted = rec.Mat_ptr.Emitted(rec.U, rec.V, rec.P); if (!rec.Mat_ptr.Scatter(r, rec, out attenuation, out scattered)) { return(emitted); } return(emitted + attenuation * Ray_color(scattered, background, world, depth - 1)); }
public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered) { attenuation = Vector3.One; float etai_over_etat = (rec.Front_face) ? (1.0f / Ref_idx) : (Ref_idx); Vector3 unit_direction = Vector3.Normalize(r_in.Direction); float cos_theta = Math.Min(Vector3.Dot(-unit_direction, rec.Normal), 1.0f); float sin_theta = (float)Math.Sqrt(1.0f - cos_theta * cos_theta); if (etai_over_etat * sin_theta > 1.0f) { Vector3 reflected = Helpers.Reflect(unit_direction, rec.Normal); scattered = new Ray(rec.P, reflected); return(true); } float reflect_prob = Helpers.Schlick(cos_theta, etai_over_etat); if (Helpers.random.NextDouble() < reflect_prob) { Vector3 reflected = Helpers.Reflect(unit_direction, rec.Normal); scattered = new Ray(rec.P, reflected); return(true); } Vector3 refracted = Helpers.Refract(unit_direction, rec.Normal, etai_over_etat); scattered = new Ray(rec.P, refracted); return(true); }
public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered) { Vector3 scatter_direction = rec.Normal + Helpers.Random_unit_Vector(); scattered = new Ray(rec.P, scatter_direction, r_in.Time); attenuation = this.Albedo.Value(rec.U, rec.V, rec.P); return(true); }
public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered) { Vector3 unit_vector = Vector3.Normalize(r_in.Direction); Vector3 reflected = Helpers.Reflect(unit_vector, rec.Normal); scattered = new Ray(rec.P, reflected + fuzz * Helpers.Random_in_unit_sphere()); attenuation = this.Albedo; return(Vector3.Dot(scattered.Direction, rec.Normal) > 0); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { if (!this.box.Hit(r, t_min, t_max)) { return(false); } bool hit_left = left.Hit(r, t_min, t_max, ref rec); bool hit_right = right.Hit(r, t_min, hit_left ? rec.T : t_max, ref rec); return(hit_left || hit_right); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { Ray moved_r = new Ray(r.Origin - offset, r.Direction, r.Time); if (!ptr.Hit(moved_r, t_min, t_max, ref rec)) { return(false); } rec.P += offset; rec.Set_Face_Normal(moved_r, rec.Normal); return(true); }
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); }
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); rec.Mat_ptr = Material; this.Get_sphere_uv((rec.P - this.Center) / this.Radius, out rec.U, out rec.V); 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); rec.Mat_ptr = Material; this.Get_sphere_uv((rec.P - this.Center) / this.Radius, out rec.U, out rec.V); return(true); } } return(false); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { Vector3 oc = r.Origin - this.Center(r.Time); var a = r.Direction.LengthSquared(); var half_b = Vector3.Dot(oc, r.Direction); var c = oc.LengthSquared() - radius * radius; var discriminant = half_b * half_b - a * c; if (discriminant > 0) { var root = (float)Math.Sqrt(discriminant); var temp = (-half_b - root) / a; if (temp < t_max && temp > t_min) { rec.T = temp; rec.P = r.At(rec.T); var outward_normal = (rec.P - this.Center(r.Time)) / radius; rec.Set_Face_Normal(r, outward_normal); rec.Mat_ptr = mat_ptr; return(true); } temp = (-half_b + root) / a; if (temp < t_max && temp > t_min) { rec.T = temp; rec.P = r.At(rec.T); var outward_normal = (rec.P - this.Center(r.Time)) / radius; rec.Set_Face_Normal(r, outward_normal); rec.Mat_ptr = mat_ptr; return(true); } } return(false); }
public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec) { return(sides.Hit(r, t0, t1, ref rec)); }
public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered) { attenuation = default; scattered = null; return(false); }
public abstract bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered);
public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered) { scattered = new Ray(rec.P, Helpers.Random_in_unit_sphere(), r_in.Time); attenuation = albedo.Value(rec.U, rec.V, rec.P); return(true); }
public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { // Print occasional samples when debugging. To enable, set enableDebug true. const bool enableDebug = false; bool debugging = enableDebug && ((float)Helpers.random.NextDouble() < 0.00001f); Hit_Record rec1, rec2; rec1 = rec2 = default; if (!boundary.Hit(r, -Helpers.Infinity, Helpers.Infinity, ref rec1)) { return(false); } if (!boundary.Hit(r, rec1.T + 0.0001f, Helpers.Infinity, ref rec2)) { return(false); } if (debugging) { Console.WriteLine($"t0={rec1.T}, t1={rec2.T}"); } if (rec1.T < t_min) { rec1.T = t_min; } if (rec2.T > t_max) { rec2.T = t_max; } if (rec1.T >= rec2.T) { return(false); } if (rec1.T < 0) { rec1.T = 0; } float ray_length = r.Direction.Length(); float distance_inside_boundary = (rec2.T - rec1.T) * ray_length; float hit_distance = neg_inv_density * (float)Math.Log(Helpers.random.NextDouble()); if (hit_distance > distance_inside_boundary) { return(false); } rec.T = rec1.T + hit_distance / ray_length; rec.P = r.At(rec.T); if (debugging) { Console.WriteLine($"hit_distance = {hit_distance} \n " + $"rec.t = {rec.T} \n" + $"rec.p = {rec.P}"); } rec.Normal = new Vector3(1, 0, 0); // arbitrary rec.Front_face = true; // also arbitrary rec.Mat_ptr = phase_function; return(true); }