Skip to content

Commit

Permalink
Chapter 10
Browse files Browse the repository at this point in the history
  • Loading branch information
jtdowney committed Mar 2, 2023
1 parent f0a406a commit d8d64ac
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 24 deletions.
56 changes: 56 additions & 0 deletions examples/chapter10.rs
@@ -0,0 +1,56 @@
use std::f64::consts::PI;

use ray_tracer::{
camera, checkers_pattern, color, gradiant_pattern, plane, point, point_light, sphere,
transform::{scaling, translation, view_transform},
vector, world, BLACK, WHITE,
};

fn main() -> anyhow::Result<()> {
let mut world = world();

let mut floor = plane();
floor.material.pattern = Some(checkers_pattern(WHITE, BLACK));
world.objects.push(floor);

let mut middle = sphere();
middle.transform = translation(-0.5, 1.0, 0.5);
middle.material.color = color(0.1, 1.0, 0.5);
middle.material.diffuse = 0.7;
middle.material.specular = 0.3;
world.objects.push(middle);

let mut right = sphere();
right.transform = translation(1.5, 0.5, -0.5) * scaling(0.5, 0.5, 0.5);
right.material.pattern = Some({
let mut pattern = gradiant_pattern(color(0.5, 0.75, 0.1), color(0.1, 0.25, 1.0));
pattern.transform = translation(1, 0, 0) * scaling(2, 2, 2);
pattern
});
right.material.diffuse = 0.7;
right.material.specular = 0.3;
world.objects.push(right);

let mut left = sphere();
left.transform = translation(-1.5, 0.33, -0.75) * scaling(0.33, 0.33, 0.33);
left.material.color = color(1.0, 0.8, 0.1);
left.material.diffuse = 0.7;
left.material.specular = 0.3;
world.objects.push(left);

world.light = Some(point_light(point(-10, 10, -10), WHITE));

let width = 1024;
let height = 768;
let mut camera = camera(width, height, PI / 3.0);
camera.transform = view_transform(
point(0.0, 1.5, -5.0),
point(0.0, 1.0, 0.0),
vector(0.0, 1.0, 0.0),
);

let canvas = camera.render(world)?;
print!("{}", canvas.to_ppm()?);

Ok(())
}
2 changes: 1 addition & 1 deletion examples/chapter6.rs
Expand Up @@ -31,7 +31,7 @@ fn main() -> anyhow::Result<()> {
let color = hit
.object
.material
.lighting(light, point, eye, normal, false);
.lighting(&shape, light, point, eye, normal, false);
canvas.write_pixel(x, y, color)?;
}
}
Expand Down
6 changes: 3 additions & 3 deletions examples/chapter7.rs
Expand Up @@ -15,23 +15,23 @@ fn main() -> anyhow::Result<()> {

let mut floor = sphere();
floor.transform = scaling(10.0, 0.01, 10.0);
floor.material = material;
floor.material = material.clone();
world.objects.push(floor);

let mut left_wall = sphere();
left_wall.transform = translation(0, 0, 5)
* rotation_y(-PI / 4.0)
* rotation_x(PI / 2.0)
* scaling(10.0, 0.01, 10.0);
left_wall.material = material;
left_wall.material = material.clone();
world.objects.push(left_wall);

let mut right_wall = sphere();
right_wall.transform = translation(0, 0, 5)
* rotation_y(PI / 4.0)
* rotation_x(PI / 2.0)
* scaling(10.0, 0.01, 10.0);
right_wall.material = material;
right_wall.material = material.clone();
world.objects.push(right_wall);

let mut middle = sphere();
Expand Down
6 changes: 1 addition & 5 deletions examples/chapter9.rs
@@ -1,18 +1,14 @@
use std::f64::consts::PI;

use ray_tracer::{
camera, color, material, plane, point, point_light, sphere,
camera, color, plane, point, point_light, sphere,
transform::{scaling, translation, view_transform},
vector, world, WHITE,
};

fn main() -> anyhow::Result<()> {
let mut world = world();

let mut material = material();
material.color = color(1.0, 0.9, 0.9);
material.specular = 0.0;

let floor = plane();
world.objects.push(floor);

Expand Down
Binary file added output/chapter10.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/lib.rs
Expand Up @@ -5,6 +5,7 @@ mod intersection;
mod light;
mod material;
mod matrix;
mod pattern;
mod point;
mod ray;
mod shapes;
Expand All @@ -19,6 +20,7 @@ pub use intersection::{hit, intersection};
pub use light::{point_light, PointLight};
pub use material::{material, Material};
pub use matrix::{identity_matrix, matrix, Matrix, Matrix2, Matrix3, Matrix4};
pub use pattern::{checkers_pattern, gradiant_pattern, ring_pattern, stripe_pattern, Pattern};
pub use point::{point, Point};
pub use ray::{ray, Ray};
pub use shapes::plane::{plane, Plane};
Expand All @@ -27,7 +29,7 @@ pub use shapes::Shape;
pub use vector::{vector, Vector};
pub use world::{default_world, world, World};

pub const EPSILON: f64 = 0.00001;
pub const EPSILON: f64 = 0.0001;
pub const ORIGIN: Point = Point {
x: 0.0,
y: 0.0,
Expand Down
29 changes: 19 additions & 10 deletions src/material.rs
@@ -1,4 +1,4 @@
use crate::{color, Color, Point, PointLight, Vector, BLACK};
use crate::{color, pattern::Pattern, Color, Point, PointLight, Shape, Vector, BLACK};

pub fn material() -> Material {
Material {
Expand All @@ -7,28 +7,37 @@ pub fn material() -> Material {
diffuse: 0.9,
specular: 0.9,
shininess: 200.0,
pattern: None,
}
}

#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Debug)]
pub struct Material {
pub color: Color,
pub ambient: f64,
pub diffuse: f64,
pub specular: f64,
pub shininess: f64,
pub pattern: Option<Pattern>,
}

impl Material {
pub fn lighting(
&self,
shape: &Shape,
light: PointLight,
point: Point,
eye_vector: Vector,
normal_vector: Vector,
in_shadow: bool,
) -> Color {
let effective_color = self.color * light.intensity;
let color = if let Some(pattern) = &self.pattern {
pattern.pattern_at_shape(shape, point)
} else {
self.color
};

let effective_color = color * light.intensity;
let light_vector = (light.position - point).normalize();
let ambient = effective_color * self.ambient;
if in_shadow {
Expand Down Expand Up @@ -64,7 +73,7 @@ impl Material {
mod tests {
use approx::assert_abs_diff_eq;

use crate::{point, point_light, vector, ORIGIN, WHITE};
use crate::{point, point_light, sphere, vector, ORIGIN, WHITE};

use super::*;

Expand All @@ -77,7 +86,7 @@ mod tests {
let light = point_light(point(0, 0, -10), color(1, 1, 1));
assert_abs_diff_eq!(
color(1.9, 1.9, 1.9),
m.lighting(light, position, eyev, normalv, false)
m.lighting(&sphere(), light, position, eyev, normalv, false)
);
}

Expand All @@ -90,7 +99,7 @@ mod tests {
let light = point_light(point(0, 0, -10), color(1, 1, 1));
assert_abs_diff_eq!(
color(1.0, 1.0, 1.0),
m.lighting(light, position, eyev, normalv, false)
m.lighting(&sphere(), light, position, eyev, normalv, false)
);
}

Expand All @@ -103,7 +112,7 @@ mod tests {
let light = point_light(point(0, 10, -10), color(1, 1, 1));
assert_abs_diff_eq!(
color(0.7364, 0.7364, 0.7364),
m.lighting(light, position, eyev, normalv, false)
m.lighting(&sphere(), light, position, eyev, normalv, false)
);
}

Expand All @@ -116,7 +125,7 @@ mod tests {
let light = point_light(point(0, 10, -10), color(1, 1, 1));
assert_abs_diff_eq!(
color(1.6364, 1.6364, 1.6364),
m.lighting(light, position, eyev, normalv, false)
m.lighting(&sphere(), light, position, eyev, normalv, false)
);
}

Expand All @@ -129,7 +138,7 @@ mod tests {
let light = point_light(point(0, 0, 10), color(1, 1, 1));
assert_abs_diff_eq!(
color(0.1, 0.1, 0.1),
m.lighting(light, position, eyev, normalv, false)
m.lighting(&sphere(), light, position, eyev, normalv, false)
);
}

Expand All @@ -143,7 +152,7 @@ mod tests {
let in_shadow = true;
assert_eq!(
color(0.1, 0.1, 0.1),
m.lighting(light, position, eyev, normalv, in_shadow)
m.lighting(&sphere(), light, position, eyev, normalv, in_shadow)
);
}
}

0 comments on commit d8d64ac

Please sign in to comment.