Add scene representing the final image in raytracingthenextweek.
This commit is contained in:
parent
7898e7022c
commit
bf633756f6
@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use aabb::AABB;
|
||||
use material::Material;
|
||||
use ray::Ray;
|
||||
@ -15,3 +17,12 @@ pub trait Hit: Send + Sync {
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord>;
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB>;
|
||||
}
|
||||
|
||||
impl Hit for Arc<Hit> {
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||
(**self).hit(r, t_min, t_max)
|
||||
}
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
||||
(**self).bounding_box(t_min, t_max)
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,9 +127,15 @@ fn reflect(v: Vec3, n: Vec3) -> Vec3 {
|
||||
}
|
||||
|
||||
impl Metal {
|
||||
pub fn new(albedo: Vec3, fuzzy: f32) -> Metal {
|
||||
pub fn new<V>(albedo: V, fuzzy: f32) -> Metal
|
||||
where
|
||||
V: Into<Vec3>,
|
||||
{
|
||||
let fuzzy = fuzzy.min(1.);
|
||||
Metal { albedo, fuzzy }
|
||||
Metal {
|
||||
albedo: albedo.into(),
|
||||
fuzzy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ pub enum Model {
|
||||
CornellBox,
|
||||
CornellSmoke,
|
||||
PerlinDebug,
|
||||
Final,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@ -42,6 +43,7 @@ impl Model {
|
||||
Model::CornellBox => scenes::cornell_box::new(&opt),
|
||||
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
||||
Model::PerlinDebug => scenes::perlin_debug::new(&opt),
|
||||
Model::Final => scenes::final_scene::new(&opt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,6 +69,7 @@ impl str::FromStr for Model {
|
||||
"cornell_box" => Ok(Model::CornellBox),
|
||||
"cornell_smoke" => Ok(Model::CornellSmoke),
|
||||
"perlin_debug" => Ok(Model::PerlinDebug),
|
||||
"final" => Ok(Model::Final),
|
||||
_ => Err(ModelParseError(s.to_owned())),
|
||||
}
|
||||
}
|
||||
@ -85,8 +88,8 @@ pub struct Opt {
|
||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||
pub subsamples: usize,
|
||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
|
||||
/// "cornell_smoke", "perlin_debug"
|
||||
#[structopt(long = "model", default_value = "perlin_debug")]
|
||||
/// "cornell_smoke", "perlin_debug", "final"
|
||||
#[structopt(long = "model", default_value = "final")]
|
||||
pub model: Model,
|
||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||
#[structopt(long = "pprof", parse(from_os_str))]
|
||||
|
||||
164
rtiow/src/scenes/final_scene.rs
Normal file
164
rtiow/src/scenes/final_scene.rs
Normal file
@ -0,0 +1,164 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use image;
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
|
||||
use camera::Camera;
|
||||
use constant_medium::ConstantMedium;
|
||||
use cuboid::Cuboid;
|
||||
use hitable::Hit;
|
||||
use hitable_list::HitableList;
|
||||
use kdtree::KDTree;
|
||||
use material::Dielectric;
|
||||
use material::DiffuseLight;
|
||||
use material::Lambertian;
|
||||
use material::Material;
|
||||
use material::Metal;
|
||||
use moving_sphere::MovingSphere;
|
||||
use rect::XZRect;
|
||||
use renderer::Opt;
|
||||
use renderer::Scene;
|
||||
use rotate::RotateY;
|
||||
use sphere::Sphere;
|
||||
use texture::ConstantTexture;
|
||||
use texture::ImageTexture;
|
||||
use texture::NoiseTexture;
|
||||
use translate::Translate;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(478., 278., -600.);
|
||||
let lookat = Vec3::new(278., 278., 0.);
|
||||
let dist_to_focus = 10.;
|
||||
let aperture = 0.1;
|
||||
let t_min = 0.;
|
||||
let t_max = 1.;
|
||||
let camera = Camera::new(
|
||||
lookfrom,
|
||||
lookat,
|
||||
Vec3::new(0., 1., 0.),
|
||||
40.,
|
||||
opt.width as f32 / opt.height as f32,
|
||||
aperture,
|
||||
dist_to_focus,
|
||||
t_min,
|
||||
t_max,
|
||||
);
|
||||
|
||||
let nb = 20;
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut boxlist: Vec<Box<Hit>> = Vec::with_capacity(10000);
|
||||
let mut list: Vec<Box<Hit>> = Vec::new();
|
||||
let white: Arc<Material> = Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73])));
|
||||
let ground: Arc<Material> = Arc::new(Lambertian::new(ConstantTexture::new([0.48, 0.83, 0.53])));
|
||||
for i in 0..nb {
|
||||
for j in 0..nb {
|
||||
let w = 100.;
|
||||
let x0 = -1000. + i as f32 * w;
|
||||
let z0 = -1000. + j as f32 * w;
|
||||
let y0 = 0.;
|
||||
let x1 = x0 + w;
|
||||
let y1 = 100. * (rng.gen_range::<f32>(0., 1.) + 0.01);
|
||||
let z1 = z0 + w;
|
||||
boxlist.push(Box::new(Cuboid::new(
|
||||
Vec3::new(x0, y0, z0),
|
||||
Vec3::new(x1, y1, z1),
|
||||
Arc::clone(&ground),
|
||||
)));
|
||||
}
|
||||
}
|
||||
list.push(Box::new(KDTree::new(boxlist, t_min, t_max)));
|
||||
|
||||
let light = DiffuseLight::new(ConstantTexture::new([7., 7., 7.]));
|
||||
// Light in ceiling
|
||||
list.push(Box::new(XZRect::new(123., 423., 147., 412., 554., light)));
|
||||
|
||||
let center = Vec3::new(400., 400., 200.);
|
||||
// Moving brownish ball
|
||||
list.push(Box::new(MovingSphere::new(
|
||||
center,
|
||||
center + Vec3::new(30., 0., 0.),
|
||||
50.,
|
||||
t_min,
|
||||
t_max,
|
||||
Lambertian::new(ConstantTexture::new([0.7, 0.3, 0.1])),
|
||||
)));
|
||||
|
||||
// Glass ball, lower-left corner
|
||||
list.push(Box::new(Sphere::new(
|
||||
[260., 150., 45.],
|
||||
50.,
|
||||
Dielectric::new(1.5),
|
||||
)));
|
||||
// Metal ball lower-right corner
|
||||
list.push(Box::new(Sphere::new(
|
||||
[0., 150., 145.],
|
||||
50.,
|
||||
Metal::new([0.8, 0.8, 0.9], 10.0),
|
||||
)));
|
||||
|
||||
// Blue smokey glass ball lower-left
|
||||
let boundary: Arc<Hit> = Arc::new(Sphere::new([360., 150., 145.], 70., Dielectric::new(1.5)));
|
||||
list.push(Box::new(Arc::clone(&boundary)));
|
||||
list.push(Box::new(ConstantMedium::new(
|
||||
Arc::clone(&boundary),
|
||||
0.2,
|
||||
ConstantTexture::new([0.2, 0.4, 0.9]),
|
||||
)));
|
||||
|
||||
// General white mist over whole scene
|
||||
let boundary: Arc<Hit> = Arc::new(Sphere::new([0., 0., 0.], 5000., Dielectric::new(1.5)));
|
||||
list.push(Box::new(Arc::clone(&boundary)));
|
||||
list.push(Box::new(ConstantMedium::new(
|
||||
Arc::clone(&boundary),
|
||||
0.0001,
|
||||
ConstantTexture::new([1.0, 1.0, 1.0]),
|
||||
)));
|
||||
|
||||
// Earth sphere
|
||||
let world_image_bytes = include_bytes!("../../images/world.jpg");
|
||||
let world = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
||||
list.push(Box::new(Sphere::new(
|
||||
Vec3::new(400., 200., 400.),
|
||||
100.,
|
||||
Lambertian::new(world),
|
||||
)));
|
||||
|
||||
// Perlin noise sphere
|
||||
let pertext = NoiseTexture::with_scale(0.1);
|
||||
list.push(Box::new(Sphere::new(
|
||||
[220., 280., 300.],
|
||||
80.,
|
||||
Lambertian::new(pertext),
|
||||
)));
|
||||
|
||||
// White 'cube' made of 1000 spheres
|
||||
let ns = 1000;
|
||||
let mut boxlist: Vec<Box<Hit>> = Vec::with_capacity(1000);
|
||||
for _ in 0..ns {
|
||||
boxlist.push(Box::new(Sphere::new(
|
||||
[
|
||||
165. * rng.gen_range::<f32>(0., 1.),
|
||||
165. * rng.gen_range::<f32>(0., 1.),
|
||||
165. * rng.gen_range::<f32>(0., 1.),
|
||||
],
|
||||
10.,
|
||||
Arc::clone(&white),
|
||||
)));
|
||||
}
|
||||
list.push(Box::new(Translate::new(
|
||||
RotateY::new(KDTree::new(boxlist, t_min, t_max), 15.),
|
||||
[-100., 270., 395.],
|
||||
)));
|
||||
|
||||
Scene {
|
||||
camera,
|
||||
world: Box::new(HitableList::new(list)),
|
||||
subsamples: opt.subsamples,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
global_illumination: false,
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ pub mod book;
|
||||
pub mod bvh;
|
||||
pub mod cornell_box;
|
||||
pub mod cornell_smoke;
|
||||
pub mod final_scene;
|
||||
pub mod perlin_debug;
|
||||
pub mod test;
|
||||
pub mod tutorial;
|
||||
|
||||
@ -16,8 +16,14 @@ impl<H> Translate<H>
|
||||
where
|
||||
H: Hit,
|
||||
{
|
||||
pub fn new(hitable: H, offset: Vec3) -> Translate<H> {
|
||||
Translate { hitable, offset }
|
||||
pub fn new<V>(hitable: H, offset: V) -> Translate<H>
|
||||
where
|
||||
V: Into<Vec3>,
|
||||
{
|
||||
Translate {
|
||||
hitable,
|
||||
offset: offset.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user