Compare commits
7 Commits
4b8bd84a84
...
d3153032b1
| Author | SHA1 | Date | |
|---|---|---|---|
| d3153032b1 | |||
| 35071b06ac | |||
| 5f0e7a26dd | |||
| 6fbdb49ce1 | |||
| 23bc5b0bf0 | |||
| 37137ac9ca | |||
| 9353ff675e |
57
rtiow/Cargo.lock
generated
57
rtiow/Cargo.lock
generated
@ -267,7 +267,7 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"toml",
|
"toml 0.4.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1892,6 +1892,15 @@ dependencies = [
|
|||||||
"version_check 0.1.5",
|
"version_check 0.1.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom8"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@ -2632,6 +2641,7 @@ dependencies = [
|
|||||||
"structopt 0.2.18",
|
"structopt 0.2.18",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
"thiserror",
|
||||||
"vec3",
|
"vec3",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2784,6 +2794,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@ -3409,6 +3428,40 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.19.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"nom8",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -3422,11 +3475,13 @@ dependencies = [
|
|||||||
name = "tracer"
|
name = "tracer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"log 0.4.17",
|
"log 0.4.17",
|
||||||
"renderer",
|
"renderer",
|
||||||
"stderrlog",
|
"stderrlog",
|
||||||
"structopt 0.2.18",
|
"structopt 0.2.18",
|
||||||
"strum",
|
"strum",
|
||||||
|
"toml 0.7.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -10,3 +10,5 @@ members = [
|
|||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 3
|
||||||
|
|||||||
@ -29,6 +29,7 @@ vec3 = {path = "../vec3"}
|
|||||||
stl = {path = "../../../stl"}
|
stl = {path = "../../../stl"}
|
||||||
strum = { version = "0.24.1", features = ["derive"] }
|
strum = { version = "0.24.1", features = ["derive"] }
|
||||||
strum_macros = "0.24.3"
|
strum_macros = "0.24.3"
|
||||||
|
thiserror = "1.0.38"
|
||||||
#stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"}
|
#stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@ -120,7 +120,7 @@ impl<M> BVHTriangles<M>
|
|||||||
where
|
where
|
||||||
M: Material,
|
M: Material,
|
||||||
{
|
{
|
||||||
pub fn new(stl: &STL, material: M) -> BVHTriangles<M> {
|
pub fn new(stl: &STL, material: M, scale_factor: f32) -> BVHTriangles<M> {
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
|
|
||||||
assert_eq!(std::mem::size_of::<BVHNode>(), 32);
|
assert_eq!(std::mem::size_of::<BVHNode>(), 32);
|
||||||
@ -129,9 +129,9 @@ where
|
|||||||
.triangles
|
.triangles
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
let v0 = t.verts[0];
|
let v0 = t.verts[0] * scale_factor;
|
||||||
let v1 = t.verts[1];
|
let v1 = t.verts[1] * scale_factor;
|
||||||
let v2 = t.verts[2];
|
let v2 = t.verts[2] * scale_factor;
|
||||||
let centroid = (v0 + v1 + v2) * div3;
|
let centroid = (v0 + v1 + v2) * div3;
|
||||||
Triangle {
|
Triangle {
|
||||||
centroid,
|
centroid,
|
||||||
|
|||||||
@ -18,6 +18,7 @@ fn random_in_unit_disk() -> Vec3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
origin: Vec3,
|
origin: Vec3,
|
||||||
lower_left_corner: Vec3,
|
lower_left_corner: Vec3,
|
||||||
|
|||||||
@ -3,8 +3,6 @@ use crate::{
|
|||||||
hitable::{Hit, HitRecord},
|
hitable::{Hit, HitRecord},
|
||||||
material::Lambertian,
|
material::Lambertian,
|
||||||
ray::Ray,
|
ray::Ray,
|
||||||
texture::{self, ConstantTexture},
|
|
||||||
vec3::Vec3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@ -16,6 +16,7 @@ pub mod material;
|
|||||||
pub mod moving_sphere;
|
pub mod moving_sphere;
|
||||||
pub mod noise;
|
pub mod noise;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
|
pub mod parser;
|
||||||
pub mod ray;
|
pub mod ray;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
|||||||
192
rtiow/renderer/src/parser.rs
Normal file
192
rtiow/renderer/src/parser.rs
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
use crate::{
|
||||||
|
bvh_triangles::BVHTriangles,
|
||||||
|
camera::Camera,
|
||||||
|
cuboid::Cuboid,
|
||||||
|
hitable::Hit,
|
||||||
|
hitable_list::HitableList,
|
||||||
|
material::{Lambertian, Material, Metal},
|
||||||
|
renderer::Scene,
|
||||||
|
sphere::Sphere,
|
||||||
|
texture::{EnvMap, Texture},
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashMap, fs::File, io::BufReader, path::PathBuf, sync::Arc};
|
||||||
|
use stl::STL;
|
||||||
|
use thiserror::Error;
|
||||||
|
use vec3::Vec3;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
scene: SceneConfig,
|
||||||
|
camera: CameraConfig,
|
||||||
|
materials: Vec<MaterialConfig>,
|
||||||
|
hitables: Vec<HitableConfig>,
|
||||||
|
envmap: Option<EnvMapConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ConfigError {
|
||||||
|
#[error("failed to load image")]
|
||||||
|
ImageError(#[from] image::ImageError),
|
||||||
|
#[error("failed to parser STL")]
|
||||||
|
STLError(#[from] stl::ParseError),
|
||||||
|
#[error("I/O error")]
|
||||||
|
IOError(#[from] std::io::Error),
|
||||||
|
#[error("duplication material named '{0}'")]
|
||||||
|
DuplicateMaterial(String),
|
||||||
|
#[error("unkown material named '{0}'")]
|
||||||
|
UnknownMaterial(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Config> for Scene {
|
||||||
|
type Error = ConfigError;
|
||||||
|
|
||||||
|
fn try_from(c: Config) -> Result<Scene, Self::Error> {
|
||||||
|
let mut materials = HashMap::new();
|
||||||
|
for mc in c.materials {
|
||||||
|
let v: Arc<dyn Material> = match mc.material {
|
||||||
|
Materials::Metal { albedo, fuzzy } => Arc::new(Metal::new(albedo, fuzzy)),
|
||||||
|
};
|
||||||
|
if materials.insert(mc.name.clone(), v).is_some() {
|
||||||
|
return Err(ConfigError::DuplicateMaterial(mc.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let hitables: Result<Vec<Box<dyn Hit>>, Self::Error> = c
|
||||||
|
.hitables
|
||||||
|
.into_iter()
|
||||||
|
.map(|hc| -> Result<Box<dyn Hit>, Self::Error> {
|
||||||
|
match hc.hitable {
|
||||||
|
Hitables::Sphere { center, radius } => Ok(Box::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
Arc::clone(
|
||||||
|
materials
|
||||||
|
.get(&hc.material_name)
|
||||||
|
.ok_or(ConfigError::UnknownMaterial(hc.material_name))?,
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
Hitables::Cuboid { min, max } => Ok(Box::new(Cuboid::new(
|
||||||
|
min.into(),
|
||||||
|
max.into(),
|
||||||
|
Arc::clone(
|
||||||
|
materials
|
||||||
|
.get(&hc.material_name)
|
||||||
|
.ok_or(ConfigError::UnknownMaterial(hc.material_name))?,
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
Hitables::STL { path, scale } => {
|
||||||
|
let r = BufReader::new(File::open(path)?);
|
||||||
|
let stl = STL::parse(r, false)?;
|
||||||
|
Ok(Box::new(BVHTriangles::new(
|
||||||
|
&stl,
|
||||||
|
Arc::clone(
|
||||||
|
materials
|
||||||
|
.get(&hc.material_name)
|
||||||
|
.ok_or(ConfigError::UnknownMaterial(hc.material_name))?,
|
||||||
|
),
|
||||||
|
scale.unwrap_or(1.),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let hitables = hitables?;
|
||||||
|
|
||||||
|
let world: Box<dyn Hit> = Box::new(HitableList::new(hitables));
|
||||||
|
let mut env_map: Option<EnvMap> = None;
|
||||||
|
|
||||||
|
if let Some(em) = c.envmap {
|
||||||
|
let im = image::open(em.path)?.into_rgb();
|
||||||
|
env_map = Some(EnvMap::new(im));
|
||||||
|
};
|
||||||
|
|
||||||
|
let camera = make_camera(&c.camera, c.scene.width, c.scene.height);
|
||||||
|
|
||||||
|
let scene = Scene {
|
||||||
|
world,
|
||||||
|
camera,
|
||||||
|
env_map,
|
||||||
|
subsamples: c.scene.subsamples.unwrap_or(8),
|
||||||
|
adaptive_subsampling: c.scene.adaptive_subsampling,
|
||||||
|
num_threads: c.scene.num_threads,
|
||||||
|
width: c.scene.width,
|
||||||
|
height: c.scene.height,
|
||||||
|
global_illumination: c.scene.global_illumination.unwrap_or(true),
|
||||||
|
};
|
||||||
|
Ok(scene)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_camera(cfg: &CameraConfig, width: usize, height: usize) -> Camera {
|
||||||
|
Camera::new(
|
||||||
|
cfg.lookfrom.into(),
|
||||||
|
cfg.lookat.into(),
|
||||||
|
Vec3::new(0., 1., 0.),
|
||||||
|
cfg.fov,
|
||||||
|
width as f32 / height as f32,
|
||||||
|
cfg.aperture,
|
||||||
|
cfg.focus_dist,
|
||||||
|
cfg.time_min,
|
||||||
|
cfg.time_max,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct SceneConfig {
|
||||||
|
subsamples: Option<usize>,
|
||||||
|
adaptive_subsampling: Option<f32>,
|
||||||
|
num_threads: Option<usize>,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
global_illumination: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
struct HitableConfig {
|
||||||
|
material_name: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
hitable: Hitables,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
enum Hitables {
|
||||||
|
#[serde(rename = "sphere")]
|
||||||
|
Sphere { center: [f32; 3], radius: f32 },
|
||||||
|
#[serde(rename = "cuboid")]
|
||||||
|
Cuboid { min: [f32; 3], max: [f32; 3] },
|
||||||
|
#[serde(rename = "stl")]
|
||||||
|
STL { path: PathBuf, scale: Option<f32> },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct MaterialConfig {
|
||||||
|
name: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
material: Materials,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
enum Materials {
|
||||||
|
#[serde(rename = "metal")]
|
||||||
|
Metal { albedo: [f32; 3], fuzzy: f32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CameraConfig {
|
||||||
|
lookfrom: [f32; 3],
|
||||||
|
lookat: [f32; 3],
|
||||||
|
fov: f32,
|
||||||
|
aperture: f32,
|
||||||
|
focus_dist: f32,
|
||||||
|
time_min: f32,
|
||||||
|
time_max: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct EnvMapConfig {
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
fmt,
|
fmt,
|
||||||
ops::{AddAssign, Range},
|
ops::{AddAssign, Range},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
@ -22,7 +23,7 @@ use crate::{
|
|||||||
camera::Camera,
|
camera::Camera,
|
||||||
hitable::Hit,
|
hitable::Hit,
|
||||||
human,
|
human,
|
||||||
material::Lambertian,
|
material::{Lambertian, Material},
|
||||||
output,
|
output,
|
||||||
ray::Ray,
|
ray::Ray,
|
||||||
scenes,
|
scenes,
|
||||||
@ -99,6 +100,9 @@ pub struct Opt {
|
|||||||
/// Select scene to render.
|
/// Select scene to render.
|
||||||
#[structopt(long = "model")]
|
#[structopt(long = "model")]
|
||||||
pub model: Option<Model>,
|
pub model: Option<Model>,
|
||||||
|
/// Toml config describing scene.
|
||||||
|
#[structopt(long = "config")]
|
||||||
|
pub config: Option<PathBuf>,
|
||||||
/// 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>,
|
||||||
@ -126,11 +130,13 @@ pub fn opt_hash(opt: &Opt) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(wathiede): implement the skips and then the renderer could use json as an input file type.
|
// TODO(wathiede): implement the skips and then the renderer could use json as an input file type.
|
||||||
#[derive(Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub world: Box<dyn Hit>,
|
pub world: Box<dyn Hit>,
|
||||||
|
//#[serde(skip)]
|
||||||
|
//pub materials: HashMap<String, Box<dyn Material>>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
pub subsamples: usize,
|
pub subsamples: usize,
|
||||||
|
|||||||
@ -2,7 +2,6 @@ use crate::{
|
|||||||
aabb::AABB,
|
aabb::AABB,
|
||||||
hitable::{Hit, HitRecord},
|
hitable::{Hit, HitRecord},
|
||||||
ray::Ray,
|
ray::Ray,
|
||||||
vec3::Vec3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@ -52,6 +52,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
height: opt.height,
|
height: opt.height,
|
||||||
global_illumination: true,
|
global_illumination: true,
|
||||||
env_map: Some(EnvMap::new(skybox)),
|
env_map: Some(EnvMap::new(skybox)),
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
f32::consts::PI,
|
f32::consts::PI,
|
||||||
io::{BufReader, Cursor},
|
io::{BufReader, Cursor},
|
||||||
iter::Inspect,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use stl::STL;
|
use stl::STL;
|
||||||
@ -13,7 +12,7 @@ use crate::{
|
|||||||
hitable::Hit,
|
hitable::Hit,
|
||||||
hitable_list::HitableList,
|
hitable_list::HitableList,
|
||||||
kdtree::KDTree,
|
kdtree::KDTree,
|
||||||
material::{Dielectric, Lambertian, Metal},
|
material::{Lambertian, Metal},
|
||||||
renderer::{Opt, Scene},
|
renderer::{Opt, Scene},
|
||||||
rotate::RotateY,
|
rotate::RotateY,
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
@ -53,7 +52,6 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
|
|
||||||
let stl_cube = STL::parse(
|
let stl_cube = STL::parse(
|
||||||
BufReader::new(Cursor::new(include_bytes!("../../stls/dragon.stl"))),
|
BufReader::new(Cursor::new(include_bytes!("../../stls/dragon.stl"))),
|
||||||
//BufReader::new(Cursor::new(include_bytes!("../../stls/cube.stl"))),
|
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.expect("failed to parse cube");
|
.expect("failed to parse cube");
|
||||||
@ -89,7 +87,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
// STL Mesh
|
// STL Mesh
|
||||||
Box::new(crate::debug_hit::DebugHit::new(RotateY::new(
|
Box::new(crate::debug_hit::DebugHit::new(RotateY::new(
|
||||||
Translate::new(
|
Translate::new(
|
||||||
Scale::new(BVHTriangles::new(&stl_cube, dragon_material), 250.),
|
BVHTriangles::new(&stl_cube, dragon_material, 250.),
|
||||||
[0., -10., 0.],
|
[0., -10., 0.],
|
||||||
),
|
),
|
||||||
180.,
|
180.,
|
||||||
|
|||||||
@ -112,5 +112,6 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
height: opt.height,
|
height: opt.height,
|
||||||
global_illumination: true,
|
global_illumination: true,
|
||||||
env_map: Some(EnvMap::new(skybox)),
|
env_map: Some(EnvMap::new(skybox)),
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,7 @@ pub fn new(opt: &Opt) -> Scene {
|
|||||||
)),
|
)),
|
||||||
// STL Mesh
|
// STL Mesh
|
||||||
Box::new(Translate::new(
|
Box::new(Translate::new(
|
||||||
BVHTriangles::new(&stl_cube, glass),
|
BVHTriangles::new(&stl_cube, glass, 1.),
|
||||||
[0., 10., 0.],
|
[0., 10., 0.],
|
||||||
)),
|
)),
|
||||||
//Box::new(BVHTriangles::new(&stl_cube, box_material.clone())),
|
//Box::new(BVHTriangles::new(&stl_cube, box_material.clone())),
|
||||||
|
|||||||
@ -7,8 +7,10 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.69"
|
||||||
log = "0.4.17"
|
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"
|
strum = "0.24.1"
|
||||||
|
toml = "0.7.2"
|
||||||
|
|||||||
49
rtiow/tracer/configs/test.toml
Normal file
49
rtiow/tracer/configs/test.toml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
[scene]
|
||||||
|
width = 768
|
||||||
|
height = 768
|
||||||
|
#subsamples = 1000
|
||||||
|
|
||||||
|
[camera]
|
||||||
|
lookfrom = [0.0, 30.0, -100.0]
|
||||||
|
lookat = [0.0, 0.0, 0.0]
|
||||||
|
fov = 45
|
||||||
|
aperture = 0.0
|
||||||
|
focus_dist = 10.0
|
||||||
|
time_min = 0.0
|
||||||
|
time_max = 1.0
|
||||||
|
|
||||||
|
[[materials]]
|
||||||
|
name = "green"
|
||||||
|
type = "metal"
|
||||||
|
albedo = [0, 1, 0]
|
||||||
|
fuzzy = 1.5
|
||||||
|
[[materials]]
|
||||||
|
name = "blue"
|
||||||
|
type = "metal"
|
||||||
|
albedo = [0, 0, 1]
|
||||||
|
fuzzy = 1.5
|
||||||
|
[[materials]]
|
||||||
|
name = "red"
|
||||||
|
type = "metal"
|
||||||
|
albedo = [1, 0, 0]
|
||||||
|
fuzzy = 1.5
|
||||||
|
|
||||||
|
|
||||||
|
[[hitables]]
|
||||||
|
type = "cuboid"
|
||||||
|
min = [-10.0, -10.0, -10.0]
|
||||||
|
max = [10.0, 10.0, 10.0]
|
||||||
|
material_name = "green"
|
||||||
|
[[hitables]]
|
||||||
|
type = "sphere"
|
||||||
|
center = [30.0, 0.0, 0.0]
|
||||||
|
radius = 10
|
||||||
|
material_name = "blue"
|
||||||
|
[[hitables]]
|
||||||
|
type = "stl"
|
||||||
|
path = "/net/nasx.h.xinu.tv/x/3dprint/stl/stanford_dragon.stl"
|
||||||
|
scale = 200
|
||||||
|
material_name = "red"
|
||||||
|
|
||||||
|
[envmap]
|
||||||
|
path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"
|
||||||
@ -1,12 +1,16 @@
|
|||||||
#![warn(unused_extern_crates)]
|
#![warn(unused_extern_crates)]
|
||||||
use std::{fs, time::Instant};
|
use std::{fs, time::Instant};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
#[cfg(feature = "profile")]
|
#[cfg(feature = "profile")]
|
||||||
use cpuprofiler::PROFILER;
|
use cpuprofiler::PROFILER;
|
||||||
use log::info;
|
use log::info;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use renderer::renderer::{render, Model, Opt};
|
use renderer::{
|
||||||
|
parser::Config,
|
||||||
|
renderer::{render, Model, Opt},
|
||||||
|
};
|
||||||
use strum::VariantNames;
|
use strum::VariantNames;
|
||||||
|
|
||||||
#[cfg(not(feature = "profile"))]
|
#[cfg(not(feature = "profile"))]
|
||||||
@ -35,7 +39,7 @@ impl MockProfiler {
|
|||||||
#[cfg(not(feature = "profile"))]
|
#[cfg(not(feature = "profile"))]
|
||||||
static PROFILER: MockProfiler = MockProfiler {};
|
static PROFILER: MockProfiler = MockProfiler {};
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<()> {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
stderrlog::new()
|
stderrlog::new()
|
||||||
.verbosity(3)
|
.verbosity(3)
|
||||||
@ -43,12 +47,28 @@ 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() {
|
if opt.model.is_none() && opt.config.is_none() {
|
||||||
eprintln!("--model should be one of {:?}", Model::VARIANTS);
|
eprintln!(
|
||||||
|
"--config <path> or --model should be one of {:?}",
|
||||||
|
Model::VARIANTS
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if opt.model.is_some() && opt.config.is_some() {
|
||||||
|
eprintln!("only specify one of --config or --model");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
info!("{:#?}", opt);
|
info!("{:#?}", opt);
|
||||||
let scene = opt.model.as_ref().unwrap().scene(&opt);
|
let scene = match (&opt.model, &opt.config) {
|
||||||
|
(Some(model), None) => model.scene(&opt),
|
||||||
|
(None, Some(config)) => {
|
||||||
|
let s = std::fs::read_to_string(config)?;
|
||||||
|
let cfg: Config = toml::from_str(&s)?;
|
||||||
|
println!("{:#?}", cfg);
|
||||||
|
cfg.try_into()?
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
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");
|
||||||
@ -68,5 +88,5 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
|
|
||||||
let time_diff = Instant::now() - start_time;
|
let time_diff = Instant::now() - start_time;
|
||||||
info!("Total runtime {} seconds", time_diff.as_secs_f32());
|
info!("Total runtime {} seconds", time_diff.as_secs_f32());
|
||||||
res
|
Ok(res?)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user