use rand; use rand::Rng; use camera::Camera; use hitable::Hit; use hitable_list::HitableList; use kdtree::KDTree; use material::Dielectric; use material::Lambertian; use material::Material; use material::Metal; use renderer::Opt; use renderer::Scene; use sphere::Sphere; use texture::CheckerTexture; use texture::ConstantTexture; use texture::EnvMap; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { let lookfrom = Vec3::new(13., 2., 3.); let lookat = Vec3::new(0., 0., 0.); let dist_to_focus = 10.; let aperture = 0.1; let time_min = 0.; let time_max = 1.; let camera = Camera::new( lookfrom, lookat, Vec3::new(0., 1., 0.), 50., opt.width as f32 / opt.height as f32, aperture, dist_to_focus, time_min, time_max, ); let ground_color = if opt.use_accel { [1.0, 0.4, 0.4] } else { [0.4, 1.0, 0.4] }; let world: Box = if opt.use_accel { Box::new(KDTree::new(random_scene(ground_color), time_min, time_max)) } else { Box::new(HitableList::new(random_scene(ground_color))) }; let skybox_bytes = include_bytes!("../../images/envmap.jpg"); let skybox = image::load_from_memory(skybox_bytes).unwrap().to_rgb(); Scene { camera, world, subsamples: opt.subsamples, width: opt.width, height: opt.height, global_illumination: true, env_map: Some(EnvMap::new(skybox)), } } fn random_scene(ground_color: V) -> Vec> where V: Into, { let mut rng = rand::thread_rng(); let checker = true; let ground_material: Box = if checker { Box::new(Lambertian::new(CheckerTexture::new( ConstantTexture::new([0., 0., 0.]), ConstantTexture::new(ground_color), ))) } else { Box::new(Lambertian::new(ConstantTexture::new(ground_color))) }; let mut objects: Vec> = vec![Box::new(Sphere::new( [0., -1000., 0.], 1000., ground_material, ))]; let mut random = || rng.gen_range::(0., 1.); for a in -11..11 { for b in -11..11 { let choose_mat = random(); let center = Vec3::new(a as f32 + 0.9 * random(), 0.2, b as f32 + 0.9 * random()); if (center - Vec3::new(4., 0.2, 0.)).length() > 0.9 { let sphere: Box = if choose_mat < 0.8 { // diffuse Box::new(Sphere::new( center, 0.2, Lambertian::new(ConstantTexture::new([ random() * random(), random() * random(), random() * random(), ])), )) } else if choose_mat < 0.95 { // metal Box::new(Sphere::new( center, 0.2, Metal::new( Vec3::new( 0.5 * (1. + random()), 0.5 * (1. + random()), 0.5 * (1. + random()), ), 0.5 * random(), ), )) } else { // glass Box::new(Sphere::new(center, 0.2, Dielectric::new(1.5))) }; objects.push(sphere); }; } } let more: Vec> = vec![ Box::new(Sphere::new( Vec3::new(0., 1., 0.), 1.0, Dielectric::new(1.5), )), Box::new(Sphere::new( Vec3::new(-4., 1., 0.), 1.0, Lambertian::new(ConstantTexture::new(Vec3::new(0.4, 0.2, 0.1))), )), Box::new(Sphere::new( Vec3::new(4., 1., 0.), 1.0, Metal::new(Vec3::new(0.7, 0.6, 0.5), 0.0), )), ]; objects.extend(more); objects }