impl depth cueing

This commit is contained in:
Michael Zhang 2023-02-15 02:08:21 -06:00
parent 000003603a
commit 0000037052
5 changed files with 76 additions and 16 deletions

View file

@ -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 $< $@

View file

@ -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

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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<Path>) -> Result<Self> {
@ -50,9 +52,8 @@ impl Scene {
.collect::<Result<Vec<_>>>()?;
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)?;