From 37f54190e8b190b403d7832da9f0e101df94541a Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 15 Feb 2023 02:08:21 -0600 Subject: [PATCH] impl depth cueing --- assignment-1b/Makefile | 2 +- assignment-1b/examples/objects.txt | 20 ++++++++++++--- assignment-1b/src/scene/data.rs | 10 ++++---- assignment-1b/src/scene/illumination.rs | 34 ++++++++++++++++++++++--- assignment-1b/src/scene/input_file.rs | 26 ++++++++++++++++--- 5 files changed, 76 insertions(+), 16 deletions(-) diff --git a/assignment-1b/Makefile b/assignment-1b/Makefile index de80502..8f1e734 100644 --- a/assignment-1b/Makefile +++ b/assignment-1b/Makefile @@ -33,7 +33,7 @@ $(HANDIN): $(BINARY) $(WRITEUP) Makefile Cargo.toml Cargo.lock README.md $(EXAMP $(ZIP) -r $@ src examples $^ examples/%.ppm: examples/%.txt $(SOURCES) - cargo run -- -o $@ $< + cargo run --release -- -o $@ $< examples/%.png: examples/%.ppm convert $< $@ diff --git a/assignment-1b/examples/objects.txt b/assignment-1b/examples/objects.txt index 8b68339..f7ba514 100644 --- a/assignment-1b/examples/objects.txt +++ b/assignment-1b/examples/objects.txt @@ -5,8 +5,10 @@ hfov 60 updir 0 1 0 bkgcolor 0.1 0.1 0.1 -light -10 10 -3 0 0 0.4 0.4 -light 10 10 -3 1 0.4 0 0.4 +depthcueing 0.1 0.1 0.1 1 0.2 100 5 + +light -10 10 -3 0 0.8 0.8 0.8 +light -10 10 -3 1 0.8 0.8 0.8 mtlcolor 0 0.5 0.5 1 1 1 0.2 0.4 0 10 sphere -1 -2 -5 2 @@ -16,10 +18,20 @@ mtlcolor 0.5 0.5 1 0.4 0.4 0.4 0.2 0.4 0 10 sphere 1 2 -3 3 sphere -6 3 -4 1 +mtlcolor 1.0 0 0.5 0.6 0.4 0.2 0.2 0.4 0 10 +sphere 20 20 -50 6 + mtlcolor 0.5 0 0.5 0.6 0.4 0.2 0.2 0.4 0 10 -sphere 5 5 -1 1 sphere -6 -4 -8 7 -cylinder -2 4 -3 0 0 5 1 4 + +mtlcolor 0.8 0 0.3 0.6 0.4 0.2 0.2 0.4 0 10 +cylinder -2 2 -3 0 0 5 1 4 + +mtlcolor 0.8 0.8 0.3 0.6 0.4 0.2 0.2 0.4 0 10 +sphere -40 35 -80 7 +sphere -25 20 -60 5 +sphere -12.5 15 -40 3 +sphere -6 11 -20 1.5 mtlcolor 0.5 1 0.5 0.2 0.4 0.8 0.2 0.4 0 10 cylinder 5 1 -2 1 -2 1 1 2 diff --git a/assignment-1b/src/scene/data.rs b/assignment-1b/src/scene/data.rs index d375357..6ce9b0f 100644 --- a/assignment-1b/src/scene/data.rs +++ b/assignment-1b/src/scene/data.rs @@ -67,11 +67,11 @@ pub struct Light { #[derive(Debug, Default)] pub struct DepthCueing { - color: Color, - a_max: f64, - a_min: f64, - dist_max: f64, - dist_min: f64, + pub color: Color, + pub a_max: f64, + pub a_min: f64, + pub dist_max: f64, + pub dist_min: f64, } impl Scene { diff --git a/assignment-1b/src/scene/illumination.rs b/assignment-1b/src/scene/illumination.rs index 250a5eb..f129ec5 100644 --- a/assignment-1b/src/scene/illumination.rs +++ b/assignment-1b/src/scene/illumination.rs @@ -3,7 +3,10 @@ use ordered_float::NotNan; use crate::image::Color; -use super::{data::LightKind, Scene}; +use super::{ + data::{DepthCueing, LightKind}, + Scene, +}; /// Information about an intersection #[derive(Derivative)] @@ -86,9 +89,34 @@ impl Scene { }) .sum(); - let result = ambient_component + diffuse_and_specular; + let color = ambient_component + diffuse_and_specular; + + // Apply depth cueing to the result + let a_dc = { + // Distance from the viewer + let d_obj = (intersection_context.point - self.eye_pos).norm(); + let DepthCueing { + dist_max, + dist_min, + a_max, + a_min, + .. + } = self.depth_cueing; + + if d_obj < dist_min { + a_max + } else if d_obj < dist_max { + a_min + (a_max - a_min) * (dist_max - d_obj) / (dist_max - dist_min) + } else { + a_min + } + }; + + let color = a_dc * color + (1.0 - a_dc) * self.depth_cueing.color; // Need to clamp the result so none of the components goes over 1 - result.map(|v| v.min(1.0)) + let clamped_result = color.map(|v| v.min(1.0)); + + clamped_result } } diff --git a/assignment-1b/src/scene/input_file.rs b/assignment-1b/src/scene/input_file.rs index a1c7226..e2114f8 100644 --- a/assignment-1b/src/scene/input_file.rs +++ b/assignment-1b/src/scene/input_file.rs @@ -10,6 +10,8 @@ use crate::scene::{ Scene, }; +use super::data::DepthCueing; + impl Scene { /// Parse the input file into a scene pub fn from_input_file(path: impl AsRef) -> Result { @@ -50,9 +52,8 @@ impl Scene { .collect::>>()?; let read_vec3 = |start: usize| { - if parts.len() < start + 3 { - bail!("Vec3 requires 3 components."); - } + ensure!(parts.len() >= start + 3, "Vec3 requires 3 components."); + Ok(Vector3::new( parts[start], parts[start + 1], @@ -68,7 +69,10 @@ impl Scene { "hfov" => scene.hfov = parts[0], "bkgcolor" => scene.bkg_color = read_vec3(0)?, + // light x y z w r g b "light" => { + ensure!(parts.len() == 7, "Light requires 7 params"); + let kind = match parts[3] as usize { 0 => LightKind::Directional { direction: read_vec3(0)?, @@ -85,8 +89,24 @@ impl Scene { scene.lights.push(light); } + // depthcueing dcr dcg dcb amax amin distmax distmin + "depthcueing" => { + ensure!(parts.len() == 7, "Depth cueing requires 7 params"); + + let color = read_vec3(0)?; + scene.depth_cueing = DepthCueing { + color, + a_max: parts[3], + a_min: parts[4], + dist_max: parts[5], + dist_min: parts[6], + }; + } + // mtlcolor Odr Odg Odb Osr Osg Osb ka kd ks n "mtlcolor" => { + ensure!(parts.len() == 10, "Material color requires 10 params"); + let diffuse_color = read_vec3(0)?; let specular_color = read_vec3(3)?;