colon skull

This commit is contained in:
Michael Zhang 2023-03-03 16:48:58 -06:00
parent 9dafc764c3
commit 70cba6d253
9 changed files with 63 additions and 15 deletions

View file

@ -1,6 +1,6 @@
/target /target
/assignment-1b /assignment-1c
/raytracer1b /raytracer1c
/examples/*.png /examples/*.png
*.ppm *.ppm
*.zip *.zip

View file

@ -1,10 +1,10 @@
eye 0 0 4 eye 0 0 4
viewdir 0 0 -1 viewdir 0 0 -1
updir 0 1 0 updir 1 1 0
hfov 60 hfov 60
imsize 640 480 imsize 640 480
bkgcolor 0.1 0.1 0.1 bkgcolor 0.4 0.4 0.4
light -2 1 0 1 1 1 1 light -2 1 0 1 1 1 1
mtlcolor 1 0.6 1 1 1 1 0.1 0.4 0.4 20 mtlcolor 1 0.6 1 1 1 1 0.1 0.4 0.4 20

BIN
assignment-1c/raytracer1b Executable file

Binary file not shown.

View file

@ -205,12 +205,13 @@ impl Scene {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let average =
intersections.iter().cloned().sum::<f64>() / intersections.len() as f64;
match intersections.is_empty() { match intersections.is_empty() {
true => 1.0, true => 1.0,
false => average, false => {
let average = intersections.iter().cloned().sum::<f64>()
/ intersections.len() as f64;
average
}
} }
} }

View file

@ -13,7 +13,7 @@ use crate::{
data::{Attenuation, Light, LightKind, Material}, data::{Attenuation, Light, LightKind, Material},
object::{Object, ObjectKind}, object::{Object, ObjectKind},
sphere::Sphere, sphere::Sphere,
texture::Texture, texture::{Texture, NormalMap},
triangle::Triangle, triangle::Triangle,
Scene, Scene,
}, },
@ -260,6 +260,21 @@ impl Scene {
scene.textures.push(texture); scene.textures.push(texture);
} }
"bump" => {
let input_parent = path.parent().unwrap().to_path_buf();
let path = match parts.next() {
Some(s) => input_parent.join(s),
None => bail!("Did not provide path."),
};
let idx = scene.textures.len();
texture_idx = Some(idx);
let image = Image::from_file(path)?;
let normal_map = NormalMap::new(image);
scene.normal_maps.push(normal_map);
}
_ => bail!("Unknown keyword {keyword}"), _ => bail!("Unknown keyword {keyword}"),
} }
} }

View file

@ -12,7 +12,7 @@ use crate::{Point, Point2, Vector};
use self::data::{Attenuation, DepthCueing, Light, Material}; use self::data::{Attenuation, DepthCueing, Light, Material};
use self::object::Object; use self::object::Object;
use self::texture::Texture; use self::texture::{Texture, NormalMap};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Scene { pub struct Scene {
@ -39,6 +39,9 @@ pub struct Scene {
/// List of textures /// List of textures
pub textures: Vec<Texture>, pub textures: Vec<Texture>,
/// List of normal maps (Extra credit)
pub normal_maps: Vec<NormalMap>,
/// Coordinates into a texture image /// Coordinates into a texture image
pub texture_vertices: Vec<Point2>, pub texture_vertices: Vec<Point2>,

View file

@ -45,8 +45,8 @@ impl ObjectKind {
} }
} }
/// Get the coordinates in the texture (between 0 and 1) that corresponds to /// Get the (u, v) coordinates in the texture (between 0 and 1) that
/// the intersection point /// corresponds to the intersection point
pub fn get_texture_coord( pub fn get_texture_coord(
&self, &self,
scene: &Scene, scene: &Scene,

View file

@ -1,4 +1,7 @@
use crate::image::{Color, Image}; use crate::{
image::{Color, Image},
Vector,
};
#[derive(Debug)] #[derive(Debug)]
pub struct Texture(Image); pub struct Texture(Image);
@ -39,3 +42,23 @@ impl Texture {
+ (alpha) * (beta) * self.pixel_at_exact(i + 1, j + 1) + (alpha) * (beta) * self.pixel_at_exact(i + 1, j + 1)
} }
} }
#[derive(Debug)]
pub struct NormalMap(Image);
impl NormalMap {
pub fn new(image: Image) -> Self {
Self(image)
}
pub fn normal_vector_at_exact(&self, x: usize, y: usize) -> Vector {
let vec = self.0.data[y * self.0.width + x];
// So, according to the instructions, this should actually be a value
// between -1 and 1. However, we're reading this in through an image.
// I'm just going to do the lazy thing here (which theoretically
// actually saves cycles) by only doing the transformation when loading
// out of the image
vec.map(|value| 2.0 * value / 255.0 - 1.0)
}
}

View file

@ -1,3 +1,5 @@
use std::f64::EPSILON;
use anyhow::Result; use anyhow::Result;
use nalgebra::{Matrix2, Vector2, Vector3}; use nalgebra::{Matrix2, Vector2, Vector3};
use ordered_float::NotNan; use ordered_float::NotNan;
@ -73,7 +75,10 @@ impl Triangle {
self.compute_barycentric_coordinates(scene, p)?; self.compute_barycentric_coordinates(scene, p)?;
// Each of alpha, beta, and gamma must be between 0 and 1 // Each of alpha, beta, and gamma must be between 0 and 1
if ![alpha, beta, gamma].into_iter().all(|v| 0.0 < v && v < 1.0) { if ![alpha, beta, gamma]
.into_iter()
.all(|v| 0.0 - EPSILON <= v && v <= 1.0 + EPSILON)
{
return Ok(None); return Ok(None);
} }
@ -87,6 +92,7 @@ impl Triangle {
(alpha * n0 + beta * n1 + gamma * n2).normalize() (alpha * n0 + beta * n1 + gamma * n2).normalize()
} }
None => n.normalize(), None => n.normalize(),
}; };
@ -142,7 +148,7 @@ impl Triangle {
(p0, p1, p2) (p0, p1, p2)
} }
/// Get the new basis vectors using p0 as the origin. /// Get the new basis vectors using p0 as the origin. Returns (p0, e1, e2)
#[inline] #[inline]
fn basis_vectors(&self, scene: &Scene) -> (Vector, Vector, Vector) { fn basis_vectors(&self, scene: &Scene) -> (Vector, Vector, Vector) {
let (p0, p1, p2) = self.corner_coordinates(scene); let (p0, p1, p2) = self.corner_coordinates(scene);