impl depth cueing
This commit is contained in:
parent
000003603a
commit
0000037052
5 changed files with 76 additions and 16 deletions
|
@ -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 $< $@
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue