wtf sphere

This commit is contained in:
Michael Zhang 2023-04-03 02:24:38 -05:00
parent 73bbd64cc0
commit 7bf1c91a99
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
3 changed files with 39 additions and 17 deletions

View file

@ -8,3 +8,4 @@
perf.data* perf.data*
flamegraph.svg flamegraph.svg
showcase.png showcase.png
/out.log

View file

@ -18,9 +18,14 @@ use super::{
// TODO: Is this a good constant? // TODO: Is this a good constant?
const JITTER_CONST: f64 = 0.05; const JITTER_CONST: f64 = 0.05;
const ZERO_COLOR: Color = Color::new(0.0, 0.0, 0.0); const ZERO_COLOR: Color = Color::new(0.0, 0.0, 0.0);
// Soft shadows: jitter some rays here to somewhere close to the
// actual location as well, and measure the proportion
// of them that intersect any objects
const SOFT_SHADOW_JITTER_RADIUS: f64 = 1.0;
const JITTER_RAYS: usize = 75;
impl Scene { impl Scene {
/// Determine the color that should be used to fill this pixel. /// Determine the color that should be used to fill this pixel.
/// ///
@ -218,6 +223,12 @@ impl Scene {
.enumerate() .enumerate()
.filter(|(i, _)| *i != obj_idx); .filter(|(i, _)| *i != obj_idx);
#[derive(Clone, Copy)]
struct ShadowResult {
transparent_coefficient: f64,
opacity: f64,
}
// Get the list of intersections with all the other objects in the scene // Get the list of intersections with all the other objects in the scene
// This list will be a set of opacities // This list will be a set of opacities
let intersections = other_objects let intersections = other_objects
@ -243,7 +254,13 @@ impl Scene {
} else { } else {
let soft_shadow_coefficient = let soft_shadow_coefficient =
self.compute_soft_shadow_coefficient(location, point, object); self.compute_soft_shadow_coefficient(location, point, object);
Some(soft_shadow_coefficient)
let material = &self.materials[object.material_idx];
Some(ShadowResult {
transparent_coefficient: 1.0 - material.alpha,
opacity: soft_shadow_coefficient,
})
} }
} }
@ -253,7 +270,10 @@ impl Scene {
if intersection_time <= 0.0 { if intersection_time <= 0.0 {
None None
} else { } else {
Some(0.0) // complete obstruction Some(ShadowResult {
transparent_coefficient: 1.0,
opacity: 0.0,
}) // complete obstruction
} }
} }
} }
@ -263,9 +283,15 @@ impl Scene {
match intersections.is_empty() { match intersections.is_empty() {
true => 1.0, true => 1.0,
false => { false => {
let average = intersections.iter().cloned().sum::<f64>() let average = intersections.iter().map(|s| s.opacity).sum::<f64>()
/ intersections.len() as f64; / intersections.len() as f64;
average
let transparency = intersections
.iter()
.map(|s| s.transparent_coefficient)
.product::<f64>();
average * transparency
} }
} }
} }
@ -276,22 +302,17 @@ impl Scene {
original_intersection_point: Point, original_intersection_point: Point,
object: &Object, object: &Object,
) -> f64 { ) -> f64 {
// Soft shadows: jitter some rays here to somewhere close to the
// actual location as well, and measure the proportion
// of them that intersect any objects
const JITTER_RADIUS: f64 = 1.0;
const JITTER_RAYS: usize = 75;
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let locations = iter::repeat_with(|| { let locations = iter::repeat_with(|| {
let x = rng.gen_range(0.0..JITTER_RADIUS); let x = rng.gen_range(0.0..SOFT_SHADOW_JITTER_RADIUS);
let y = rng.gen_range(0.0..JITTER_RADIUS); let y = rng.gen_range(0.0..SOFT_SHADOW_JITTER_RADIUS);
let z = rng.gen_range(0.0..JITTER_RADIUS); let z = rng.gen_range(0.0..SOFT_SHADOW_JITTER_RADIUS);
let delta = Vector::new(x, y, z); let delta = Vector::new(x, y, z);
light_location + delta light_location + delta
}) })
.take(JITTER_RAYS) .take(JITTER_RAYS)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let num_obstructed_rays = locations let num_obstructed_rays = locations
.into_par_iter() .into_par_iter()
.filter(|location| { .filter(|location| {
@ -431,14 +452,14 @@ impl Scene {
let t_lambda = self.trace_single_ray(ray, depth + 1)?; let t_lambda = self.trace_single_ray(ray, depth + 1)?;
let value = (1.0 - fresnel_coefficient) * (1.0 - material.alpha) * t_lambda; let value = (1.0 - fresnel_coefficient) * (1.0 - material.alpha) * t_lambda;
debug!( /* debug!(
depth, depth,
fresnel_coefficient, fresnel_coefficient,
alpha = material.alpha, alpha = material.alpha,
?t_lambda, ?t_lambda,
?value, ?value,
"computing final value" "computing final value"
); ); */
Ok(value) Ok(value)
} }

View file

@ -81,7 +81,7 @@ impl Sphere {
let dy = ray.origin.y - self.center.y; let dy = ray.origin.y - self.center.y;
let dz = ray.origin.z - self.center.z; let dz = ray.origin.z - self.center.z;
dx.powi(2) + dy.powi(2) + dz.powi(2) < self.radius.powi(2) dx.powi(2) + dy.powi(2) + dz.powi(2) <= self.radius.powi(2)
}; };
/* let normal = match exiting { /* let normal = match exiting {