Move scene building to its own set of submodules.
This commit is contained in:
parent
aa26c79f6d
commit
57ccefbcdc
@ -3,340 +3,16 @@ extern crate log;
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rtiow;
|
extern crate rtiow;
|
||||||
extern crate stderrlog;
|
extern crate stderrlog;
|
||||||
#[macro_use]
|
|
||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::str;
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use rand::Rng;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use rtiow::bvh::BVH;
|
|
||||||
use rtiow::camera::Camera;
|
|
||||||
use rtiow::cube::Cube;
|
|
||||||
use rtiow::hitable::Hit;
|
|
||||||
use rtiow::hitable_list::HitableList;
|
|
||||||
use rtiow::material::Dielectric;
|
|
||||||
use rtiow::material::Lambertian;
|
|
||||||
use rtiow::material::Metal;
|
|
||||||
use rtiow::moving_sphere::MovingSphere;
|
|
||||||
use rtiow::renderer::render;
|
use rtiow::renderer::render;
|
||||||
use rtiow::renderer::Scene;
|
use rtiow::renderer::Model;
|
||||||
use rtiow::sphere::Sphere;
|
use rtiow::renderer::Opt;
|
||||||
use rtiow::vec3::Vec3;
|
use rtiow::scenes;
|
||||||
|
|
||||||
fn random_scene() -> 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(Vec3::new(0.5, 0.5, 0.5))),
|
|
||||||
))];
|
|
||||||
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(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(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
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_scene_book(bvh: bool, 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 world: Box<Hit>;
|
|
||||||
if bvh {
|
|
||||||
let b = BVH::new(random_scene(), time_min, time_max);
|
|
||||||
trace!(target: "bvh", "World {}", b);
|
|
||||||
world = Box::new(b);
|
|
||||||
} else {
|
|
||||||
world = Box::new(HitableList::new(random_scene()));
|
|
||||||
}
|
|
||||||
Scene {
|
|
||||||
camera,
|
|
||||||
world,
|
|
||||||
subsamples: opt.subsamples,
|
|
||||||
width: opt.width,
|
|
||||||
height: opt.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_scene_bvh(opt: &Opt) -> Scene {
|
|
||||||
let lookfrom = Vec3::new(3., 3., 2.);
|
|
||||||
let lookat = Vec3::new(0., 0., -1.);
|
|
||||||
let dist_to_focus = (lookfrom - lookat).length();
|
|
||||||
let aperture = 0.1;
|
|
||||||
let time_min = 0.;
|
|
||||||
let time_max = 1.;
|
|
||||||
let camera = Camera::new(
|
|
||||||
lookfrom,
|
|
||||||
lookat,
|
|
||||||
Vec3::new(0., 1., 0.),
|
|
||||||
45.,
|
|
||||||
opt.width as f32 / opt.height as f32,
|
|
||||||
aperture,
|
|
||||||
dist_to_focus,
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
);
|
|
||||||
let b = BVH::new(
|
|
||||||
vec![
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., -100.5, -1.),
|
|
||||||
100.,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(1., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
|
||||||
)),
|
|
||||||
Box::new(MovingSphere::new(
|
|
||||||
Vec3::new(-1., 0., -1.25),
|
|
||||||
Vec3::new(-1., 0., -0.75),
|
|
||||||
0.5,
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
);
|
|
||||||
trace!(target: "bvh", "World {}", b);
|
|
||||||
let world: Box<Hit> = Box::new(b);
|
|
||||||
Scene {
|
|
||||||
camera,
|
|
||||||
world,
|
|
||||||
subsamples: opt.subsamples,
|
|
||||||
width: opt.width,
|
|
||||||
height: opt.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_scene_tutorial(opt: &Opt) -> Scene {
|
|
||||||
let lookfrom = Vec3::new(3., 3., 2.);
|
|
||||||
let lookat = Vec3::new(0., 0., -1.);
|
|
||||||
let dist_to_focus = (lookfrom - lookat).length();
|
|
||||||
let aperture = 0.1;
|
|
||||||
let time_min = 0.;
|
|
||||||
let time_max = 1.;
|
|
||||||
let camera = Camera::new(
|
|
||||||
lookfrom,
|
|
||||||
lookat,
|
|
||||||
Vec3::new(0., 1., 0.),
|
|
||||||
45.,
|
|
||||||
opt.width as f32 / opt.height as f32,
|
|
||||||
aperture,
|
|
||||||
dist_to_focus,
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
);
|
|
||||||
let world: Box<Hit> = Box::new(HitableList::new(vec![
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., -100.5, -1.),
|
|
||||||
100.,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(1., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)),
|
|
||||||
)),
|
|
||||||
Box::new(MovingSphere::new(
|
|
||||||
Vec3::new(-1., 0., -1.25),
|
|
||||||
Vec3::new(-1., 0., -0.75),
|
|
||||||
0.5,
|
|
||||||
0.,
|
|
||||||
1.,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))),
|
|
||||||
)),
|
|
||||||
]));
|
|
||||||
Scene {
|
|
||||||
camera,
|
|
||||||
world,
|
|
||||||
subsamples: opt.subsamples,
|
|
||||||
width: opt.width,
|
|
||||||
height: opt.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_scene_cube(opt: &Opt) -> Scene {
|
|
||||||
let lookfrom = Vec3::new(3., 3., 2.);
|
|
||||||
let lookat = Vec3::new(0., 0., 0.);
|
|
||||||
let dist_to_focus = (lookfrom - lookat).length();
|
|
||||||
let aperture = 0.1;
|
|
||||||
let time_min = 0.;
|
|
||||||
let time_max = 1.;
|
|
||||||
let camera = Camera::new(
|
|
||||||
lookfrom,
|
|
||||||
lookat,
|
|
||||||
Vec3::new(0., 1., 0.),
|
|
||||||
45.,
|
|
||||||
opt.width as f32 / opt.height as f32,
|
|
||||||
aperture,
|
|
||||||
dist_to_focus,
|
|
||||||
time_min,
|
|
||||||
time_max,
|
|
||||||
);
|
|
||||||
let world: Box<Hit> = Box::new(HitableList::new(vec![
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., 0., -1.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
|
||||||
)),
|
|
||||||
Box::new(Cube::new(
|
|
||||||
Vec3::new(0., 0., 0.),
|
|
||||||
0.5,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.5, 0.2, 0.1))),
|
|
||||||
)),
|
|
||||||
Box::new(Sphere::new(
|
|
||||||
Vec3::new(0., -100.5, -1.),
|
|
||||||
100.,
|
|
||||||
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
|
||||||
)),
|
|
||||||
]));
|
|
||||||
Scene {
|
|
||||||
camera,
|
|
||||||
world,
|
|
||||||
subsamples: opt.subsamples,
|
|
||||||
width: opt.width,
|
|
||||||
height: opt.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Model {
|
|
||||||
Book,
|
|
||||||
BookBVH,
|
|
||||||
Tutorial,
|
|
||||||
Cube,
|
|
||||||
BVH,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ModelParseError(String);
|
|
||||||
|
|
||||||
impl fmt::Display for ModelParseError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "unknown model enum type '{}'", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl str::FromStr for Model {
|
|
||||||
type Err = ModelParseError;
|
|
||||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
|
||||||
match s {
|
|
||||||
"book" => Ok(Model::Book),
|
|
||||||
"book_bvh" => Ok(Model::BookBVH),
|
|
||||||
"tutorial" => Ok(Model::Tutorial),
|
|
||||||
"cube" => Ok(Model::Cube),
|
|
||||||
"bvh" => Ok(Model::BVH),
|
|
||||||
_ => Err(ModelParseError(s.to_owned())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
|
||||||
#[structopt(name = "tracer", about = "An experimental ray tracer.")]
|
|
||||||
pub struct Opt {
|
|
||||||
/// Image width
|
|
||||||
#[structopt(short = "w", long = "width", default_value = "1280")]
|
|
||||||
pub width: usize,
|
|
||||||
/// Image height
|
|
||||||
#[structopt(short = "h", long = "height", default_value = "720")]
|
|
||||||
pub height: usize,
|
|
||||||
/// Sub-samples per pixel
|
|
||||||
#[structopt(short = "s", long = "subsample", default_value = "10")]
|
|
||||||
pub subsamples: usize,
|
|
||||||
#[structopt(long = "model")]
|
|
||||||
pub model: Model,
|
|
||||||
|
|
||||||
/// Output directory
|
|
||||||
#[structopt(parse(from_os_str))]
|
|
||||||
pub output: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<(), std::io::Error> {
|
||||||
stderrlog::new()
|
stderrlog::new()
|
||||||
@ -347,11 +23,11 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
let scene = match opt.model {
|
let scene = match opt.model {
|
||||||
Model::Book => build_scene_book(false, &opt),
|
Model::Book => scenes::book::new(false, &opt),
|
||||||
Model::BookBVH => build_scene_book(true, &opt),
|
Model::BookBVH => scenes::book::new(true, &opt),
|
||||||
Model::Cube => build_scene_cube(&opt),
|
Model::Cube => scenes::cube::new(&opt),
|
||||||
Model::Tutorial => build_scene_tutorial(&opt),
|
Model::Tutorial => scenes::tutorial::new(&opt),
|
||||||
Model::BVH => build_scene_bvh(&opt),
|
Model::BVH => scenes::bvh::new(&opt),
|
||||||
};
|
};
|
||||||
let res = render(scene, &opt.output);
|
let res = render(scene, &opt.output);
|
||||||
let runtime = start.elapsed();
|
let runtime = start.elapsed();
|
||||||
|
|||||||
@ -8,6 +8,7 @@ pub mod material;
|
|||||||
pub mod moving_sphere;
|
pub mod moving_sphere;
|
||||||
pub mod ray;
|
pub mod ray;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
pub mod scenes;
|
||||||
pub mod sphere;
|
pub mod sphere;
|
||||||
pub mod vec3;
|
pub mod vec3;
|
||||||
|
|
||||||
@ -18,3 +19,5 @@ extern crate log;
|
|||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate structopt;
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
use std;
|
use std;
|
||||||
|
use std::fmt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::str;
|
||||||
use std::sync;
|
use std::sync;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
@ -15,6 +18,58 @@ use hitable::Hit;
|
|||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Model {
|
||||||
|
Book,
|
||||||
|
BookBVH,
|
||||||
|
Tutorial,
|
||||||
|
Cube,
|
||||||
|
BVH,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ModelParseError(String);
|
||||||
|
|
||||||
|
impl fmt::Display for ModelParseError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "unknown model enum type '{}'", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl str::FromStr for Model {
|
||||||
|
type Err = ModelParseError;
|
||||||
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"book" => Ok(Model::Book),
|
||||||
|
"book_bvh" => Ok(Model::BookBVH),
|
||||||
|
"tutorial" => Ok(Model::Tutorial),
|
||||||
|
"cube" => Ok(Model::Cube),
|
||||||
|
"bvh" => Ok(Model::BVH),
|
||||||
|
_ => Err(ModelParseError(s.to_owned())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
#[structopt(name = "tracer", about = "An experimental ray tracer.")]
|
||||||
|
pub struct Opt {
|
||||||
|
/// Image width
|
||||||
|
#[structopt(short = "w", long = "width", default_value = "1280")]
|
||||||
|
pub width: usize,
|
||||||
|
/// Image height
|
||||||
|
#[structopt(short = "h", long = "height", default_value = "720")]
|
||||||
|
pub height: usize,
|
||||||
|
/// Sub-samples per pixel
|
||||||
|
#[structopt(short = "s", long = "subsample", default_value = "10")]
|
||||||
|
pub subsamples: usize,
|
||||||
|
#[structopt(long = "model")]
|
||||||
|
pub model: Model,
|
||||||
|
|
||||||
|
/// Output directory
|
||||||
|
#[structopt(parse(from_os_str))]
|
||||||
|
pub output: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
pub world: Box<Hit>,
|
pub world: Box<Hit>,
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
|
|||||||
118
rtiow/src/scenes/book.rs
Normal file
118
rtiow/src/scenes/book.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use rand;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
use bvh::BVH;
|
||||||
|
use camera::Camera;
|
||||||
|
use hitable::Hit;
|
||||||
|
use hitable_list::HitableList;
|
||||||
|
use material::Dielectric;
|
||||||
|
use material::Lambertian;
|
||||||
|
use material::Metal;
|
||||||
|
use renderer::Opt;
|
||||||
|
use renderer::Scene;
|
||||||
|
use sphere::Sphere;
|
||||||
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
pub fn new(bvh: bool, 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 world: Box<Hit>;
|
||||||
|
if bvh {
|
||||||
|
let b = BVH::new(random_scene(), time_min, time_max);
|
||||||
|
trace!(target: "bvh", "World {}", b);
|
||||||
|
world = Box::new(b);
|
||||||
|
} else {
|
||||||
|
world = Box::new(HitableList::new(random_scene()));
|
||||||
|
}
|
||||||
|
Scene {
|
||||||
|
camera,
|
||||||
|
world,
|
||||||
|
subsamples: opt.subsamples,
|
||||||
|
width: opt.width,
|
||||||
|
height: opt.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_scene() -> 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(Vec3::new(0.5, 0.5, 0.5))),
|
||||||
|
))];
|
||||||
|
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(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(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
|
||||||
|
}
|
||||||
68
rtiow/src/scenes/bvh.rs
Normal file
68
rtiow/src/scenes/bvh.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use bvh::BVH;
|
||||||
|
use camera::Camera;
|
||||||
|
use hitable::Hit;
|
||||||
|
use material::Lambertian;
|
||||||
|
use material::Metal;
|
||||||
|
use moving_sphere::MovingSphere;
|
||||||
|
use renderer::Opt;
|
||||||
|
use renderer::Scene;
|
||||||
|
use sphere::Sphere;
|
||||||
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
pub fn new(opt: &Opt) -> Scene {
|
||||||
|
let lookfrom = Vec3::new(3., 3., 2.);
|
||||||
|
let lookat = Vec3::new(0., 0., -1.);
|
||||||
|
let dist_to_focus = (lookfrom - lookat).length();
|
||||||
|
let aperture = 0.1;
|
||||||
|
let time_min = 0.;
|
||||||
|
let time_max = 1.;
|
||||||
|
let camera = Camera::new(
|
||||||
|
lookfrom,
|
||||||
|
lookat,
|
||||||
|
Vec3::new(0., 1., 0.),
|
||||||
|
45.,
|
||||||
|
opt.width as f32 / opt.height as f32,
|
||||||
|
aperture,
|
||||||
|
dist_to_focus,
|
||||||
|
time_min,
|
||||||
|
time_max,
|
||||||
|
);
|
||||||
|
let b = BVH::new(
|
||||||
|
vec![
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., 0., -1.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
|
)),
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., -100.5, -1.),
|
||||||
|
100.,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
||||||
|
)),
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(1., 0., -1.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Metal::new(Vec3::new(0.6, 0.6, 0.6), 0.2)),
|
||||||
|
)),
|
||||||
|
Box::new(MovingSphere::new(
|
||||||
|
Vec3::new(-1., 0., -1.25),
|
||||||
|
Vec3::new(-1., 0., -0.75),
|
||||||
|
0.5,
|
||||||
|
time_min,
|
||||||
|
time_max,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
time_min,
|
||||||
|
time_max,
|
||||||
|
);
|
||||||
|
trace!(target: "bvh", "World {}", b);
|
||||||
|
let world: Box<Hit> = Box::new(b);
|
||||||
|
Scene {
|
||||||
|
camera,
|
||||||
|
world,
|
||||||
|
subsamples: opt.subsamples,
|
||||||
|
width: opt.width,
|
||||||
|
height: opt.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
53
rtiow/src/scenes/cube.rs
Normal file
53
rtiow/src/scenes/cube.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use camera::Camera;
|
||||||
|
use cube::Cube;
|
||||||
|
use hitable::Hit;
|
||||||
|
use hitable_list::HitableList;
|
||||||
|
use material::Lambertian;
|
||||||
|
use renderer::Opt;
|
||||||
|
use renderer::Scene;
|
||||||
|
use sphere::Sphere;
|
||||||
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
pub fn new(opt: &Opt) -> Scene {
|
||||||
|
let lookfrom = Vec3::new(3., 3., 2.);
|
||||||
|
let lookat = Vec3::new(0., 0., 0.);
|
||||||
|
let dist_to_focus = (lookfrom - lookat).length();
|
||||||
|
let aperture = 0.1;
|
||||||
|
let time_min = 0.;
|
||||||
|
let time_max = 1.;
|
||||||
|
let camera = Camera::new(
|
||||||
|
lookfrom,
|
||||||
|
lookat,
|
||||||
|
Vec3::new(0., 1., 0.),
|
||||||
|
45.,
|
||||||
|
opt.width as f32 / opt.height as f32,
|
||||||
|
aperture,
|
||||||
|
dist_to_focus,
|
||||||
|
time_min,
|
||||||
|
time_max,
|
||||||
|
);
|
||||||
|
let world: Box<Hit> = Box::new(HitableList::new(vec![
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., 0., -1.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
|
)),
|
||||||
|
Box::new(Cube::new(
|
||||||
|
Vec3::new(0., 0., 0.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.5, 0.2, 0.1))),
|
||||||
|
)),
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., -100.5, -1.),
|
||||||
|
100.,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
||||||
|
)),
|
||||||
|
]));
|
||||||
|
Scene {
|
||||||
|
camera,
|
||||||
|
world,
|
||||||
|
subsamples: opt.subsamples,
|
||||||
|
width: opt.width,
|
||||||
|
height: opt.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
4
rtiow/src/scenes/mod.rs
Normal file
4
rtiow/src/scenes/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod book;
|
||||||
|
pub mod bvh;
|
||||||
|
pub mod cube;
|
||||||
|
pub mod tutorial;
|
||||||
62
rtiow/src/scenes/tutorial.rs
Normal file
62
rtiow/src/scenes/tutorial.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use camera::Camera;
|
||||||
|
use hitable::Hit;
|
||||||
|
use hitable_list::HitableList;
|
||||||
|
use material::Lambertian;
|
||||||
|
use material::Metal;
|
||||||
|
use moving_sphere::MovingSphere;
|
||||||
|
use renderer::Opt;
|
||||||
|
use renderer::Scene;
|
||||||
|
use sphere::Sphere;
|
||||||
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
pub fn new(opt: &Opt) -> Scene {
|
||||||
|
let lookfrom = Vec3::new(3., 3., 2.);
|
||||||
|
let lookat = Vec3::new(0., 0., -1.);
|
||||||
|
let dist_to_focus = (lookfrom - lookat).length();
|
||||||
|
let aperture = 0.1;
|
||||||
|
let time_min = 0.;
|
||||||
|
let time_max = 1.;
|
||||||
|
let camera = Camera::new(
|
||||||
|
lookfrom,
|
||||||
|
lookat,
|
||||||
|
Vec3::new(0., 1., 0.),
|
||||||
|
45.,
|
||||||
|
opt.width as f32 / opt.height as f32,
|
||||||
|
aperture,
|
||||||
|
dist_to_focus,
|
||||||
|
time_min,
|
||||||
|
time_max,
|
||||||
|
);
|
||||||
|
let world: Box<Hit> = Box::new(HitableList::new(vec![
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., 0., -1.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||||
|
)),
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(0., -100.5, -1.),
|
||||||
|
100.,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))),
|
||||||
|
)),
|
||||||
|
Box::new(Sphere::new(
|
||||||
|
Vec3::new(1., 0., -1.),
|
||||||
|
0.5,
|
||||||
|
Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)),
|
||||||
|
)),
|
||||||
|
Box::new(MovingSphere::new(
|
||||||
|
Vec3::new(-1., 0., -1.25),
|
||||||
|
Vec3::new(-1., 0., -0.75),
|
||||||
|
0.5,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))),
|
||||||
|
)),
|
||||||
|
]));
|
||||||
|
Scene {
|
||||||
|
camera,
|
||||||
|
world,
|
||||||
|
subsamples: opt.subsamples,
|
||||||
|
width: opt.width,
|
||||||
|
height: opt.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user