public override void trace(Ray r) { vect3d dst = r.pos - this.pos; double B = dst * r.dir; double C = dst.length2() - this.radius2; double D = B * B - C; if (D > 0) { double dist; double flip_norm = 1; if (r.is_outside) { dist = -B - Math.Sqrt(D); } else { dist = -B + Math.Sqrt(D); flip_norm = -1; } if (dist > 0 && dist < r.hit_dist) { r.hit_dist = dist; r.hit_pos = r.pos + r.dir * dist; r.hit_norm = (r.hit_pos - this.pos) * flip_norm; r.hit_norm.normalize(); r.hit_tex_coord = r.hit_norm; r.hit_object = this; } } }
protected void lightDirectPointSpecNoShadow(Ray r, double specular_coeff, ref vect3d diff_accum, ref vect3d spec_accum) { Ray shadow_ray = new Ray(); shadow_ray.pos = r.hit_pos; foreach (var l in r.scene.lights) { vect3d dir = l.pos - r.hit_pos; double dist2 = 1.0 / dir.length2(); dir *= Math.Sqrt(dist2); // diffuse double incidence_dif = (dir * r.hit_norm); if (incidence_dif > 0) { diff_accum += l.color * incidence_dif * dist2; } // specular highlight vect3d dir_r = r.hit_norm * ((dir * r.hit_norm) * 2) - dir; double incidence_spec = (dir_r * r.hit_norm); if (incidence_spec > 0) { spec_accum += l.color * Math.Pow(incidence_spec, specular_coeff) * dist2; } } }
public static vect3d rand_in_sphere() { vect3d p; do { p = new vect3d(rand.NextDouble() * 2 - 1, rand.NextDouble() * 2 - 1, rand.NextDouble() * 2 - 1); } while (p.length2() > 1); return(p); }
protected void lightDirectPointSpec(Ray r, double specular_coeff, ref vect3d diff_accum, ref vect3d spec_accum) { Ray shadow_ray = new Ray(); shadow_ray.pos = r.hit_pos; foreach (var l in r.scene.lights) { vect3d dir = l.pos - r.hit_pos; double dist2 = dir.length2(); double dist2_inv = 1.0 / dist2; dir *= Math.Sqrt(dist2_inv); // calculate incidences to do early reject of shadow ray double incidence_dif = (dir * r.hit_norm); vect3d dir_r = r.hit_norm * ((dir * r.hit_norm) * 2) - dir; double incidence_spec = (dir_r * r.hit_norm); if (incidence_dif < 0 && incidence_spec < 0) { continue; } // shadow ray test shadow_ray.dir = dir; shadow_ray.hit_dist = Double.MaxValue; r.scene.trace(shadow_ray); if (shadow_ray.hit_dist * shadow_ray.hit_dist < dist2) { continue; } // diffuse if (incidence_dif > 0) { diff_accum += l.color * incidence_dif * dist2_inv; } // specular highlight if (incidence_spec > 0) { spec_accum += l.color * Math.Pow(incidence_spec, specular_coeff) * dist2_inv; } } }