rtiow: add basic Metal material support to parser.
This commit is contained in:
parent
35071b06ac
commit
d3153032b1
@ -4,13 +4,13 @@ use crate::{
|
|||||||
cuboid::Cuboid,
|
cuboid::Cuboid,
|
||||||
hitable::Hit,
|
hitable::Hit,
|
||||||
hitable_list::HitableList,
|
hitable_list::HitableList,
|
||||||
material::Lambertian,
|
material::{Lambertian, Material, Metal},
|
||||||
renderer::Scene,
|
renderer::Scene,
|
||||||
sphere::Sphere,
|
sphere::Sphere,
|
||||||
texture::{EnvMap, Texture},
|
texture::{EnvMap, Texture},
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc};
|
use std::{collections::HashMap, fs::File, io::BufReader, path::PathBuf, sync::Arc};
|
||||||
use stl::STL;
|
use stl::STL;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
@ -19,6 +19,7 @@ use vec3::Vec3;
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
scene: SceneConfig,
|
scene: SceneConfig,
|
||||||
camera: CameraConfig,
|
camera: CameraConfig,
|
||||||
|
materials: Vec<MaterialConfig>,
|
||||||
hitables: Vec<HitableConfig>,
|
hitables: Vec<HitableConfig>,
|
||||||
envmap: Option<EnvMapConfig>,
|
envmap: Option<EnvMapConfig>,
|
||||||
}
|
}
|
||||||
@ -31,35 +32,59 @@ pub enum ConfigError {
|
|||||||
STLError(#[from] stl::ParseError),
|
STLError(#[from] stl::ParseError),
|
||||||
#[error("I/O error")]
|
#[error("I/O error")]
|
||||||
IOError(#[from] std::io::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 {
|
impl TryFrom<Config> for Scene {
|
||||||
type Error = ConfigError;
|
type Error = ConfigError;
|
||||||
|
|
||||||
fn try_from(c: Config) -> Result<Scene, Self::Error> {
|
fn try_from(c: Config) -> Result<Scene, Self::Error> {
|
||||||
// TODO(wathiede): make this something that is loaded from the config and referenced by
|
let mut materials = HashMap::new();
|
||||||
// name in the object's config.
|
for mc in c.materials {
|
||||||
let material = Lambertian::new([1., 0., 0.]);
|
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
|
let hitables: Result<Vec<Box<dyn Hit>>, Self::Error> = c
|
||||||
.hitables
|
.hitables
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|hc| -> Result<Box<dyn Hit>, Self::Error> {
|
.map(|hc| -> Result<Box<dyn Hit>, Self::Error> {
|
||||||
match hc {
|
match hc.hitable {
|
||||||
HitableConfig::Sphere { center, radius } => {
|
Hitables::Sphere { center, radius } => Ok(Box::new(Sphere::new(
|
||||||
Ok(Box::new(Sphere::new(center, radius, material.clone())))
|
center,
|
||||||
}
|
radius,
|
||||||
HitableConfig::Cuboid { min, max } => Ok(Box::new(Cuboid::new(
|
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(),
|
min.into(),
|
||||||
max.into(),
|
max.into(),
|
||||||
Arc::new(material.clone()),
|
Arc::clone(
|
||||||
|
materials
|
||||||
|
.get(&hc.material_name)
|
||||||
|
.ok_or(ConfigError::UnknownMaterial(hc.material_name))?,
|
||||||
|
),
|
||||||
))),
|
))),
|
||||||
HitableConfig::STL { path, scale } => {
|
Hitables::STL { path, scale } => {
|
||||||
let r = BufReader::new(File::open(path)?);
|
let r = BufReader::new(File::open(path)?);
|
||||||
let stl = STL::parse(r, false)?;
|
let stl = STL::parse(r, false)?;
|
||||||
Ok(Box::new(BVHTriangles::new(
|
Ok(Box::new(BVHTriangles::new(
|
||||||
&stl,
|
&stl,
|
||||||
material.clone(),
|
Arc::clone(
|
||||||
|
materials
|
||||||
|
.get(&hc.material_name)
|
||||||
|
.ok_or(ConfigError::UnknownMaterial(hc.material_name))?,
|
||||||
|
),
|
||||||
scale.unwrap_or(1.),
|
scale.unwrap_or(1.),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -119,7 +144,15 @@ struct SceneConfig {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
enum HitableConfig {
|
struct HitableConfig {
|
||||||
|
material_name: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
hitable: Hitables,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
enum Hitables {
|
||||||
#[serde(rename = "sphere")]
|
#[serde(rename = "sphere")]
|
||||||
Sphere { center: [f32; 3], radius: f32 },
|
Sphere { center: [f32; 3], radius: f32 },
|
||||||
#[serde(rename = "cuboid")]
|
#[serde(rename = "cuboid")]
|
||||||
@ -128,12 +161,25 @@ enum HitableConfig {
|
|||||||
STL { path: PathBuf, scale: Option<f32> },
|
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)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct CameraConfig {
|
pub struct CameraConfig {
|
||||||
lookfrom: [f32; 3],
|
lookfrom: [f32; 3],
|
||||||
lookat: [f32; 3],
|
lookat: [f32; 3],
|
||||||
fov: f32,
|
fov: f32,
|
||||||
aspect: f32,
|
|
||||||
aperture: f32,
|
aperture: f32,
|
||||||
focus_dist: f32,
|
focus_dist: f32,
|
||||||
time_min: f32,
|
time_min: f32,
|
||||||
|
|||||||
@ -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,
|
||||||
@ -134,6 +135,8 @@ pub fn opt_hash(opt: &Opt) -> String {
|
|||||||
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,
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,24 +7,43 @@ height = 768
|
|||||||
lookfrom = [0.0, 30.0, -100.0]
|
lookfrom = [0.0, 30.0, -100.0]
|
||||||
lookat = [0.0, 0.0, 0.0]
|
lookat = [0.0, 0.0, 0.0]
|
||||||
fov = 45
|
fov = 45
|
||||||
aspect = 1
|
|
||||||
aperture = 0.0
|
aperture = 0.0
|
||||||
focus_dist = 10.0
|
focus_dist = 10.0
|
||||||
time_min = 0.0
|
time_min = 0.0
|
||||||
time_max = 1.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]]
|
[[hitables]]
|
||||||
type = "cuboid"
|
type = "cuboid"
|
||||||
min = [-10.0, -10.0, -10.0]
|
min = [-10.0, -10.0, -10.0]
|
||||||
max = [10.0, 10.0, 10.0]
|
max = [10.0, 10.0, 10.0]
|
||||||
|
material_name = "green"
|
||||||
[[hitables]]
|
[[hitables]]
|
||||||
type = "sphere"
|
type = "sphere"
|
||||||
center = [30.0, 0.0, 0.0]
|
center = [30.0, 0.0, 0.0]
|
||||||
radius = 10
|
radius = 10
|
||||||
|
material_name = "blue"
|
||||||
[[hitables]]
|
[[hitables]]
|
||||||
type = "stl"
|
type = "stl"
|
||||||
path = "/net/nasx.h.xinu.tv/x/3dprint/stl/stanford_dragon.stl"
|
path = "/net/nasx.h.xinu.tv/x/3dprint/stl/stanford_dragon.stl"
|
||||||
scale = 200
|
scale = 200
|
||||||
|
material_name = "red"
|
||||||
|
|
||||||
[envmap]
|
[envmap]
|
||||||
path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"
|
path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user