126 lines
3.6 KiB
Rust
126 lines
3.6 KiB
Rust
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::Metal;
|
|
use renderer::Opt;
|
|
use renderer::Scene;
|
|
use sphere::Sphere;
|
|
use texture::ConstantTexture;
|
|
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.),
|
|
20.,
|
|
opt.width as f32 / opt.height as f32,
|
|
aperture,
|
|
dist_to_focus,
|
|
time_min,
|
|
time_max,
|
|
);
|
|
let ground_color = if opt.use_accel {
|
|
Vec3::new(1.0, 0.4, 0.4)
|
|
} else {
|
|
Vec3::new(0.4, 1.0, 0.4)
|
|
};
|
|
let world: Box<Hit> = 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)))
|
|
};
|
|
Scene {
|
|
camera,
|
|
world,
|
|
subsamples: opt.subsamples,
|
|
width: opt.width,
|
|
height: opt.height,
|
|
}
|
|
}
|
|
|
|
fn random_scene(background_color: Vec3) -> Vec<Box<Hit>> {
|
|
let mut rng = rand::thread_rng();
|
|
let mut objects: Vec<Box<Hit>> = vec![Box::new(Sphere::new(
|
|
Vec3::new(0., -1000., 0.),
|
|
1000.,
|
|
Box::new(Lambertian::new(Box::new(ConstantTexture::new(
|
|
background_color,
|
|
)))),
|
|
))];
|
|
let mut random = || rng.gen_range::<f32>(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 = if choose_mat < 0.8 {
|
|
// diffuse
|
|
Box::new(Sphere::new(
|
|
center,
|
|
0.2,
|
|
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
|
random() * random(),
|
|
random() * random(),
|
|
random() * random(),
|
|
))))),
|
|
))
|
|
} else if choose_mat < 0.95 {
|
|
// metal
|
|
Box::new(Sphere::new(
|
|
center,
|
|
0.2,
|
|
Box::new(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, Box::new(Dielectric::new(1.5))))
|
|
};
|
|
objects.push(sphere);
|
|
};
|
|
}
|
|
}
|
|
|
|
let more: Vec<Box<Hit>> = vec![
|
|
Box::new(Sphere::new(
|
|
Vec3::new(0., 1., 0.),
|
|
1.0,
|
|
Box::new(Dielectric::new(1.5)),
|
|
)),
|
|
Box::new(Sphere::new(
|
|
Vec3::new(-4., 1., 0.),
|
|
1.0,
|
|
Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new(
|
|
0.4, 0.2, 0.1,
|
|
))))),
|
|
)),
|
|
Box::new(Sphere::new(
|
|
Vec3::new(4., 1., 0.),
|
|
1.0,
|
|
Box::new(Metal::new(Vec3::new(0.7, 0.6, 0.5), 0.0)),
|
|
)),
|
|
];
|
|
objects.extend(more);
|
|
objects
|
|
}
|