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 aabb::AABB;
|
||||||
use material::Material;
|
use material::Material;
|
||||||
use ray::Ray;
|
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 hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord>;
|
||||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB>;
|
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 {
|
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.);
|
let fuzzy = fuzzy.min(1.);
|
||||||
Metal { albedo, fuzzy }
|
Metal {
|
||||||
|
albedo: albedo.into(),
|
||||||
|
fuzzy,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ pub enum Model {
|
|||||||
CornellBox,
|
CornellBox,
|
||||||
CornellSmoke,
|
CornellSmoke,
|
||||||
PerlinDebug,
|
PerlinDebug,
|
||||||
|
Final,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
@ -42,6 +43,7 @@ impl Model {
|
|||||||
Model::CornellBox => scenes::cornell_box::new(&opt),
|
Model::CornellBox => scenes::cornell_box::new(&opt),
|
||||||
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
||||||
Model::PerlinDebug => scenes::perlin_debug::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_box" => Ok(Model::CornellBox),
|
||||||
"cornell_smoke" => Ok(Model::CornellSmoke),
|
"cornell_smoke" => Ok(Model::CornellSmoke),
|
||||||
"perlin_debug" => Ok(Model::PerlinDebug),
|
"perlin_debug" => Ok(Model::PerlinDebug),
|
||||||
|
"final" => Ok(Model::Final),
|
||||||
_ => Err(ModelParseError(s.to_owned())),
|
_ => Err(ModelParseError(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,8 +88,8 @@ pub struct Opt {
|
|||||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||||
pub subsamples: usize,
|
pub subsamples: usize,
|
||||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
|
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
|
||||||
/// "cornell_smoke", "perlin_debug"
|
/// "cornell_smoke", "perlin_debug", "final"
|
||||||
#[structopt(long = "model", default_value = "perlin_debug")]
|
#[structopt(long = "model", default_value = "final")]
|
||||||
pub model: Model,
|
pub model: Model,
|
||||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||||
#[structopt(long = "pprof", parse(from_os_str))]
|
#[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 bvh;
|
||||||
pub mod cornell_box;
|
pub mod cornell_box;
|
||||||
pub mod cornell_smoke;
|
pub mod cornell_smoke;
|
||||||
|
pub mod final_scene;
|
||||||
pub mod perlin_debug;
|
pub mod perlin_debug;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod tutorial;
|
pub mod tutorial;
|
||||||
|
|||||||
@ -16,8 +16,14 @@ impl<H> Translate<H>
|
|||||||
where
|
where
|
||||||
H: Hit,
|
H: Hit,
|
||||||
{
|
{
|
||||||
pub fn new(hitable: H, offset: Vec3) -> Translate<H> {
|
pub fn new<V>(hitable: H, offset: V) -> Translate<H>
|
||||||
Translate { hitable, offset }
|
where
|
||||||
|
V: Into<Vec3>,
|
||||||
|
{
|
||||||
|
Translate {
|
||||||
|
hitable,
|
||||||
|
offset: offset.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user