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); }
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 static double hit_sphere(Vektor center, double radius, ray r) { 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) { return(-1); } else { return((-half_b - Math.Sqrt(discriminant)) / a); } }
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 MainWindow() { InitializeComponent(); const int image_width = 400; const int image_height = 236; double aspect_ratio = (double)image_width / (double)image_height; const int samples_per_pixel = 10; const int max_depth = 50; //World var world = new hittable_list(); var material = new Metal(new Vektor(.7, .7, .7), 0.7); var material1 = new Metal(new Vektor(1, 0.32, 0.36), 0); var material2 = new Metal(new Vektor(0.90, 0.76, 0.46), 0); var material3 = new Metal(new Vektor(0.65, 0.77, 0.97), 0); var material4 = new Metal(new Vektor(0.90, 0.90, 0.90), 0); world.Add(new sphere(new Vektor(0.0, -10004, -20), 10000, material)); world.Add(new sphere(new Vektor(0, 0, -20), 4, material1)); world.Add(new sphere(new Vektor(5, -1, -15), 2, material2)); world.Add(new sphere(new Vektor(5, 0, -25), 3, material3)); world.Add(new sphere(new Vektor(-5.5, 0, -15), 3, material4)); //Camera Vektor lookfrom = new Vektor(0, 0, 0); Vektor lookat = new Vektor(0, 0, -1); Vektor vup = new Vektor(0, 1, 0); var dist_to_focus = 10; var aperture = 0.1; Camera cam = new Camera(lookfrom, lookat, vup, 50, aspect_ratio, aperture, dist_to_focus); Vektor[,] vArr = new Vektor[image_height, image_width]; Bitmap bmp = new Bitmap(image_width, image_height); Parallel.For(0, image_height, j => { for (int i = 0; i < image_width; i++) { Vektor pixel_color = new Vektor(0, 0, 0); for (int s = 0; s < samples_per_pixel; s++) { var u = ((double)i + Mathe.random_double()) / (image_width - 1); var v = ((double)j + Mathe.random_double()) / (image_height - 1); ray r = cam.get_ray(u, v); pixel_color += ray.ray_color(r, world, max_depth); } vArr[j, i] = pixel_color; } }); for (int j = 0; j < image_height; j++) { for (int i = 0; i < image_width; i++) { bmp.SetPixel(i, (j - (image_height - 1)) * -1, Vektor.toColor(vArr[j, i], samples_per_pixel)); } } image.Source = BitmapToImageSource(bmp); }