fix
BIN
assignment-1c/examples/hw1c_grading_files/Test1.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
14
assignment-1c/examples/hw1c_grading_files/Test1.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
eye 0 0 0
|
||||
viewdir 0 0 -1
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 512 256
|
||||
bkgcolor 0.1 0.1 0.1
|
||||
light -2 1 0 1 1 1 1
|
||||
mtlcolor 0 1 0 1 1 1 0.2 0.6 0.2 20
|
||||
v 0 1 -4
|
||||
v -1 -1 -4
|
||||
v 1 -1 -4
|
||||
v 2 1 -6
|
||||
f 1 2 3
|
||||
f 1 3 4
|
BIN
assignment-1c/examples/hw1c_grading_files/Test2.png
Normal file
After Width: | Height: | Size: 12 KiB |
18
assignment-1c/examples/hw1c_grading_files/Test2.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
eye 0 0 0
|
||||
viewdir 0 0 -1
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 512 256
|
||||
bkgcolor 0.1 0.1 0.1
|
||||
light -2 1 0 1 1 1 1
|
||||
mtlcolor 0 0 1 1 1 1 0.2 0.6 0.2 20
|
||||
v -1 1 -4
|
||||
v -1 -1 -4
|
||||
v 1 -1 -4
|
||||
v 1 1 -4
|
||||
vn -1 1 1
|
||||
vn -1 -1 1
|
||||
vn 1 -1 1
|
||||
vn 1 1 1
|
||||
f 1//1 2//2 3//3
|
||||
f 1//1 3//3 4//4
|
BIN
assignment-1c/examples/hw1c_grading_files/Test3.png
Normal file
After Width: | Height: | Size: 105 KiB |
10
assignment-1c/examples/hw1c_grading_files/Test3.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
eye 2 -6 1
|
||||
viewdir -1 3 -0.5
|
||||
updir 0 0 1
|
||||
hfov 50
|
||||
imsize 512 512
|
||||
bkgcolor 0.5 0.7 0.9
|
||||
light 0 1 -1 0 1 1 1
|
||||
mtlcolor 0 1 0 1 1 1 0.2 0.8 0.1 20
|
||||
texture earthtexture.ppm
|
||||
sphere 0 0 0 2
|
BIN
assignment-1c/examples/hw1c_grading_files/Test4.png
Normal file
After Width: | Height: | Size: 28 KiB |
19
assignment-1c/examples/hw1c_grading_files/Test4.txt
Normal file
|
@ -0,0 +1,19 @@
|
|||
eye 0 0 0
|
||||
viewdir 0 0 -1
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 512 256
|
||||
bkgcolor 0.1 0.1 0.1
|
||||
light -2 1 0 1 1 1 1
|
||||
mtlcolor 0 0 1 1 1 1 0.2 0.6 0.2 20
|
||||
texture umn.ppm
|
||||
v -1 1 -4
|
||||
v -1 -1 -4
|
||||
v 1 -1 -4
|
||||
v 1 1 -4
|
||||
vt 0 0
|
||||
vt 0 1
|
||||
vt 1 1
|
||||
vt 1 0
|
||||
f 1/1 2/2 3/3
|
||||
f 1/1 3/3 4/4
|
BIN
assignment-1c/examples/hw1c_grading_files/Test5.png
Normal file
After Width: | Height: | Size: 25 KiB |
25
assignment-1c/examples/hw1c_grading_files/Test5.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
eye 0 0 0
|
||||
viewdir 0 0 -1
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 512 256
|
||||
bkgcolor 0.1 0.1 0.1
|
||||
light -2 1 0 1 1 1 1
|
||||
mtlcolor 0 0 1 1 1 1 0.2 0.6 0.2 20
|
||||
texture umn.ppm
|
||||
v -1 1 -4
|
||||
v -1 -1 -4
|
||||
v 1 -1 -4
|
||||
v 1 1 -4
|
||||
vn -1 1 1
|
||||
vn -1 -1 1
|
||||
vn 1 -1 1
|
||||
vn 1 1 1
|
||||
vt 0 0
|
||||
vt 0 1
|
||||
vt 1 1
|
||||
vt 1 0
|
||||
f 1/1/1 2/2/2 3/3/3
|
||||
f 1/1/1 3/3/3 4/4/4
|
||||
|
||||
|
BIN
assignment-1c/examples/hw1c_grading_files/Test6.png
Normal file
After Width: | Height: | Size: 640 KiB |
56
assignment-1c/examples/hw1c_grading_files/Test6.txt
Normal file
|
@ -0,0 +1,56 @@
|
|||
eye 12.5 5 2.5
|
||||
viewdir -2 -0.5 2
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 900 600
|
||||
bkgcolor 0.5 0.7 0.9
|
||||
light 1 -1 1 0 1 1 1
|
||||
mtlcolor 0 1 0 1 1 1 0.2 0.8 0 20
|
||||
v 10 0 5
|
||||
v -10 0 5
|
||||
v -10 0 25
|
||||
v 10 0 25
|
||||
v 5 0 12.5
|
||||
v -5 0 12.5
|
||||
v -5 5 12.5
|
||||
v 5 5 12.5
|
||||
v 5 0 17.5
|
||||
v -5 0 17.5
|
||||
v -5 5 17.5
|
||||
v 5 5 17.5
|
||||
v 5 7.5 15
|
||||
v -5 7.5 15
|
||||
v 5 4.5 12
|
||||
v -5 4.5 12
|
||||
v 5 4.5 18
|
||||
v -5 4.5 18
|
||||
vt 0 0
|
||||
vt 0 1
|
||||
vt 1 1
|
||||
vt 1 0
|
||||
vt 2 0
|
||||
vt 2 1
|
||||
vt 0.5 0
|
||||
vt 4 0
|
||||
vt 4 1
|
||||
texture grass.ppm
|
||||
f 1/2 2/3 3/4
|
||||
f 1/2 3/4 4/1
|
||||
texture wood.ppm
|
||||
f 5/2 6/6 7/5
|
||||
f 5/2 7/5 8/1
|
||||
f 9/2 11/5 10/6
|
||||
f 9/2 12/1 11/5
|
||||
f 6/2 10/3 11/4
|
||||
f 6/2 11/4 7/1
|
||||
f 5/3 12/1 9/2
|
||||
f 5/3 8/4 12/1
|
||||
f 7/2 11/3 14/7
|
||||
f 8/3 13/7 12/2
|
||||
texture redwood.ppm
|
||||
f 13/1 15/2 16/9
|
||||
f 13/1 16/9 14/8
|
||||
f 13/8 14/1 18/2
|
||||
f 13/8 18/2 17/9
|
||||
texture soccerball.ppm
|
||||
sphere -2.5 0.5 9 0.5
|
BIN
assignment-1c/examples/hw1c_grading_files/TestE.png
Normal file
After Width: | Height: | Size: 46 KiB |
20
assignment-1c/examples/hw1c_grading_files/TestE.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
eye 0 0 0
|
||||
viewdir 0 0 -1
|
||||
updir 0 1 0
|
||||
hfov 60
|
||||
imsize 512 256
|
||||
bkgcolor 0.1 0.1 0.1
|
||||
light -2 1 0 1 1 1 1
|
||||
mtlcolor 1 1 1 1 1 1 0.2 0.6 0.2 20 1 0
|
||||
bump normalmap.ppm
|
||||
sphere -1.6 0 -4 0.5
|
||||
v -1 1 -4
|
||||
v -1 -1 -4
|
||||
v 1 -1 -4
|
||||
v 1 1 -4
|
||||
vt 0 0
|
||||
vt 0 1
|
||||
vt 1 1
|
||||
vt 1 0
|
||||
f 1/1 2/2 3/3
|
||||
f 1/1 3/3 4/4
|
2
assignment-1c/examples/hw1c_grading_files/grading.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#! /bin/sh
|
||||
PROGRAM_NAME="raytracer1c"; echo "-------- Running Test1.txt --------"; ./$PROGRAM_NAME Test1.txt; echo "-------- Running Test2.txt --------";./$PROGRAM_NAME Test2.txt; echo "-------- Running Test3.txt --------";./$PROGRAM_NAME Test3.txt; echo "-------- Running Test4.txt --------";./$PROGRAM_NAME Test4.txt; echo "-------- Running Test5.txt --------";./$PROGRAM_NAME Test5.txt; echo "-------- Running Test6.txt --------";./$PROGRAM_NAME Test6.txt; echo "-------- Running TestE.txt --------";./$PROGRAM_NAME TestE.txt;
|
|
@ -4,7 +4,7 @@ extern crate tracing;
|
|||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use assignment_1c::image::Image;
|
||||
use assignment_1c::ray::Ray;
|
||||
use assignment_1c::scene::Scene;
|
||||
|
@ -112,9 +112,9 @@ fn main() -> Result<()> {
|
|||
|
||||
Ok(match earliest_intersection {
|
||||
// Take the object's material color
|
||||
Some((obj_idx, intersection_context, object)) => {
|
||||
scene.compute_pixel_color(obj_idx, object, intersection_context)?
|
||||
}
|
||||
Some((obj_idx, intersection_context, object)) => scene
|
||||
.compute_pixel_color(obj_idx, object, intersection_context)
|
||||
.context("Could not compute pixel color.")?,
|
||||
|
||||
// There was no intersection, so this should default to the scene's
|
||||
// background color
|
||||
|
|
|
@ -43,7 +43,7 @@ impl Scene {
|
|||
|
||||
let texture = match self.textures.get(texture_idx) {
|
||||
Some(v) => v,
|
||||
None => bail!("Texture index not found."),
|
||||
None => bail!("Texture index {texture_idx} not found."),
|
||||
};
|
||||
|
||||
texture.pixel_at(u, v)
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::path::Path;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use itertools::Itertools;
|
||||
use nalgebra::Vector3;
|
||||
use nalgebra::{Vector2, Vector3};
|
||||
|
||||
use crate::{
|
||||
image::{Color, Image},
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||
data::{Attenuation, Light, LightKind, Material},
|
||||
object::{Object, ObjectKind},
|
||||
sphere::Sphere,
|
||||
texture::{Texture, NormalMap},
|
||||
texture::Texture,
|
||||
triangle::Triangle,
|
||||
Scene,
|
||||
},
|
||||
|
@ -209,6 +209,9 @@ impl Scene {
|
|||
// vn nx ny nz
|
||||
"vn" => scene.vertex_normals.push(r!(Vector)),
|
||||
|
||||
// vt u v
|
||||
"vt" => scene.texture_vertices.push(r!(Vector2<f64>)),
|
||||
|
||||
// f v1 v2 v3
|
||||
// f v1//n1 v2//n2 v3//n3
|
||||
"f" => {
|
||||
|
@ -230,7 +233,7 @@ impl Scene {
|
|||
let textures = match textures.iter().filter(|o| o.is_some()).count() {
|
||||
0 => None,
|
||||
n if n == vs.len() => Some(textures.map(|o| o.unwrap())),
|
||||
_ => bail!("Cannot mix and match having a normal index"),
|
||||
_ => bail!("Cannot mix and match having a texture index"),
|
||||
};
|
||||
|
||||
let triangle = Triangle {
|
||||
|
@ -256,7 +259,7 @@ impl Scene {
|
|||
texture_idx = Some(idx);
|
||||
|
||||
let image = Image::from_file(path)?;
|
||||
let texture = Texture::new(image);
|
||||
let texture = Texture::new(image, false);
|
||||
scene.textures.push(texture);
|
||||
}
|
||||
|
||||
|
@ -271,8 +274,8 @@ impl Scene {
|
|||
texture_idx = Some(idx);
|
||||
|
||||
let image = Image::from_file(path)?;
|
||||
let normal_map = NormalMap::new(image);
|
||||
scene.normal_maps.push(normal_map);
|
||||
let normal_map = Texture::new(image, true);
|
||||
scene.textures.push(normal_map);
|
||||
}
|
||||
|
||||
_ => bail!("Unknown keyword {keyword}"),
|
||||
|
@ -332,6 +335,25 @@ macro_rules! impl_construct {
|
|||
impl_construct!(f64);
|
||||
impl_construct!(usize);
|
||||
|
||||
impl Construct for Vector2<f64> {
|
||||
type Args = ();
|
||||
|
||||
fn construct<'a, I>(it: &mut I, _: Self::Args) -> Result<Self>
|
||||
where
|
||||
I: Iterator<Item = &'a str>,
|
||||
{
|
||||
let (x, y) = match it.next_tuple() {
|
||||
Some(v) => v,
|
||||
None => bail!("Expected 2 values"),
|
||||
};
|
||||
|
||||
let x: f64 = x.parse()?;
|
||||
let y: f64 = y.parse()?;
|
||||
|
||||
Ok(Vector2::new(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
impl Construct for Vector3<f64> {
|
||||
type Args = ();
|
||||
|
||||
|
|
|
@ -7,12 +7,14 @@ pub mod sphere;
|
|||
pub mod texture;
|
||||
pub mod triangle;
|
||||
|
||||
use nalgebra::Vector2;
|
||||
|
||||
use crate::image::Color;
|
||||
use crate::{Point, Point2, Vector};
|
||||
|
||||
use self::data::{Attenuation, DepthCueing, Light, Material};
|
||||
use self::object::Object;
|
||||
use self::texture::{Texture, NormalMap};
|
||||
use self::texture::{Texture};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Scene {
|
||||
|
@ -40,7 +42,7 @@ pub struct Scene {
|
|||
pub textures: Vec<Texture>,
|
||||
|
||||
/// List of normal maps (Extra credit)
|
||||
pub normal_maps: Vec<NormalMap>,
|
||||
pub normal_maps: Vec<Texture>,
|
||||
|
||||
/// Coordinates into a texture image
|
||||
pub texture_vertices: Vec<Point2>,
|
||||
|
|
|
@ -4,17 +4,33 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Texture(Image);
|
||||
pub struct Texture {
|
||||
image: Image,
|
||||
is_normal_map: bool,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
pub fn new(image: Image) -> Self {
|
||||
Self(image)
|
||||
pub fn new(image: Image, is_normal_map: bool) -> Self {
|
||||
Self {
|
||||
image,
|
||||
is_normal_map,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pixel_at_exact(&self, x: usize, y: usize) -> Color {
|
||||
// TODO: Debug asserts?
|
||||
|
||||
self.0.data[y * self.0.width + x]
|
||||
let x = match x {
|
||||
n if n < self.image.width => n,
|
||||
_ => self.image.width - 1,
|
||||
};
|
||||
|
||||
let y = match y {
|
||||
n if n < self.image.height => n,
|
||||
_ => self.image.height - 1,
|
||||
};
|
||||
|
||||
self.image.data[y * self.image.width + x]
|
||||
}
|
||||
|
||||
/// Returns a pixel at the given coordinate. For non-lattice coordinates,
|
||||
|
@ -24,8 +40,8 @@ impl Texture {
|
|||
debug_assert!(0.0 <= v && v <= 1.0, "u must be between 0 and 1");
|
||||
|
||||
// Slide 121
|
||||
let x = u * (self.0.width - 1) as f64;
|
||||
let y = v * (self.0.height - 1) as f64;
|
||||
let x = u * (self.image.width - 1) as f64;
|
||||
let y = v * (self.image.height - 1) as f64;
|
||||
|
||||
let i = x.floor();
|
||||
let j = y.floor();
|
||||
|
@ -42,23 +58,3 @@ 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)
|
||||
}
|
||||
}
|
||||
|
|