mod camera; mod hittable; mod material; mod ray; mod render; mod scene; mod sphere; mod utils; use cgmath::prelude::*; use cgmath::{vec3, Vector3}; use rand::prelude::*; use std::f64::consts::PI; use scene::Scene; use sphere::Sphere; use material::{Lambertian, Dielectric, Metal}; pub fn random_scene(rng: &mut ThreadRng) -> scene::Scene { let mut scene = Scene::new(); scene.add(Box::new(Sphere::new( vec3(0.0, -1000.0, 0.0), 0.0, 1.0, 1000.0, Box::new(Lambertian::new(vec3(0.5, 0.5, 0.5))), ))); for a in -11..11 { for b in -11..11 { let choose_mat: f64 = rng.gen(); let center = vec3( a as f64 + 0.9 * rng.gen::(), 0.2, b as f64 + 0.9 * rng.gen::(), ); if (center - vec3(4.0, 0.2, 0.0)).magnitude() > 0.9 { if choose_mat < 0.8 { // diffuse let albedo = utils::random_vector3(rng, 0.0, 1.0) .mul_element_wise(utils::random_vector3(rng, 0.0, 1.0)); let moving_center = center + vec3(0.0, rng.gen_range(0.0, 0.1), 0.0); scene.add(Box::new(Sphere::new_moving( center, moving_center, 0.0, 1.0, 0.2, Box::new(Lambertian::new(albedo)), ))); } else if choose_mat < 0.95 { // metal let albedo = utils::random_vector3(rng, 0.5, 1.0); let fuzz = rng.gen_range(0.0, 0.5); scene.add(Box::new(Sphere::new( center, 0.0, 1.0, 0.2, Box::new(Metal::new(albedo, fuzz)), ))); } else { // glass scene.add(Box::new(Sphere::new( center, 0.0, 1.0, 0.2, Box::new(Dielectric::new(1.5)), ))); } } } } scene.add(Box::new(Sphere::new( vec3(0.0, 1.0, 0.0), 0.0, 1.0, 1.0, Box::new(Dielectric::new(1.5)), ))); scene.add(Box::new(Sphere::new( vec3(-4.0, 1.0, 0.0), 0.0, 1.0, 1.0, Box::new(Lambertian::new(vec3(0.4, 0.2, 0.1))), ))); scene.add(Box::new(Sphere::new( vec3(4.0, 1.0, 0.0), 0.0, 1.0, 1.0, Box::new(Metal::new(vec3(0.7, 0.6, 0.5), 0.0)), ))); scene } fn main() { let image_width = 400; let image_height = 200; let samples = 100; let threads = 4; let max_depth = 50; let aspect_ratio = image_width as f64 / image_height as f64; println!("P3\n{} {}\n255", image_width, image_height); let mut rng = thread_rng(); let scene = random_scene(&mut rng); let lookfrom = vec3(13.0, 2.0, 3.0); let lookat = vec3(0.0, 0.0, 0.0); let vup = vec3(0.0, 1.0, 0.0); let dist_to_focus = 10.0; let aperture = 0.1; let camera = camera::Camera::new( &lookfrom, &lookat, &vup, 20.0 * PI / 180.0, aspect_ratio, aperture, dist_to_focus, 0.0, 1.0, ); render::render( &scene, &camera, image_height, image_width, samples, max_depth, threads, ); eprintln!("\nDone") }