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
/assignment-1b
/raytracer1b
/assignment-1c
/raytracer1c
/examples/*.png
*.ppm
*.zip

View file

@ -1,10 +1,10 @@
eye 0 0 4
viewdir 0 0 -1
updir 0 1 0
updir 1 1 0
hfov 60
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
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<_>>();
let average =
intersections.iter().cloned().sum::<f64>() / intersections.len() as f64;
match intersections.is_empty() {
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},
object::{Object, ObjectKind},
sphere::Sphere,
texture::Texture,
texture::{Texture, NormalMap},
triangle::Triangle,
Scene,
},
@ -260,6 +260,21 @@ impl Scene {
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}"),
}
}

View file

@ -12,7 +12,7 @@ use crate::{Point, Point2, Vector};
use self::data::{Attenuation, DepthCueing, Light, Material};
use self::object::Object;
use self::texture::Texture;
use self::texture::{Texture, NormalMap};
#[derive(Debug, Default)]
pub struct Scene {
@ -39,6 +39,9 @@ pub struct Scene {
/// List of textures
pub textures: Vec<Texture>,
/// List of normal maps (Extra credit)
pub normal_maps: Vec<NormalMap>,
/// Coordinates into a texture image
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
/// the intersection point
/// Get the (u, v) coordinates in the texture (between 0 and 1) that
/// corresponds to the intersection point
pub fn get_texture_coord(
&self,
scene: &Scene,

View file

@ -1,4 +1,7 @@
use crate::image::{Color, Image};
use crate::{
image::{Color, Image},
Vector,
};
#[derive(Debug)]
pub struct Texture(Image);
@ -39,3 +42,23 @@ impl Texture {
+ (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 nalgebra::{Matrix2, Vector2, Vector3};
use ordered_float::NotNan;
@ -73,7 +75,10 @@ impl Triangle {
self.compute_barycentric_coordinates(scene, p)?;
// 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);
}
@ -87,6 +92,7 @@ impl Triangle {
(alpha * n0 + beta * n1 + gamma * n2).normalize()
}
None => n.normalize(),
};
@ -142,7 +148,7 @@ impl Triangle {
(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]
fn basis_vectors(&self, scene: &Scene) -> (Vector, Vector, Vector) {
let (p0, p1, p2) = self.corner_coordinates(scene);