rtiow: implement EnvMap in parser.

This commit is contained in:
Bill Thiede 2023-02-15 15:46:23 -08:00
parent 6fbdb49ce1
commit 5f0e7a26dd
3 changed files with 53 additions and 29 deletions

View File

@ -8,7 +8,8 @@ use crate::{
texture::{EnvMap, Texture},
};
use serde::Deserialize;
use std::path::PathBuf;
use thiserror::Error;
use vec3::Vec3;
#[derive(Debug, Deserialize)]
@ -16,38 +17,40 @@ pub struct Config {
scene: SceneConfig,
camera: CameraConfig,
spheres: Vec<SphereConfig>,
envmap: Option<EnvMapConfig>,
}
impl From<Config> for Scene {
fn from(c: Config) -> Scene {
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("failed to load image")]
ImageError(#[from] image::ImageError),
}
impl TryFrom<Config> for Scene {
type Error = ConfigError;
fn try_from(c: Config) -> Result<Scene, Self::Error> {
// TODO(wathiede): make this something that is loaded from the config and referenced by
// name in the object's config.
let material = Lambertian::new([1., 0., 0.]);
let objects: Vec<Box<dyn Hit>> = c
let spheres: Vec<Box<dyn Hit>> = c
.spheres
.iter()
.map(|sc| -> Box<dyn Hit> {
Box::new(Sphere::new(sc.center, sc.radius, material.clone()))
})
.collect();
let world: Box<dyn Hit> = Box::new(HitableList::new(objects));
let env_map: Option<EnvMap> = None;
let lookfrom = Vec3::new(0., 80., 80.);
let lookat = Vec3::new(0., 0., 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.,
c.scene.width as f32 / c.scene.height as f32,
aperture,
dist_to_focus,
time_min,
time_max,
);
let world: Box<dyn Hit> = Box::new(HitableList::new(spheres));
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,
@ -60,11 +63,24 @@ impl From<Config> for Scene {
height: c.scene.height,
global_illumination: c.scene.global_illumination.unwrap_or(true),
};
dbg!(&scene);
scene
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>,
@ -92,3 +108,8 @@ pub struct CameraConfig {
time_min: f32,
time_max: f32,
}
#[derive(Debug, Deserialize)]
struct EnvMapConfig {
path: PathBuf,
}

View File

@ -1,12 +1,12 @@
[scene]
width = 768
height = 768
subsamples = 1000
#subsamples = 1000
[camera]
lookfrom = [0.0, 10.0, 0.0]
lookfrom = [0.0, 10.0, -100.0]
lookat = [0.0, 0.0, 0.0]
fov = 45.0
fov = 45
aspect = 1
aperture = 0.0
focus_dist = 10.0
@ -22,3 +22,6 @@ radius = 10
[[spheres]]
center = [-30.0, 0.0, 0.0]
radius = 10
[envmap]
path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"

View File

@ -65,7 +65,7 @@ fn main() -> Result<()> {
let s = std::fs::read_to_string(config)?;
let cfg: Config = toml::from_str(&s)?;
println!("{:#?}", cfg);
cfg.into()
cfg.try_into()?
}
_ => unreachable!(),
};