diff --git a/src/render/mod.rs b/src/render/mod.rs index 769c70c..46bdffa 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -8,3 +8,5 @@ pub use object::*; pub mod scene; pub use scene::*; + +pub(crate) mod utils; diff --git a/src/render/scene.rs b/src/render/scene.rs index a4b906c..f50a6eb 100644 --- a/src/render/scene.rs +++ b/src/render/scene.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; -use super::{light_aggregate::LightAggregate, object::Object}; +use super::{light_aggregate::LightAggregate, object::Object, utils::*}; use crate::{ core::{Camera, LightProperties, LinearColor, ReflTransEnum}, material::Material, @@ -296,72 +296,6 @@ impl Scene { } } -fn reflected(incident: Vector, normal: Vector) -> Vector { - let proj = incident.dot(&normal); - let delt = normal * (proj * 2.); - (incident - delt).normalize() -} - -/// Returns None if the ray was totally reflected, Some(refracted_ray, reflected_amount) if not -/// Adds an element to the top of indices that should be removed -fn refracted( - incident: Vector, - normal: Vector, - indices: &mut RefractionInfo, - new_index: f32, -) -> Option<(Vector, f32)> { - let cos1 = incident.dot(&normal); - let normal = if cos1 < 0. { - // Entering object, change the medium - indices.enter_medium(new_index); // The old index is now in old_index - normal - } else { - // Exiting object, exit the medium - indices.exit_medium(); // We swapped the indices - -normal - }; - let (n_1, n_2) = (indices.old_index, indices.new_index); - let eta = n_1 / n_2; - let k = 1. - eta * eta * (1. - cos1 * cos1); - if k < 0. { - return None; - } - let cos1 = cos1.abs(); - let cos2 = k.sqrt(); - let refracted = eta * incident + (eta * cos1 - cos2) * normal; - let f_r = (n_2 * cos1 - n_1 * cos2) / (n_2 * cos1 + n_1 * cos2); - let f_t = (n_1 * cos2 - n_2 * cos1) / (n_1 * cos2 + n_2 * cos1); - let refl_t = (f_r * f_r + f_t * f_t) / 2.; - //Some((refracted, 0.)) - Some((refracted.normalize(), refl_t)) -} - -#[derive(Debug, PartialEq, Clone)] -struct RefractionInfo { - pub old_index: f32, - pub new_index: f32, -} - -impl RefractionInfo { - pub fn with_index(index: f32) -> Self { - RefractionInfo { - old_index: index, - new_index: index, - } - } - - pub fn enter_medium(&mut self, index: f32) { - *self = RefractionInfo { - old_index: self.new_index, - new_index: index, - } - } - - pub fn exit_medium(&mut self) { - std::mem::swap(&mut self.old_index, &mut self.new_index) - } -} - #[derive(Debug, PartialEq, Deserialize)] struct SerializedScene { camera: Camera, diff --git a/src/render/utils.rs b/src/render/utils.rs new file mode 100644 index 0000000..185765a --- /dev/null +++ b/src/render/utils.rs @@ -0,0 +1,67 @@ +use crate::Vector; + +pub fn reflected(incident: Vector, normal: Vector) -> Vector { + let proj = incident.dot(&normal); + let delt = normal * (proj * 2.); + (incident - delt).normalize() +} + +/// Returns None if the ray was totally reflected, Some(refracted_ray, reflected_amount) if not +/// Adds an element to the top of indices that should be removed +pub fn refracted( + incident: Vector, + normal: Vector, + indices: &mut RefractionInfo, + new_index: f32, +) -> Option<(Vector, f32)> { + let cos1 = incident.dot(&normal); + let normal = if cos1 < 0. { + // Entering object, change the medium + indices.enter_medium(new_index); // The old index is now in old_index + normal + } else { + // Exiting object, exit the medium + indices.exit_medium(); // We swapped the indices + -normal + }; + let (n_1, n_2) = (indices.old_index, indices.new_index); + let eta = n_1 / n_2; + let k = 1. - eta * eta * (1. - cos1 * cos1); + if k < 0. { + return None; + } + let cos1 = cos1.abs(); + let cos2 = k.sqrt(); + let refracted = eta * incident + (eta * cos1 - cos2) * normal; + let f_r = (n_2 * cos1 - n_1 * cos2) / (n_2 * cos1 + n_1 * cos2); + let f_t = (n_1 * cos2 - n_2 * cos1) / (n_1 * cos2 + n_2 * cos1); + let refl_t = (f_r * f_r + f_t * f_t) / 2.; + //Some((refracted, 0.)) + Some((refracted.normalize(), refl_t)) +} + +#[derive(Debug, PartialEq, Clone)] +pub struct RefractionInfo { + pub old_index: f32, + pub new_index: f32, +} + +impl RefractionInfo { + pub fn with_index(index: f32) -> Self { + RefractionInfo { + old_index: index, + new_index: index, + } + } + + pub fn enter_medium(&mut self, index: f32) { + *self = RefractionInfo { + old_index: self.new_index, + new_index: index, + } + } + + pub fn exit_medium(&mut self) { + std::mem::swap(&mut self.old_index, &mut self.new_index) + } +}