public override void trace(Ray r) { double v = r.dir * norm; if (r.is_outside && v > 0 || !r.is_outside && v < 0) return; double dist = ((p0 - r.pos) * norm) / v; if (dist > 0 && dist < r.hit_dist) { vect3d hit_pos = r.pos + r.dir * dist; // find barycentric coordinates; double b0 = ((p1 - hit_pos) % (p2 - hit_pos)) * N; double b1 = ((p2 - hit_pos) % (p0 - hit_pos)) * N; double b2 = 1 - b0 - b1; if (b0 >= 0 && b1 >= 0 && b2 >= 0) { r.hit_dist = dist; r.hit_pos = hit_pos; r.hit_tex_coord = t0 * b0 + t1 * b1 + t2 * b2; r.hit_norm = n0 * b0 + n1 * b1 + n2 * b2; r.hit_norm.normalize(); r.hit_object = this; } } }
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; } } }
public override void colorize(Ray r) { vect3d diff_accum = new vect3d(0, 0, 0); vect3d spec_accum = new vect3d(0, 0, 0); lightDirectPointSpecNoShadow(r, specular_coeff, ref diff_accum, ref spec_accum); r.color = diff_accum.times(diffuse_color) + spec_accum.times(specular_color); }
public override void colorize(Ray r) { vect3d diff_accum = new vect3d(0, 0, 0); vect3d spec_accum = new vect3d(0, 0, 0); lightDirectPointSpec(r, specular_coeff, ref diff_accum, ref spec_accum); vect3d diffuse_color = tex.sample(r.hit_tex_coord); r.color = diff_accum.times(diffuse_color) + spec_accum.times(specular_color); }
public override void colorize(Ray r) { vect3d diff_accum = new vect3d(0, 0, 0); vect3d spec_accum = new vect3d(0, 0, 0); lightDirectPointSpec(r, specular_coeff, ref diff_accum, ref spec_accum); // calculate the polar coordinates vect3d sp; sp.x = -Math.Atan2(r.hit_tex_coord.z, r.hit_tex_coord.x) / (2 * Math.PI); sp.y = -Math.Atan2(Math.Sqrt(r.hit_tex_coord.x * r.hit_tex_coord.x + r.hit_tex_coord.z * r.hit_tex_coord.z), r.hit_tex_coord.y) / (Math.PI); sp.z = 0; vect3d diffuse_color = tex.sample(sp); r.color = diff_accum.times(diffuse_color) + spec_accum.times(specular_color); }
public override void trace(Ray r) { double v = r.dir * z; if (r.is_outside && v > 0 || !r.is_outside && v < 0) return; double dist = ((pos - r.pos) * z) / v; if (dist > 0 && dist < r.hit_dist) { r.hit_dist = dist; r.hit_pos = r.pos + r.dir * dist; vect3d rp = r.hit_pos - pos; r.hit_tex_coord = new vect3d(x * rp, y * rp, 0); r.hit_norm = z; r.hit_object = this; } }
public override void trace(Ray r) { vect3d o = r.pos, d = r.dir; double t = Double.MaxValue; double Aq = A * d.x * d.x + D * d.x * d.y + B * d.y * d.y + C * d.z * d.z + d.x * d.z * E + d.y * d.z * F; double Bq = d.x * G + d.y * H + d.z * I + 2 * A * d.x * o.x + D * d.y * o.x + d.z * E * o.x + D * d.x * o.y + 2 * B * d.y * o.y + d.z * F * o.y + 2 * C * d.z * o.z + d.x * E * o.z + d.y * F * o.z; double Cq = J + G * o.x + A * o.x * o.x + H * o.y + D * o.x * o.y + B * o.y * o.y + I * o.z + E * o.x * o.z + F * o.y * o.z + C * o.z * o.z; if (Aq == 0) { if (Bq != 0) t = -Cq / Bq; } else { double Dq = Bq * Bq - 4 * Aq * Cq; if (Dq > 0) { if (r.is_outside) t = (-Bq - Math.Sqrt(Dq)) / (2 * Aq); else t = (-Bq + Math.Sqrt(Dq)) / (2 * Aq); } } if (t > 0 && t < r.hit_dist) { r.hit_dist = t; r.hit_object = this; vect3d p = r.pos + r.dir * t; r.hit_pos = p; r.hit_tex_coord = p; r.hit_norm = new vect3d( 2 * A * p.x + D * p.y + E * p.z + G, 2 * B * p.y + D * p.x + F * p.z + H, 2 * C * p.z + E * p.x + F * p.y + I); r.hit_norm.normalize(); if (r.dir * r.hit_norm > 0) r.hit_norm *= -1; } }
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; } }
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; } }
public Bitmap create_image(Scene scene) { Bitmap bmp = new Bitmap(width, height); // get the orientation of the camera matrix4d rotmat = orient.getMatrix(); vect3d rt = new vect3d(rotmat.m[0], rotmat.m[1], rotmat.m[2]); vect3d up = new vect3d(rotmat.m[4], rotmat.m[5], rotmat.m[6]); vect3d fwd = new vect3d(rotmat.m[8], rotmat.m[9], rotmat.m[10]); // convert the orientation to a 3D screen double aspect = (double)width / (double)height; double h = Math.Tan(fov_y * Math.PI / 360.0); up *= -h * 2; rt *= aspect * h * 2; fwd *= -1; // 2D screen conversions vect3d dx = rt / width; vect3d dy = up / height; vect3d corner = fwd - rt * .5 - up * .5; // expose each pixel Ray r = new Ray(); r.scene = scene; double subsample_res = 1.0 / subsamples; for (int j = 0; j < bmp.Height; j++) { for (int i = 0; i < bmp.Width; i++) { vect3d color = new vect3d(0, 0, 0); for (int jj = 0; jj < subsamples; jj++) { for (int ii = 0; ii < subsamples; ii++) { // set ray properties r.pos = this.pos; r.hit_dist = Double.MaxValue; r.color = new vect3d(0, 0, 0); r.hit_object = null; r.dir = corner + dx * (i + (ii+.5/*Rand.rand.NextDouble()*/) * subsample_res) + dy * (j + (jj+.5/*Rand.rand.NextDouble()*/) * subsample_res); r.dir.normalize(); // trace the ray scene.trace(r); if (r.hit_object != null) { r.hit_object.shader.colorize(r); color += r.color; } } } color *= subsample_res * subsample_res; // gamma correct the color double brightness = color.length(); color /= Math.Sqrt(brightness); // store the color int red = clamp(color.x); int green = clamp(color.y); int blue = clamp(color.z); bmp.SetPixel(i, j, Color.FromArgb(255, red, green, blue)); } } return bmp; }
public virtual void colorize(Ray r) { r.color = new vect3d(1, 1, 1); }
public override void trace(Ray r) { occluder.trace(r); }
public void trace(Ray r) { if (left != null) { int f_d, f_n; double d_l, d_r; bool h_l = Custom.Intersect.rayBoxIntersectDist(r.pos, r.dir, left.bounds, out d_l, out f_d, out f_n); bool h_r = Custom.Intersect.rayBoxIntersectDist(r.pos, r.dir, right.bounds, out d_r, out f_d, out f_n); if (h_l && h_r) { if (d_l < d_r) { left.trace(r); if (d_r < r.hit_dist) right.trace(r); } else { right.trace(r); if (d_l < r.hit_dist) left.trace(r); } } else if (h_l) left.trace(r); else if (h_r) right.trace(r); } else { foreach (var o in list) o.trace(r); } }
public override void trace(Ray r) { foreach (var o in list) o.trace(r); }
public override void trace(Ray r) { int f_d, f_n; double d_l; bool h_l = Custom.Intersect.rayBoxIntersectDist(r.pos, r.dir, tree.bounds, out d_l, out f_d, out f_n); if (h_l && d_l >= 0) tree.trace(r); }
public virtual void trace(Ray r) { }