library: document render module
This commit is contained in:
parent
a9fd726a0d
commit
64125dbc43
|
@ -1,8 +1,11 @@
|
||||||
|
//! Utility module to compute overall illumination
|
||||||
|
|
||||||
use crate::light::*;
|
use crate::light::*;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
/// A struct centralizing the light computation logic.
|
||||||
pub struct LightAggregate {
|
pub struct LightAggregate {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
ambients: Vec<AmbientLight>,
|
ambients: Vec<AmbientLight>,
|
||||||
|
@ -15,10 +18,39 @@ pub struct LightAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LightAggregate {
|
impl LightAggregate {
|
||||||
|
/// Creates a new empty `LightAggregate`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use pathtracer::render::LightAggregate;
|
||||||
|
/// #
|
||||||
|
/// let la = LightAggregate::empty();
|
||||||
|
/// assert_eq!(la.ambient_lights_iter().count(), 0);
|
||||||
|
/// assert_eq!(la.spatial_lights_iter().count(), 0);
|
||||||
|
/// ```
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
LightAggregate::new(vec![], vec![], vec![], vec![])
|
LightAggregate::new(vec![], vec![], vec![], vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `LightAggregate` from `Vec`s of [`Light`]s.
|
||||||
|
///
|
||||||
|
/// [`Light`]: ../../light/trait.Light.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use pathtracer::render::LightAggregate;
|
||||||
|
/// #
|
||||||
|
/// let la = LightAggregate::new(
|
||||||
|
/// Vec::new(),
|
||||||
|
/// Vec::new(),
|
||||||
|
/// Vec::new(),
|
||||||
|
/// Vec::new(),
|
||||||
|
/// );
|
||||||
|
/// assert_eq!(la.ambient_lights_iter().count(), 0);
|
||||||
|
/// assert_eq!(la.spatial_lights_iter().count(), 0);
|
||||||
|
/// ```
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ambients: Vec<AmbientLight>,
|
ambients: Vec<AmbientLight>,
|
||||||
directionals: Vec<DirectionalLight>,
|
directionals: Vec<DirectionalLight>,
|
||||||
|
@ -33,10 +65,21 @@ impl LightAggregate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the aggregate's [`AmbientLight`]s.
|
||||||
|
///
|
||||||
|
/// [`AmbientLight`]: ../../light/ambient_light/struct.AmbientLight.html
|
||||||
pub fn ambient_lights_iter(&self) -> impl Iterator<Item = &'_ dyn Light> {
|
pub fn ambient_lights_iter(&self) -> impl Iterator<Item = &'_ dyn Light> {
|
||||||
self.ambients.iter().map(|l| l as &dyn Light)
|
self.ambients.iter().map(|l| l as &dyn Light)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the aggregate's [`SpatialLight`]s.
|
||||||
|
///
|
||||||
|
/// This simply merges iterators over [`DirectionalLight`], [`PointLight`] and [`SpotLight`].
|
||||||
|
///
|
||||||
|
/// [`SpatialLight`]: ../../light/trait.SpatialLight.html
|
||||||
|
/// [`DirectionalLight`]: ../../light/directional_light/struct.DirectionalLight.html
|
||||||
|
/// [`PointLight`]: ../../light/point_light/struct.PointLight.html
|
||||||
|
/// [`Spotight`]: ../../light/spot_light/struct.Spotight.html
|
||||||
pub fn spatial_lights_iter(&self) -> impl Iterator<Item = &'_ dyn SpatialLight> {
|
pub fn spatial_lights_iter(&self) -> impl Iterator<Item = &'_ dyn SpatialLight> {
|
||||||
self.directionals
|
self.directionals
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Rendering logic
|
||||||
|
|
||||||
pub mod light_aggregate;
|
pub mod light_aggregate;
|
||||||
pub use light_aggregate::*;
|
pub use light_aggregate::*;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Logic for the scene objects
|
||||||
|
|
||||||
use crate::material::MaterialEnum;
|
use crate::material::MaterialEnum;
|
||||||
use crate::shape::{Shape, ShapeEnum};
|
use crate::shape::{Shape, ShapeEnum};
|
||||||
use crate::texture::TextureEnum;
|
use crate::texture::TextureEnum;
|
||||||
|
@ -8,14 +10,42 @@ use serde::Deserialize;
|
||||||
/// An object being rendered in the scene.
|
/// An object being rendered in the scene.
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
pub struct Object {
|
pub struct Object {
|
||||||
|
/// The `Object`'s physical shape
|
||||||
pub shape: ShapeEnum,
|
pub shape: ShapeEnum,
|
||||||
|
/// The `Object`'s material
|
||||||
pub material: MaterialEnum,
|
pub material: MaterialEnum,
|
||||||
|
/// The `Object`'s texture
|
||||||
pub texture: TextureEnum,
|
pub texture: TextureEnum,
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
|
/// Index inside the `BVH`
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object {
|
impl Object {
|
||||||
|
/// Creates a new `Object`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use pathtracer::core::{LightProperties, LinearColor};
|
||||||
|
/// # use pathtracer::material::UniformMaterial;
|
||||||
|
/// # use pathtracer::render::Object;
|
||||||
|
/// # use pathtracer::shape::Sphere;
|
||||||
|
/// # use pathtracer::texture::UniformTexture;
|
||||||
|
/// # use pathtracer::Point;
|
||||||
|
/// #
|
||||||
|
/// let obj = Object::new(
|
||||||
|
/// Sphere::new(Point::origin(), 1.0).into(),
|
||||||
|
/// UniformMaterial::new(
|
||||||
|
/// LightProperties::new(
|
||||||
|
/// LinearColor::new(1.0, 0.0, 0.0), // diffuse component
|
||||||
|
/// LinearColor::new(0.0, 0.0, 0.0), // specular component
|
||||||
|
/// None,
|
||||||
|
/// ),
|
||||||
|
/// ).into(),
|
||||||
|
/// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
pub fn new(shape: ShapeEnum, material: MaterialEnum, texture: TextureEnum) -> Self {
|
pub fn new(shape: ShapeEnum, material: MaterialEnum, texture: TextureEnum) -> Self {
|
||||||
Object {
|
Object {
|
||||||
shape,
|
shape,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Scene rendering logic
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use super::{light_aggregate::LightAggregate, object::Object};
|
use super::{light_aggregate::LightAggregate, object::Object};
|
||||||
|
@ -26,6 +28,39 @@ pub struct Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
|
/// Creates a new `Scene`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use pathtracer::core::{Camera, LightProperties, LinearColor};
|
||||||
|
/// # use pathtracer::material::UniformMaterial;
|
||||||
|
/// # use pathtracer::render::{LightAggregate, Object, Scene};
|
||||||
|
/// # use pathtracer::shape::Sphere;
|
||||||
|
/// # use pathtracer::texture::UniformTexture;
|
||||||
|
/// # use pathtracer::Point;
|
||||||
|
/// #
|
||||||
|
/// let scene = Scene::new(
|
||||||
|
/// Camera::default(),
|
||||||
|
/// LightAggregate::empty(),
|
||||||
|
/// vec![
|
||||||
|
/// Object::new(
|
||||||
|
/// Sphere::new(Point::origin(), 1.0).into(),
|
||||||
|
/// UniformMaterial::new(
|
||||||
|
/// LightProperties::new(
|
||||||
|
/// LinearColor::new(1.0, 0.0, 0.0), // diffuse component
|
||||||
|
/// LinearColor::new(0.0, 0.0, 0.0), // specular component
|
||||||
|
/// None,
|
||||||
|
/// ),
|
||||||
|
/// ).into(),
|
||||||
|
/// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(),
|
||||||
|
/// ),
|
||||||
|
/// ],
|
||||||
|
/// 5, // aliasing limit
|
||||||
|
/// 3, // reflection recursion limit
|
||||||
|
/// 0.0, // diffraction index
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
pub fn new(
|
pub fn new(
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
lights: LightAggregate,
|
lights: LightAggregate,
|
||||||
|
@ -34,6 +69,7 @@ impl Scene {
|
||||||
reflection_limit: u32,
|
reflection_limit: u32,
|
||||||
diffraction_index: f32,
|
diffraction_index: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// NOTE(Antoine): fun fact: BVH::build stack overflows when given an empty slice :)
|
||||||
let bvh = BVH::build(&mut objects);
|
let bvh = BVH::build(&mut objects);
|
||||||
Scene {
|
Scene {
|
||||||
camera,
|
camera,
|
||||||
|
@ -338,4 +374,20 @@ mod test {
|
||||||
let _: Scene = serde_yaml::from_str(yaml).unwrap();
|
let _: Scene = serde_yaml::from_str(yaml).unwrap();
|
||||||
// FIXME: actually test the equality ?
|
// FIXME: actually test the equality ?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore] // stack overflow because of BVH :(
|
||||||
|
fn bvh_fails() {
|
||||||
|
use crate::core::Camera;
|
||||||
|
use crate::render::{LightAggregate, Scene};
|
||||||
|
|
||||||
|
let _scene = Scene::new(
|
||||||
|
Camera::default(),
|
||||||
|
LightAggregate::empty(),
|
||||||
|
Vec::new(), // Objects list
|
||||||
|
5, // aliasing limit
|
||||||
|
3, // reflection recursion limit
|
||||||
|
0.0, // diffraction index
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue