diff --git a/img.ppm b/img.ppm index 79b1e6d..6a07845 100644 Binary files a/img.ppm and b/img.ppm differ diff --git a/src/main.rs b/src/main.rs index 9bfed35..238156a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,8 @@ pub mod material; use std::{io::{BufWriter, Write, stdout}, fs::File, time::Instant}; -use material::Metal; - use crate::{ + material::*, color::*, sphere::*, rtweekend::*, @@ -23,6 +22,45 @@ use crate::{ camera::*, material::{Lambertian, Dielectric}, }; +fn random_scene() -> HittableList { + let mut world = HittableList::new_empty(); + + static GROUND_MATERIAL: Lambertian = Lambertian::new(Color::new(0.5, 0.5, 0.5)); + world.add(Box::new(Sphere::new(Point3::new(0.0, -1000.0, 0.0), 1000.0, &GROUND_MATERIAL))); + + for a in 0..12 { + for b in 0..12 { + let choose_mat = random_f64(); + let center = Point3::new(a as f64 + 0.9*random_f64(), 0.2, b as f64 + 0.9*random_f64()); + + if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 { + if choose_mat < 0.8 { + //let albedo = Color::new(0.3, 0.8, 0.4); + static SPHERE_MATERIAL: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.4)); + world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL))); + } else if choose_mat < 0.95 { + static SPHERE_MATERIAL: Metal = Metal::new(Color::new(0.3, 0.6, 0.2), 0.2); + world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL))); + } else { + static SPHERE_MATERIAL: Dielectric = Dielectric::new(1.5); + world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL))); + } + } + } + } + + static MATERIAL1: Dielectric = Dielectric::new(1.5); + world.add(Box::new(Sphere::new(Point3::new(0.0, 1.0, 0.0), 1.0, &MATERIAL1))); + + static MATERIAL2: Lambertian = Lambertian::new(Color::new(0.4, 0.2, 0.1)); + world.add(Box::new(Sphere::new(Point3::new(-4.0, 1.0, 0.0), 1.0, &MATERIAL2))); + + static MATERIAL3: Metal = Metal::new(Color::new(0.7, 0.6, 0.5), 0.0); + world.add(Box::new(Sphere::new(Point3::new(4.0, 1.0, 0.0), 1.0, &MATERIAL3))); + + world +} + fn ray_color(r: Ray, world: &mut dyn Hittable, depth: i32) -> Color { // Limit the bounces if depth <= 0 { @@ -48,28 +86,19 @@ fn ray_color(r: Ray, world: &mut dyn Hittable, depth: i32) -> Color { fn main() { // Image let aspect_ratio: f64 = 1.0 / 1.0; - let image_width: i32 = 512; + let image_width: i32 = 1000; let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32; let samples_per_pixel: i32 = 200; let max_depth: i32 = 4; // World - let mut world = HittableList::new_empty(); - static MATERIAL_GROUND: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.0)); - static MATERIAL_CENTER: Lambertian = Lambertian::new(Color::new(0.1, 0.2, 0.5)); - static MATERIAL_LEFT: Dielectric = Dielectric::new(1.5); - static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.0); - - world.add(Box::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &MATERIAL_GROUND))); - world.add(Box::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5, &MATERIAL_CENTER))); - world.add(Box::new(Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, &MATERIAL_LEFT))); - world.add(Box::new(Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &MATERIAL_RIGHT))); + let mut world = random_scene(); // Camera - let lookfrom = Point3::new(-2.0, 2.0, 1.0); - let lookat = Point3::new(0.0, 0.0, -1.0); + let lookfrom = Point3::new(-13.0, 2.0, 3.0); + let lookat = Point3::new(0.0, 0.0, 0.0); let vup = Vec3::new(0.0, 1.0, 0.0); - let dist_to_focus = (lookfrom-lookat).length_squared(); + let dist_to_focus = 10.0;//(lookfrom-lookat).length_squared(); let cam = Camera::new( lookfrom,