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*
flamegraph.svg
showcase.png
/out.log

View file

@ -18,9 +18,14 @@ use super::{
// TODO: Is this a good constant?
const JITTER_CONST: f64 = 0.05;
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 {
/// Determine the color that should be used to fill this pixel.
///
@ -218,6 +223,12 @@ impl Scene {
.enumerate()
.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
// This list will be a set of opacities
let intersections = other_objects
@ -243,7 +254,13 @@ impl Scene {
} else {
let soft_shadow_coefficient =
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 {
None
} 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() {
true => 1.0,
false => {
let average = intersections.iter().cloned().sum::<f64>()
let average = intersections.iter().map(|s| s.opacity).sum::<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,
object: &Object,
) -> 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 locations = iter::repeat_with(|| {
let x = rng.gen_range(0.0..JITTER_RADIUS);
let y = rng.gen_range(0.0..JITTER_RADIUS);
let z = 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..SOFT_SHADOW_JITTER_RADIUS);
let z = rng.gen_range(0.0..SOFT_SHADOW_JITTER_RADIUS);
let delta = Vector::new(x, y, z);
light_location + delta
})
.take(JITTER_RAYS)
.collect::<Vec<_>>();
let num_obstructed_rays = locations
.into_par_iter()
.filter(|location| {
@ -431,14 +452,14 @@ impl Scene {
let t_lambda = self.trace_single_ray(ray, depth + 1)?;
let value = (1.0 - fresnel_coefficient) * (1.0 - material.alpha) * t_lambda;
debug!(
/* debug!(
depth,
fresnel_coefficient,
alpha = material.alpha,
?t_lambda,
?value,
"computing final value"
);
); */
Ok(value)
}

View file

@ -81,7 +81,7 @@ impl Sphere {
let dy = ray.origin.y - self.center.y;
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 {