Compare commits

...

4 Commits

Author SHA1 Message Date
5ba5aa5f5d rtiow: cargo fix. 2023-01-30 19:59:40 -08:00
4e6e9bf78a rtiow: cargo update. 2023-01-30 19:57:57 -08:00
beeb5e479b rtiow: add dragon scene, tune stltest to compare with cuboid.
Refactor enum Model to use strum.
2023-01-30 19:55:28 -08:00
fc1bfa419e rtiow: BVHTriangles add tests comparing results with Cuboid impl. 2023-01-29 19:56:51 -08:00
11 changed files with 303 additions and 135 deletions

97
rtiow/Cargo.lock generated
View File

@ -425,9 +425,9 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.11.1" version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
[[package]] [[package]]
name = "byte-tools" name = "byte-tools"
@ -460,9 +460,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.78" version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -823,9 +823,9 @@ dependencies = [
[[package]] [[package]]
name = "cxx" name = "cxx"
version = "1.0.85" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8"
dependencies = [ dependencies = [
"cc", "cc",
"cxxbridge-flags", "cxxbridge-flags",
@ -835,9 +835,9 @@ dependencies = [
[[package]] [[package]]
name = "cxx-build" name = "cxx-build"
version = "1.0.85" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8"
dependencies = [ dependencies = [
"cc", "cc",
"codespan-reporting", "codespan-reporting",
@ -850,15 +850,15 @@ dependencies = [
[[package]] [[package]]
name = "cxxbridge-flags" name = "cxxbridge-flags"
version = "1.0.85" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971"
[[package]] [[package]]
name = "cxxbridge-macro" name = "cxxbridge-macro"
version = "1.0.85" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e"
dependencies = [ dependencies = [
"proc-macro2 1.0.50", "proc-macro2 1.0.50",
"quote 1.0.23", "quote 1.0.23",
@ -911,9 +911,9 @@ checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]] [[package]]
name = "either" name = "either"
version = "1.8.0" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]] [[package]]
name = "encoding" name = "encoding"
@ -1160,9 +1160,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.27.0" version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec"
[[package]] [[package]]
name = "h2" name = "h2"
@ -1229,6 +1229,12 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.2.6" version = "0.2.6"
@ -1603,9 +1609,9 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
[[package]] [[package]]
name = "matches" name = "matches"
version = "0.1.9" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]] [[package]]
name = "maybe-uninit" name = "maybe-uninit"
@ -1867,9 +1873,9 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]] [[package]]
name = "object" name = "object"
version = "0.30.0" version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -2347,9 +2353,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.10.1" version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
dependencies = [ dependencies = [
"crossbeam-channel 0.5.6", "crossbeam-channel 0.5.6",
"crossbeam-deque 0.8.2", "crossbeam-deque 0.8.2",
@ -2434,6 +2440,8 @@ dependencies = [
"serde_json", "serde_json",
"stl", "stl",
"structopt 0.2.18", "structopt 0.2.18",
"strum",
"strum_macros",
"vec3", "vec3",
] ]
@ -2462,6 +2470,12 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "rustversion"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.12" version = "1.0.12"
@ -2740,7 +2754,7 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
dependencies = [ dependencies = [
"heck", "heck 0.3.3",
"proc-macro2 0.4.30", "proc-macro2 0.4.30",
"quote 0.6.13", "quote 0.6.13",
"syn 0.15.44", "syn 0.15.44",
@ -2752,13 +2766,35 @@ version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [ dependencies = [
"heck", "heck 0.3.3",
"proc-macro-error", "proc-macro-error",
"proc-macro2 1.0.50", "proc-macro2 1.0.50",
"quote 1.0.23", "quote 1.0.23",
"syn 1.0.107", "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]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.4.1"
@ -2815,9 +2851,9 @@ dependencies = [
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.1.3" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [ dependencies = [
"winapi-util", "winapi-util",
] ]
@ -3163,6 +3199,7 @@ dependencies = [
"renderer", "renderer",
"stderrlog", "stderrlog",
"structopt 0.2.18", "structopt 0.2.18",
"strum",
] ]
[[package]] [[package]]
@ -3234,9 +3271,9 @@ dependencies = [
[[package]] [[package]]
name = "try-lock" name = "try-lock"
version = "0.2.3" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
@ -3292,9 +3329,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.8" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"

View File

@ -27,6 +27,8 @@ serde_json = "1.0.91"
structopt = "0.2.18" structopt = "0.2.18"
vec3 = {path = "../vec3"} vec3 = {path = "../vec3"}
stl = {path = "../../../stl"} 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"} #stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"}
[dev-dependencies] [dev-dependencies]

View File

@ -183,7 +183,7 @@ where
let v0v1 = v1 - v0; let v0v1 = v1 - v0;
let v0v2 = v2 - v0; let v0v2 = v2 - v0;
let normal = cross(v0v1, v0v2); let normal = cross(v0v1, v0v2).unit_vector();
return Some(HitRecord { return Some(HitRecord {
t, t,
uv, uv,
@ -289,3 +289,64 @@ fn ray_triangle_intersect_moller_trumbore(r: Ray, tri: &Triangle) -> Option<RayT
} }
None None
} }
#[cfg(test)]
mod tests {
use crate::{
bvh_triangles::BVHTriangles, cuboid::Cuboid, hitable::Hit, material::Dielectric, ray::Ray,
};
use std::{
io::{BufReader, Cursor},
sync::Arc,
};
use stl::STL;
#[test]
fn compare_cuboid() {
let c = Cuboid::new(
[0., 0., 0.].into(),
[20., 20., 20.].into(),
Arc::new(Dielectric::new(1.5)),
);
let stl_cube = STL::parse(
BufReader::new(Cursor::new(include_bytes!("../stls/cube.stl"))),
false,
)
.expect("failed to parse cube");
let s = 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))),
);
let rays = [
Ray::new([-1., 1., 1.], [1., 0., 0.], 0.),
Ray::new([21., 1., 1.], [-1., 0., 0.], 0.),
Ray::new([1., -1., 1.], [0., 1., 0.], 0.),
Ray::new([1., 21., 1.], [0., -1., 0.], 0.),
Ray::new([1., 1., -1.], [0., 0., 1.], 0.),
Ray::new([1., 1., 21.], [0., 0., -1.], 0.),
// TODO more
];
for (i, r) in rays.into_iter().enumerate() {
let c_hit = c.hit(r, 0., f32::MAX).expect("c_hit missed");
let s_hit = s.hit(r, 0., f32::MAX).expect("s_hit missed");
assert_eq!(
c_hit.t, s_hit.t,
"{i}: [t] c_hit: {c_hit:?}, s_hit: {s_hit:?}"
);
// uv isn't valid for BVHTriangles.
// assert_eq!( c_hit.uv, s_hit.uv, "{i}: [uv] c_hit: {c_hit:?}, s_hit: {s_hit:?}");
assert_eq!(
c_hit.p, s_hit.p,
"{i}: [p] c_hit: {c_hit:?}, s_hit: {s_hit:?}"
);
assert_eq!(
c_hit.normal, s_hit.normal,
"{i}: [normal] c_hit: {c_hit:?}, s_hit: {s_hit:?}"
);
}
}
}

