extern crate image; mod camera; mod color; mod hittable; mod hittable_list; mod ray; mod utility; mod vec3; use std::env; //use std::fs::File; //use std::io::BufWriter; //use std::io::Write; use camera::Camera; use hittable::{HitRecord, Hittable, Sphere}; use hittable_list::HittableList; use image::{Rgb, RgbImage}; use rayon::prelude::*; use ray::Ray; use vec3::{Color, Point3, Vec3}; fn ray_color(r: &Ray, world: &HittableList) -> Color { let mut rec = HitRecord::empty(); if world.hit(r, 0.0, f64::INFINITY, &mut rec) { return 0.5 * (rec.normal + Color::new(1.0, 1.0, 1.0)); } let unit_direction = r.direction(); let t = 0.5 * (unit_direction.y() + 1.0); return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0); } fn main() { // File let mut default_file = "image.ppm"; // Image let aspect_ratio = 16.0 / 9.0; let image_width = 1000; let image_height = (image_width as f64 / aspect_ratio) as u32; let samples_per_pixel = 50_u32; // World let mut world = HittableList::new(); world.add(Box::::new(Sphere::new( Point3::new(0.0, 0.0, -1.0), 0.5, ))); world.add(Box::::new(Sphere::new( Point3::new(0.0, -100.5, -150.0), 100.0, ))); world.add(Box::::new(Sphere::new( Point3::new(1.0, 0.0, -1.5), 0.3, ))); world.add(Box::::new(Sphere::new( Point3::new(1.0, 1.1, -1.5), 0.3, ))); world.add(Box::::new(Sphere::new( Point3::new(-1.0, 1.1, -1.5), 0.3, ))); /* for i in -15..15 { for j in -15..15 { world.add(Box::::new(Sphere::new(Point3::new(j as f64/6.0 as f64, i as f64/6.0 as f64, -1.5), 0.05))); } } */ // Camera let cam = Camera::new(); // Render let args: Vec = env::args().collect(); if args.len() > 1 && args[1] != "" { default_file = &args[1]; } let mut image = RgbImage::new(image_width, image_height); //let mut file = BufWriter::new(File::create(default_file).unwrap()); //writeln!(&mut file, "P3\n{image_width} {image_height}\n255\n").unwrap(); TODO: // world in vec umwandeln for j in (0..image_height).rev() { eprint!("\rScanlines remaining: {j:5}"); (0..image_width).into_par_iter().for_each(|i| pixel_color_calc(&mut image, &cam, &world, j, i, image_width, image_height, samples_per_pixel)); } image.save(default_file).unwrap(); eprintln!("\nDone!"); } fn pixel_color_calc(image: &mut RgbImage, cam: &Camera, world: &HittableList, j: u32, i: u32, image_width: u32, image_height: u32, samples_per_pixel: u32) { let mut pixel_color = Color::new(0.0, 0.0, 0.0); for _ in 0..samples_per_pixel { let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64; let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64; let r = cam.get_ray(u, v); pixel_color += ray_color(&r, &world); } //color::write_color(&mut file, &pixel_color); color::put_color( &mut image, &pixel_color, i, image_height - j - 1, samples_per_pixel, ); }