Add ConstantMedium and cornell_smoke scene.
Shows the ability to compute smoke as a wrapper for anything implementing Hit.
This commit is contained in:
parent
36b2fba5b7
commit
6a1e8b2784
83
rtiow/src/constant_medium.rs
Normal file
83
rtiow/src/constant_medium.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use std;
|
||||
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
|
||||
use aabb::AABB;
|
||||
use hitable::Hit;
|
||||
use hitable::HitRecord;
|
||||
use material::Material;
|
||||
use ray::Ray;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub struct ConstantMedium<H, M>
|
||||
where
|
||||
H: Hit,
|
||||
M: Material,
|
||||
{
|
||||
density: f32,
|
||||
material: M,
|
||||
hitable: H,
|
||||
}
|
||||
|
||||
impl<H, M> ConstantMedium<H, M>
|
||||
where
|
||||
H: Hit,
|
||||
M: Material,
|
||||
{
|
||||
pub fn new(hitable: H, density: f32, material: M) -> ConstantMedium<H, M> {
|
||||
ConstantMedium {
|
||||
density,
|
||||
material,
|
||||
hitable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, M> Hit for ConstantMedium<H, M>
|
||||
where
|
||||
H: Hit,
|
||||
M: Material,
|
||||
{
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||
let mut rng = rand::thread_rng();
|
||||
if let Some(mut rec1) = self.hitable.hit(r, std::f32::MIN, std::f32::MAX) {
|
||||
if let Some(mut rec2) = self.hitable.hit(r, rec1.t + 0.001, std::f32::MAX) {
|
||||
if rec1.t < t_min {
|
||||
rec1.t = t_min;
|
||||
}
|
||||
if rec2.t > t_max {
|
||||
rec2.t = t_max;
|
||||
}
|
||||
if rec1.t >= rec2.t {
|
||||
return None;
|
||||
}
|
||||
if rec1.t < 0. {
|
||||
rec1.t = 0.;
|
||||
}
|
||||
let distance_inside_boundary = (rec2.t - rec1.t) * r.direction.length();
|
||||
let hit_distance = -(1. / self.density) * rng.gen_range::<f32>(0., 1.).ln();
|
||||
if hit_distance < distance_inside_boundary {
|
||||
let t = rec1.t + hit_distance / r.direction.length();
|
||||
let normal = Vec3::new(
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
).unit_vector();
|
||||
return Some(HitRecord {
|
||||
t,
|
||||
p: r.point_at_parameter(t),
|
||||
normal,
|
||||
material: &self.material,
|
||||
uv: (0., 0.),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
||||
self.hitable.bounding_box(t_min, t_max)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
pub mod aabb;
|
||||
pub mod bvh;
|
||||
pub mod camera;
|
||||
pub mod constant_medium;
|
||||
pub mod cuboid;
|
||||
pub mod flip_normals;
|
||||
pub mod hitable;
|
||||
|
||||
@ -214,3 +214,25 @@ where
|
||||
self.emit.value(u, v, p)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use texture::ConstantTexture;
|
||||
|
||||
#[test]
|
||||
fn arc_material() {
|
||||
let white: Arc<Material> =
|
||||
Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73])));
|
||||
|
||||
fn material_fn<M>(m: M)
|
||||
where
|
||||
M: Material,
|
||||
{
|
||||
let _ = m;
|
||||
}
|
||||
|
||||
material_fn(Arc::clone(&white));
|
||||
material_fn(Arc::clone(&white));
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ pub enum Model {
|
||||
BVH,
|
||||
Test,
|
||||
CornellBox,
|
||||
CornellSmoke,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@ -38,6 +39,7 @@ impl Model {
|
||||
Model::BVH => scenes::bvh::new(&opt),
|
||||
Model::Test => scenes::test::new(&opt),
|
||||
Model::CornellBox => scenes::cornell_box::new(&opt),
|
||||
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,6 +63,7 @@ impl str::FromStr for Model {
|
||||
"bvh" => Ok(Model::BVH),
|
||||
"test" => Ok(Model::Test),
|
||||
"cornell_box" => Ok(Model::CornellBox),
|
||||
"cornell_smoke" => Ok(Model::CornellSmoke),
|
||||
_ => Err(ModelParseError(s.to_owned())),
|
||||
}
|
||||
}
|
||||
@ -78,8 +81,9 @@ pub struct Opt {
|
||||
/// Sub-samples per pixel
|
||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||
pub subsamples: usize,
|
||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box"
|
||||
#[structopt(long = "model", default_value = "book")]
|
||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
|
||||
/// "cornell_smoke"
|
||||
#[structopt(long = "model", default_value = "cornell_smoke")]
|
||||
pub model: Model,
|
||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||
#[structopt(long = "pprof", parse(from_os_str))]
|
||||
|
||||
122
rtiow/src/scenes/cornell_smoke.rs
Normal file
122
rtiow/src/scenes/cornell_smoke.rs
Normal file
@ -0,0 +1,122 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use camera::Camera;
|
||||
use constant_medium::ConstantMedium;
|
||||
use cuboid::Cuboid;
|
||||
use flip_normals::FlipNormals;
|
||||
use hitable::Hit;
|
||||
use hitable_list::HitableList;
|
||||
use kdtree::KDTree;
|
||||
use material::DiffuseLight;
|
||||
use material::Lambertian;
|
||||
use material::Material;
|
||||
use rect::XYRect;
|
||||
use rect::XZRect;
|
||||
use rect::YZRect;
|
||||
use renderer::Opt;
|
||||
use renderer::Scene;
|
||||
use rotate::RotateY;
|
||||
use texture::ConstantTexture;
|
||||
use translate::Translate;
|
||||
use vec3::Vec3;
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(278., 278., -800.);
|
||||
let lookat = Vec3::new(278., 278., 0.);
|
||||
let dist_to_focus = 10.0;
|
||||
let aperture = 0.0;
|
||||
let time_min = 0.;
|
||||
let time_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,
|
||||
time_min,
|
||||
time_max,
|
||||
);
|
||||
|
||||
let red = Lambertian::new(ConstantTexture::new([0.65, 0.05, 0.05]));
|
||||
let white: Arc<Material> = Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73])));
|
||||
let green = Lambertian::new(ConstantTexture::new([0.12, 0.45, 0.15]));
|
||||
let light = DiffuseLight::new(ConstantTexture::new([7., 7., 7.]));
|
||||
|
||||
let objects: Vec<Box<Hit>> = vec![
|
||||
// White smoke box on the right
|
||||
Box::new(ConstantMedium::new(
|
||||
Translate::new(
|
||||
RotateY::new(
|
||||
Cuboid::new(
|
||||
Vec3::new(0., 0., 0.),
|
||||
Vec3::new(165., 165., 165.),
|
||||
Arc::clone(&white),
|
||||
),
|
||||
-18.,
|
||||
),
|
||||
Vec3::new(130., 0., 65.),
|
||||
),
|
||||
0.01,
|
||||
Lambertian::new(ConstantTexture::new([1., 1., 1.])),
|
||||
)),
|
||||
// Black smoke box on the left
|
||||
Box::new(ConstantMedium::new(
|
||||
Translate::new(
|
||||
RotateY::new(
|
||||
Cuboid::new(
|
||||
Vec3::new(0., 0., 0.),
|
||||
Vec3::new(165., 330., 165.),
|
||||
Arc::clone(&white),
|
||||
),
|
||||
15.,
|
||||
),
|
||||
Vec3::new(265., 0., 295.),
|
||||
),
|
||||
0.01,
|
||||
Lambertian::new(ConstantTexture::new([0., 0., 0.])),
|
||||
)),
|
||||
// Green wall left
|
||||
Box::new(FlipNormals::new(YZRect::new(
|
||||
0., 555., 0., 555., 555., green,
|
||||
))),
|
||||
// Red floor right
|
||||
Box::new(YZRect::new(0., 555., 0., 555., 0., red)),
|
||||
// Light in ceiling
|
||||
Box::new(XZRect::new(113., 443., 127., 432., 554., light)),
|
||||
// Grey ceiling
|
||||
Box::new(FlipNormals::new(XZRect::new(
|
||||
0.,
|
||||
555.,
|
||||
0.,
|
||||
555.,
|
||||
555.,
|
||||
Arc::clone(&white),
|
||||
))),
|
||||
// Grey floor
|
||||
Box::new(XZRect::new(0., 555., 0., 555., 0., Arc::clone(&white))),
|
||||
// Grey back wall
|
||||
Box::new(FlipNormals::new(XYRect::new(
|
||||
0.,
|
||||
555.,
|
||||
0.,
|
||||
555.,
|
||||
555.,
|
||||
Arc::clone(&white),
|
||||
))),
|
||||
];
|
||||
let world: Box<Hit> = if opt.use_accel {
|
||||
Box::new(KDTree::new(objects, time_min, time_max))
|
||||
} else {
|
||||
Box::new(HitableList::new(objects))
|
||||
};
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
subsamples: opt.subsamples,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
global_illumination: false,
|
||||
}
|
||||
}
|
||||
@ -2,5 +2,6 @@ pub mod bench;
|
||||
pub mod book;
|
||||
pub mod bvh;
|
||||
pub mod cornell_box;
|
||||
pub mod cornell_smoke;
|
||||
pub mod test;
|
||||
pub mod tutorial;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user