colon skull
This commit is contained in:
parent
9dafc764c3
commit
70cba6d253
9 changed files with 63 additions and 15 deletions
4
assignment-1c/.gitignore
vendored
4
assignment-1c/.gitignore
vendored
|
@ -1,6 +1,6 @@
|
||||||
/target
|
/target
|
||||||
/assignment-1b
|
/assignment-1c
|
||||||
/raytracer1b
|
/raytracer1c
|
||||||
/examples/*.png
|
/examples/*.png
|
||||||
*.ppm
|
*.ppm
|
||||||
*.zip
|
*.zip
|
||||||
|
|
|
@ -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
BIN
assignment-1c/raytracer1b
Executable file
Binary file not shown.
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue