extern crate rand; extern crate rtiow; use rand::Rng; use rtiow::camera::Camera; use rtiow::hitable::Hit; use rtiow::hitable_list::HitableList; use rtiow::material::Dielectric; use rtiow::material::Lambertian; use rtiow::material::Metal; use rtiow::ray::Ray; use rtiow::sphere::Sphere; use rtiow::vec3::Vec3; fn color(r: Ray, world: &Hit, depth: usize) -> Vec3 { if let Some(rec) = world.hit(r, 0.001, std::f32::MAX) { let scatter_response = rec.material.scatter(&r, &rec); if depth < 50 && scatter_response.reflected { return scatter_response.attenutation * color(scatter_response.scattered, world, depth + 1); } return Default::default(); } // No hit, choose color from background. let unit_direction = r.direction().unit_vector(); let t = 0.5 * (unit_direction.y + 1.); Vec3::new(1., 1., 1.) * (1. - t) + Vec3::new(0.5, 0.7, 1.) * t } fn main() -> Result<(), std::io::Error> { let mut rng = rand::thread_rng(); let nx = 200; let ny = 100; let ns = 100; println!("P3\n{} {}\n255", nx, ny); let objects = vec![ Sphere::new( Vec3::new(0., 0., -1.), 0.5, Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), ), Sphere::new( Vec3::new(0., -100.5, -1.), 100., Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.))), ), Sphere::new( Vec3::new(1., 0., -1.), 0.5, Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)), ), Sphere::new(Vec3::new(-1., 0., -1.), 0.5, Box::new(Dielectric::new(1.5))), Sphere::new( Vec3::new(-1., 0., -1.), -0.45, Box::new(Dielectric::new(1.5)), ), ]; let cam = Camera::new_lookfrom_vfov( Vec3::new(-2., 2., 1.), Vec3::new(0., 0., -1.), Vec3::new(0., 1., 0.), 90., nx as f32 / ny as f32, ); let world = HitableList::new(objects.iter().map(|o| o).collect()); for j in (0..ny).rev() { for i in 0..nx { let mut col: Vec3 = Default::default(); for _ in 0..ns { let u = (rng.gen_range::(0., 1.) + i as f32) / nx as f32; let v = (rng.gen_range::(0., 1.) + j as f32) / ny as f32; let r = cam.get_ray(u, v); col = col + color(r, &world, 0); } col = col / ns as f32; // Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 // or sqrt. col = Vec3::new(col[0].sqrt(), col[1].sqrt(), col[2].sqrt()); let ir = (255.99 * col[0]) as u32; let ig = (255.99 * col[1]) as u32; let ib = (255.99 * col[2]) as u32; println!("{} {} {}", ir, ig, ib); } } Ok(()) }