diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/main.rs b/src/main.rs index 4abc7c9..1a0b001 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,35 +1,84 @@ -use cgmath::vec3; +use cgmath::prelude::*; +use cgmath::{Vector3, vec3}; use rand::prelude::*; +use std::f64::consts::PI; mod camera; -mod colour; mod hittable; mod material; -mod random; mod ray; mod render; mod scene; mod sphere; +mod utils; -fn main() { - let image_width = 200; - let image_height = 100; - let samples = 50; - let max_depth = 25; +pub fn random_scene(rng: &mut ThreadRng) -> scene::Scene { + let mut scene = scene::Scene::new(); - println!("P3\n{} {}\n255", image_width, image_height); + scene.add(Box::new(sphere::Sphere::new( + vec3(0.0, -1000.0, 0.0), 1000.0, Box::new(material::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::<f64>(), 0.2, b as f64 + 0.9*rng.gen::<f64>()); + 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)); + scene.add( + Box::new(sphere::Sphere::new(center, 0.2, Box::new(material::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::Sphere::new( + center, 0.2, Box::new(material::Metal::new(albedo, fuzz))))); + } else { + // glass + scene.add(Box::new(sphere::Sphere::new( + center, 0.2, Box::new(material::Dielectric::new(1.5))))); + } + } + } + } - let mut world = scene::Scene::new(); - world.add(Box::new(sphere::Sphere::new( - vec3(0.0, 0.0, -1.0), 0.5, Box::new(material::Lambertian::new(vec3(1.0, 1.0, 1.0)))))); - world.add(Box::new(sphere::Sphere::new( - vec3(0.0, -100.5, -1.0), 100.0, Box::new(material::Lambertian::new(vec3(1.0, 1.0, 1.0)))))); + scene.add(Box::new(sphere::Sphere::new( + vec3(0.0, 1.0, 0.0), 1.0, Box::new(material::Dielectric::new(1.5))))); - let camera = camera::Camera::new(); + scene.add( + Box::new(sphere::Sphere::new(vec3(-4.0, 1.0, 0.0), 1.0, + Box::new(material::Lambertian::new(vec3(0.4, 0.2, 0.1)))))); + + scene.add( + Box::new(sphere::Sphere::new( + vec3(4.0, 1.0, 0.0), 1.0, Box::new(material::Metal::new(vec3(0.7, 0.6, 0.5), 0.0))))); + + scene +} +fn main() { + let image_width = 1200; + let image_height = 800; + let samples = 100; + 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(); - render::render(&world, camera, image_height, image_width, samples, max_depth, &mut 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); + + render::render(&scene, camera, image_height, image_width, samples, max_depth, &mut rng); eprintln!("\nDone") } |