rtiow: add dragon scene, tune stltest to compare with cuboid.
Refactor enum Model to use strum.
This commit is contained in:
parent
fc1bfa419e
commit
beeb5e479b
41
rtiow/Cargo.lock
generated
41
rtiow/Cargo.lock
generated
@ -1229,6 +1229,12 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
@ -2434,6 +2440,8 @@ dependencies = [
|
||||
"serde_json",
|
||||
"stl",
|
||||
"structopt 0.2.18",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"vec3",
|
||||
]
|
||||
|
||||
@ -2462,6 +2470,12 @@ dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.12"
|
||||
@ -2740,7 +2754,7 @@ version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
@ -2752,13 +2766,35 @@ version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.50",
|
||||
"quote 1.0.23",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||
dependencies = [
|
||||
"heck 0.4.0",
|
||||
"proc-macro2 1.0.50",
|
||||
"quote 1.0.23",
|
||||
"rustversion",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
@ -3163,6 +3199,7 @@ dependencies = [
|
||||
"renderer",
|
||||
"stderrlog",
|
||||
"structopt 0.2.18",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -27,6 +27,8 @@ serde_json = "1.0.91"
|
||||
structopt = "0.2.18"
|
||||
vec3 = {path = "../vec3"}
|
||||
stl = {path = "../../../stl"}
|
||||
strum = { version = "0.24.1", features = ["derive"] }
|
||||
strum_macros = "0.24.3"
|
||||
#stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"}
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@ -30,8 +30,10 @@ use crate::{
|
||||
texture::{ConstantTexture, EnvMap},
|
||||
vec3::Vec3,
|
||||
};
|
||||
use strum::{EnumString, EnumVariantNames};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, EnumString, EnumVariantNames, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum Model {
|
||||
BVH,
|
||||
Bench,
|
||||
@ -46,6 +48,7 @@ pub enum Model {
|
||||
Test,
|
||||
Tron,
|
||||
Tutorial,
|
||||
Dragon,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@ -56,6 +59,7 @@ impl Model {
|
||||
Model::Book => scenes::book::new(opt),
|
||||
Model::CornellBox => scenes::cornell_box::new(opt),
|
||||
Model::CornellSmoke => scenes::cornell_smoke::new(opt),
|
||||
Model::Dragon => scenes::dragon::new(opt),
|
||||
Model::Final => scenes::final_scene::new(opt),
|
||||
Model::Mandelbrot => scenes::mandelbrot::new(opt),
|
||||
Model::PerlinDebug => scenes::perlin_debug::new(opt),
|
||||
@ -77,48 +81,6 @@ impl fmt::Display for ModelParseError {
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for Model {
|
||||
type Err = ModelParseError;
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s {
|
||||
"bench" => Ok(Model::Bench),
|
||||
"book" => Ok(Model::Book),
|
||||
"bvh" => Ok(Model::BVH),
|
||||
"cornell_box" => Ok(Model::CornellBox),
|
||||
"cornell_smoke" => Ok(Model::CornellSmoke),
|
||||
"final" => Ok(Model::Final),
|
||||
"mandelbrot" => Ok(Model::Mandelbrot),
|
||||
"perlin_debug" => Ok(Model::PerlinDebug),
|
||||
"spheramid" => Ok(Model::Spheramid),
|
||||
"stltest" => Ok(Model::Stltest),
|
||||
"test" => Ok(Model::Test),
|
||||
"tron" => Ok(Model::Tron),
|
||||
"tutorial" => Ok(Model::Tutorial),
|
||||
_ => Err(ModelParseError(s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::string::ToString for Model {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Model::BVH => "bvh".to_string(),
|
||||
Model::Bench => "bench".to_string(),
|
||||
Model::Book => "book".to_string(),
|
||||
Model::CornellBox => "cornell_box".to_string(),
|
||||
Model::CornellSmoke => "cornell_smoke".to_string(),
|
||||
Model::Final => "final".to_string(),
|
||||
Model::Mandelbrot => "mandelbrot".to_string(),
|
||||
Model::PerlinDebug => "perlin_debug".to_string(),
|
||||
Model::Spheramid => "spheramid".to_string(),
|
||||
Model::Stltest => "stltest".to_string(),
|
||||
Model::Test => "test".to_string(),
|
||||
Model::Tron => "tron".to_string(),
|
||||
Model::Tutorial => "tutorial".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(name = "tracer", about = "An experimental ray tracer.")]
|
||||
pub struct Opt {
|
||||
@ -134,10 +96,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",
|
||||
/// "cornell_smoke", "perlin_debug", "final"
|
||||
#[structopt(long = "model", default_value = "book")]
|
||||
pub model: Model,
|
||||
/// Select scene to render.
|
||||
#[structopt(long = "model")]
|
||||
pub model: Option<Model>,
|
||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||
#[structopt(long = "pprof", parse(from_os_str))]
|
||||
pub pprof: Option<PathBuf>,
|
||||
@ -158,7 +119,7 @@ pub fn opt_hash(opt: &Opt) -> String {
|
||||
opt.height,
|
||||
opt.subsamples,
|
||||
opt.pprof.is_some(),
|
||||
opt.model.to_string(),
|
||||
opt.model.as_ref().unwrap().to_string(),
|
||||
opt.use_accel,
|
||||
opt.output.display().to_string().replace('/', "_")
|
||||
)
|
||||
|
||||
119
rtiow/renderer/src/scenes/dragon.rs
Normal file
119
rtiow/renderer/src/scenes/dragon.rs
Normal file
@ -0,0 +1,119 @@
|
||||
use std::{
|
||||
io::{BufReader, Cursor},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use stl::STL;
|
||||
|
||||
use crate::{
|
||||
bvh_triangles::BVHTriangles,
|
||||
camera::Camera,
|
||||
cuboid::Cuboid,
|
||||
hitable::Hit,
|
||||
hitable_list::HitableList,
|
||||
kdtree::KDTree,
|
||||
material::{Dielectric, DiffuseLight, Lambertian, Metal},
|
||||
rect::{XYRect, XZRect},
|
||||
renderer::{Opt, Scene},
|
||||
scale::Scale,
|
||||
sphere::Sphere,
|
||||
texture::{ConstantTexture, EnvMap},
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(0., 40., -100.);
|
||||
let lookat = Vec3::new(0., 10., 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.),
|
||||
45.,
|
||||
opt.width as f32 / opt.height as f32,
|
||||
aperture,
|
||||
dist_to_focus,
|
||||
time_min,
|
||||
time_max,
|
||||
);
|
||||
let ground_color = if opt.use_accel {
|
||||
ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4))
|
||||
} else {
|
||||
ConstantTexture::new(Vec3::new(0.4, 0.4, 0.4))
|
||||
};
|
||||
|
||||
let stl_cube = STL::parse(
|
||||
BufReader::new(Cursor::new(include_bytes!(
|
||||
"../../stls/cube.stl"
|
||||
//"../../stls/stanford_dragon-lowres.stl" //"../../stls/stanford_dragon.stl"
|
||||
))),
|
||||
false,
|
||||
)
|
||||
.expect("failed to parse cube");
|
||||
let light_size = 50.;
|
||||
let light_height = 200.;
|
||||
let objects: Vec<Box<dyn Hit>> = vec![
|
||||
// Light from above - white
|
||||
// Earth sized sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., -10000., 0.),
|
||||
10000.,
|
||||
Lambertian::new(ground_color),
|
||||
)),
|
||||
// Blue sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., 20., 40.),
|
||||
20.,
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.2, 1.))),
|
||||
)),
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(40., 20., 40.),
|
||||
20.,
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 1.0, 0.2))),
|
||||
)),
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(-40., 20., 40.),
|
||||
20.,
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(1.0, 0.2, 0.2))),
|
||||
)),
|
||||
// STL Mesh
|
||||
Box::new(Scale::new(
|
||||
BVHTriangles::new(
|
||||
&stl_cube,
|
||||
Dielectric::new(1.5),
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
//Lambertian::new(ConstantTexture::new(Vec3::new(1.0, 0.2, 0.2))),
|
||||
),
|
||||
1.,
|
||||
//250.,
|
||||
)),
|
||||
Box::new(Cuboid::new(
|
||||
[-20., 0., 0.].into(),
|
||||
[0., 20., 20.].into(),
|
||||
Arc::new(Dielectric::new(1.5)),
|
||||
)),
|
||||
];
|
||||
let world: Box<dyn Hit> = if opt.use_accel {
|
||||
Box::new(KDTree::new(objects, time_min, time_max))
|
||||
} else {
|
||||
Box::new(HitableList::new(objects))
|
||||
};
|
||||
let skybox_bytes = include_bytes!("../../images/envmap.jpg");
|
||||
let skybox = image::load_from_memory(skybox_bytes).unwrap().to_rgb();
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
subsamples: opt.subsamples,
|
||||
num_threads: opt.num_threads,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
global_illumination: true,
|
||||
env_map: Some(EnvMap::new(skybox)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ pub mod book;
|
||||
pub mod bvh;
|
||||
pub mod cornell_box;
|
||||
pub mod cornell_smoke;
|
||||
pub mod dragon;
|
||||
pub mod final_scene;
|
||||
pub mod mandelbrot;
|
||||
pub mod perlin_debug;
|
||||
|
||||
@ -1,23 +1,28 @@
|
||||
use std::io::{BufReader, Cursor};
|
||||
use std::{
|
||||
io::{BufReader, Cursor},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use stl::STL;
|
||||
|
||||
use crate::{
|
||||
bvh_triangles::BVHTriangles,
|
||||
camera::Camera,
|
||||
cuboid::Cuboid,
|
||||
hitable::Hit,
|
||||
hitable_list::HitableList,
|
||||
kdtree::KDTree,
|
||||
material::{DiffuseLight, Lambertian, Metal},
|
||||
material::{Dielectric, DiffuseLight, Lambertian, Metal},
|
||||
rect::{XYRect, XZRect},
|
||||
renderer::{Opt, Scene},
|
||||
scale::Scale,
|
||||
sphere::Sphere,
|
||||
texture::ConstantTexture,
|
||||
texture::{ConstantTexture, EnvMap},
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(-20., 100., -100.);
|
||||
let lookfrom = Vec3::new(0., 40., -100.);
|
||||
let lookat = Vec3::new(0., 10., 0.);
|
||||
let dist_to_focus = 10.0;
|
||||
let aperture = 0.0;
|
||||
@ -41,9 +46,7 @@ pub fn new(opt: &Opt) -> Scene {
|
||||
};
|
||||
|
||||
let stl_cube = STL::parse(
|
||||
BufReader::new(Cursor::new(include_bytes!(
|
||||
"../../stls/stanford_dragon-lowres.stl"
|
||||
))),
|
||||
BufReader::new(Cursor::new(include_bytes!("../../stls/cube.stl"))),
|
||||
false,
|
||||
)
|
||||
.expect("failed to parse cube");
|
||||
@ -51,65 +54,41 @@ pub fn new(opt: &Opt) -> Scene {
|
||||
let light_height = 200.;
|
||||
let objects: Vec<Box<dyn Hit>> = vec![
|
||||
// Light from above - white
|
||||
Box::new(XZRect::new(
|
||||
-light_size,
|
||||
light_size,
|
||||
-light_size,
|
||||
light_size,
|
||||
light_height,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(15., 15., 15.))),
|
||||
)),
|
||||
// Light from back - green
|
||||
Box::new(XYRect::new(
|
||||
-light_size,
|
||||
light_size,
|
||||
-light_size,
|
||||
light_size,
|
||||
-light_height,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 15., 1.))),
|
||||
)),
|
||||
// Light from front - blue
|
||||
Box::new(XYRect::new(
|
||||
-light_size,
|
||||
light_size,
|
||||
-light_size,
|
||||
light_size,
|
||||
light_height,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 15.))),
|
||||
)),
|
||||
// Earth sized sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., -1200., 0.),
|
||||
1000.,
|
||||
Vec3::new(0., -10000., 0.),
|
||||
10000.,
|
||||
Lambertian::new(ground_color),
|
||||
)),
|
||||
/*
|
||||
// Blue sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(-40., 20., 0.),
|
||||
Vec3::new(0., 20., 40.),
|
||||
20.,
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.2, 1.))),
|
||||
)),
|
||||
*/
|
||||
// Shiny sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(40., 20., -40.),
|
||||
Vec3::new(40., 20., 40.),
|
||||
20.,
|
||||
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 1.0, 0.2))),
|
||||
)),
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(-40., 20., 40.),
|
||||
20.,
|
||||
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(1.0, 0.2, 0.2))),
|
||||
)),
|
||||
// STL Mesh
|
||||
Box::new(Scale::new(
|
||||
BVHTriangles::new(
|
||||
Box::new(BVHTriangles::new(
|
||||
&stl_cube,
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(0.6, 0.6, 0.6))),
|
||||
),
|
||||
//1.,
|
||||
250.,
|
||||
Dielectric::new(1.5),
|
||||
//Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
//Lambertian::new(ConstantTexture::new(Vec3::new(1.0, 0.2, 0.2))),
|
||||
)),
|
||||
Box::new(Cuboid::new(
|
||||
[-20., 0., 0.].into(),
|
||||
[0., 20., 20.].into(),
|
||||
Arc::new(Dielectric::new(1.5)),
|
||||
)),
|
||||
];
|
||||
let world: Box<dyn Hit> = if opt.use_accel {
|
||||
@ -117,6 +96,8 @@ pub fn new(opt: &Opt) -> Scene {
|
||||
} else {
|
||||
Box::new(HitableList::new(objects))
|
||||
};
|
||||
let skybox_bytes = include_bytes!("../../images/envmap.jpg");
|
||||
let skybox = image::load_from_memory(skybox_bytes).unwrap().to_rgb();
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
@ -124,6 +105,8 @@ pub fn new(opt: &Opt) -> Scene {
|
||||
num_threads: opt.num_threads,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
global_illumination: true,
|
||||
env_map: Some(EnvMap::new(skybox)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
1
rtiow/renderer/stls/stanford_dragon-lowres.stl
Symbolic link
1
rtiow/renderer/stls/stanford_dragon-lowres.stl
Symbolic link
@ -0,0 +1 @@
|
||||
/home/wathiede/3dprint/stl/stanford_dragon-lowres.stl
|
||||
@ -11,3 +11,4 @@ log = "0.4.17"
|
||||
renderer = { path = "../renderer" }
|
||||
stderrlog = "0.4.3"
|
||||
structopt = "0.2.18"
|
||||
strum = "0.24.1"
|
||||
|
||||
@ -6,7 +6,8 @@ use cpuprofiler::PROFILER;
|
||||
use log::info;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use renderer::renderer::{render, Opt};
|
||||
use renderer::renderer::{render, Model, Opt};
|
||||
use strum::VariantNames;
|
||||
|
||||
#[cfg(not(feature = "profile"))]
|
||||
struct MockTimer;
|
||||
@ -41,8 +42,12 @@ fn main() -> Result<(), std::io::Error> {
|
||||
.init()
|
||||
.unwrap();
|
||||
let opt = Opt::from_args();
|
||||
if opt.model.is_none() {
|
||||
eprintln!("--model should be one of {:?}", Model::VARIANTS);
|
||||
return Ok(());
|
||||
}
|
||||
info!("{:?}", opt);
|
||||
let scene = opt.model.scene(&opt);
|
||||
let scene = opt.model.as_ref().unwrap().scene(&opt);
|
||||
fs::create_dir_all(&opt.output)?;
|
||||
if opt.pprof.is_some() && !cfg!(feature = "profile") {
|
||||
panic!("profiling disabled at compile time, but -pprof specified");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user