View File

@ -30,8 +30,10 @@ use crate::{
texture::{ConstantTexture, EnvMap}, texture::{ConstantTexture, EnvMap},
vec3::Vec3, vec3::Vec3,
}; };
use strum::{EnumString, EnumVariantNames};
#[derive(Debug)] #[derive(Debug, EnumString, EnumVariantNames, strum::Display)]
#[strum(serialize_all = "snake_case")]
pub enum Model { pub enum Model {
BVH, BVH,
Bench, Bench,
@ -46,6 +48,7 @@ pub enum Model {
Test, Test,
Tron, Tron,
Tutorial, Tutorial,
Dragon,
} }
impl Model { impl Model {
@ -56,6 +59,7 @@ impl Model {
Model::Book => scenes::book::new(opt), Model::Book => scenes::book::new(opt),
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::Dragon => scenes::dragon::new(opt),
Model::Final => scenes::final_scene::new(opt), Model::Final => scenes::final_scene::new(opt),
Model::Mandelbrot => scenes::mandelbrot::new(opt), Model::Mandelbrot => scenes::mandelbrot::new(opt),
Model::PerlinDebug => scenes::perlin_debug::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)] #[derive(Debug, StructOpt)]
#[structopt(name = "tracer", about = "An experimental ray tracer.")] #[structopt(name = "tracer", about = "An experimental ray tracer.")]
pub struct Opt { pub struct Opt {
@ -134,10 +96,9 @@ pub struct Opt {
/// Sub-samples per pixel /// Sub-samples per pixel
#[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.
/// "cornell_smoke", "perlin_debug", "final" #[structopt(long = "model")]
#[structopt(long = "model", default_value = "book")] pub model: Option<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))]
pub pprof: Option<PathBuf>, pub pprof: Option<PathBuf>,
@ -158,7 +119,7 @@ pub fn opt_hash(opt: &Opt) -> String {
opt.height, opt.height,
opt.subsamples, opt.subsamples,
opt.pprof.is_some(), opt.pprof.is_some(),
opt.model.to_string(), opt.model.as_ref().unwrap().to_string(),
opt.use_accel, opt.use_accel,
opt.output.display().to_string().replace('/', "_") opt.output.display().to_string().replace('/', "_")
) )

View File

@ -0,0 +1,118 @@
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, Lambertian},
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()
}
}

View File

@ -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 dragon;
pub mod final_scene; pub mod final_scene;
pub mod mandelbrot; pub mod mandelbrot;
pub mod perlin_debug; pub mod perlin_debug;

View File

@ -1,23 +1,26 @@
use std::io::{BufReader, Cursor}; use std::{
io::{BufReader, Cursor},
sync::Arc,
};
use stl::STL; use stl::STL;
use crate::{ use crate::{
bvh_triangles::BVHTriangles, bvh_triangles::BVHTriangles,
camera::Camera, camera::Camera,
cuboid::Cuboid,
hitable::Hit, hitable::Hit,
hitable_list::HitableList, hitable_list::HitableList,
kdtree::KDTree, kdtree::KDTree,
material::{DiffuseLight, Lambertian, Metal}, material::{Dielectric, Lambertian},
rect::{XYRect, XZRect},
renderer::{Opt, Scene}, renderer::{Opt, Scene},
scale::Scale,
sphere::Sphere, sphere::Sphere,
texture::ConstantTexture, texture::{ConstantTexture, EnvMap},
vec3::Vec3, vec3::Vec3,
}; };
pub fn new(opt: &Opt) -> Scene { 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 lookat = Vec3::new(0., 10., 0.);
let dist_to_focus = 10.0; let dist_to_focus = 10.0;
let aperture = 0.0; let aperture = 0.0;
@ -41,75 +44,49 @@ pub fn new(opt: &Opt) -> Scene {
}; };
let stl_cube = STL::parse( let stl_cube = STL::parse(
BufReader::new(Cursor::new(include_bytes!( BufReader::new(Cursor::new(include_bytes!("../../stls/cube.stl"))),
"../../stls/stanford_dragon-lowres.stl"
))),
false, false,
) )
.expect("failed to parse cube"); .expect("failed to parse cube");
let light_size = 50.; let _light_size = 50.;
let light_height = 200.; let _light_height = 200.;
let objects: Vec<Box<dyn Hit>> = vec![ let objects: Vec<Box<dyn Hit>> = vec![
// Light from above - white // 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 // Earth sized sphere
Box::new(Sphere::new( Box::new(Sphere::new(
Vec3::new(0., -1200., 0.), Vec3::new(0., -10000., 0.),
1000., 10000.,
Lambertian::new(ground_color), Lambertian::new(ground_color),
)), )),
/*
// Blue sphere // Blue sphere
Box::new(Sphere::new( Box::new(Sphere::new(
Vec3::new(-40., 20., 0.), Vec3::new(0., 20., 40.),
20., 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( Box::new(Sphere::new(
Vec3::new(40., 20., -40.), Vec3::new(40., 20., 40.),
20., 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( Box::new(Sphere::new(
Vec3::new(-40., 20., 40.), Vec3::new(-40., 20., 40.),
20., 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 // STL Mesh
Box::new(Scale::new( Box::new(BVHTriangles::new(
BVHTriangles::new( &stl_cube,
&stl_cube, Dielectric::new(1.5),
Lambertian::new(ConstantTexture::new(Vec3::new(0.6, 0.6, 0.6))), //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 { let world: Box<dyn Hit> = if opt.use_accel {
@ -117,6 +94,8 @@ pub fn new(opt: &Opt) -> Scene {
} else { } else {
Box::new(HitableList::new(objects)) 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 { Scene {
camera, camera,
world, world,
@ -124,6 +103,8 @@ pub fn new(opt: &Opt) -> Scene {
num_threads: opt.num_threads, num_threads: opt.num_threads,
width: opt.width, width: opt.width,
height: opt.height, height: opt.height,
global_illumination: true,
env_map: Some(EnvMap::new(skybox)),
..Default::default() ..Default::default()
} }
} }

View File

@ -0,0 +1 @@
/home/wathiede/3dprint/stl/stanford_dragon-lowres.stl

View File

@ -11,3 +11,4 @@ log = "0.4.17"
renderer = { path = "../renderer" } renderer = { path = "../renderer" }
stderrlog = "0.4.3" stderrlog = "0.4.3"
structopt = "0.2.18" structopt = "0.2.18"
strum = "0.24.1"

View File

@ -6,7 +6,8 @@ use cpuprofiler::PROFILER;
use log::info; use log::info;
use structopt::StructOpt; use structopt::StructOpt;
use renderer::renderer::{render, Opt}; use renderer::renderer::{render, Model, Opt};
use strum::VariantNames;
#[cfg(not(feature = "profile"))] #[cfg(not(feature = "profile"))]
struct MockTimer; struct MockTimer;
@ -41,8 +42,12 @@ fn main() -> Result<(), std::io::Error> {
.init() .init()
.unwrap(); .unwrap();
let opt = Opt::from_args(); let opt = Opt::from_args();
if opt.model.is_none() {
eprintln!("--model should be one of {:?}", Model::VARIANTS);
return Ok(());
}
info!("{:?}", opt); info!("{:?}", opt);
let scene = opt.model.scene(&opt); let scene = opt.model.as_ref().unwrap().scene(&opt);
fs::create_dir_all(&opt.output)?; fs::create_dir_all(&opt.output)?;
if opt.pprof.is_some() && !cfg!(feature = "profile") { if opt.pprof.is_some() && !cfg!(feature = "profile") {
panic!("profiling disabled at compile time, but -pprof specified"); panic!("profiling disabled at compile time, but -pprof specified");