wtf sphere
This commit is contained in:
parent
73bbd64cc0
commit
7bf1c91a99
3 changed files with 39 additions and 17 deletions
1
assignment-1d/.gitignore
vendored
1
assignment-1d/.gitignore
vendored
|
@ -8,3 +8,4 @@
|
||||||
perf.data*
|
perf.data*
|
||||||
flamegraph.svg
|
flamegraph.svg
|
||||||
showcase.png
|
showcase.png
|
||||||
|
/out.log
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue