Compare commits
1 Commits
7de0f07f56
...
c0e422a7eb
| Author | SHA1 | Date | |
|---|---|---|---|
| c0e422a7eb |
@ -21,13 +21,13 @@ fn main() -> Result<()> {
|
|||||||
let pixel_size = wall_size / w as Float;
|
let pixel_size = wall_size / w as Float;
|
||||||
let half = wall_size / 2.;
|
let half = wall_size / 2.;
|
||||||
let mut shape = Shape::sphere();
|
let mut shape = Shape::sphere();
|
||||||
shape.set_material(Material {
|
shape.material = Material {
|
||||||
color: Color::new(1., 0.2, 1.),
|
color: Color::new(1., 0.2, 1.),
|
||||||
specular: 0.5,
|
specular: 0.5,
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
shininess: 30.,
|
shininess: 30.,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
let light_position = Tuple::point(-10., 10., -10.);
|
let light_position = Tuple::point(-10., 10., -10.);
|
||||||
let light_color = WHITE;
|
let light_color = WHITE;
|
||||||
let light = PointLight::new(light_position, light_color);
|
let light = PointLight::new(light_position, light_color);
|
||||||
@ -44,14 +44,7 @@ fn main() -> Result<()> {
|
|||||||
let point = r.position(hit.t);
|
let point = r.position(hit.t);
|
||||||
let normal = hit.object.normal_at(point);
|
let normal = hit.object.normal_at(point);
|
||||||
let eye = -r.direction;
|
let eye = -r.direction;
|
||||||
let color = lighting(
|
let color = lighting(&hit.object.material, &light, point, eye, normal, in_shadow);
|
||||||
&hit.object.material(),
|
|
||||||
&light,
|
|
||||||
point,
|
|
||||||
eye,
|
|
||||||
normal,
|
|
||||||
in_shadow,
|
|
||||||
);
|
|
||||||
c.set(x, y, color);
|
c.set(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,11 +41,11 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut floor = Shape::sphere();
|
let mut floor = Shape::sphere();
|
||||||
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
||||||
floor.set_material(Material {
|
floor.material = Material {
|
||||||
color: Color::new(1., 0.9, 0.9),
|
color: Color::new(1., 0.9, 0.9),
|
||||||
specular: 0.,
|
specular: 0.,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut left_wall = Shape::sphere();
|
let mut left_wall = Shape::sphere();
|
||||||
left_wall.set_transform(
|
left_wall.set_transform(
|
||||||
@ -54,7 +54,7 @@ fn main() -> Result<()> {
|
|||||||
* Matrix4x4::rotation_x(PI / 2.)
|
* Matrix4x4::rotation_x(PI / 2.)
|
||||||
* Matrix4x4::scaling(10., 0.01, 10.),
|
* Matrix4x4::scaling(10., 0.01, 10.),
|
||||||
);
|
);
|
||||||
left_wall.set_material(floor.material().clone());
|
left_wall.material = floor.material.clone();
|
||||||
|
|
||||||
let mut right_wall = Shape::sphere();
|
let mut right_wall = Shape::sphere();
|
||||||
right_wall.set_transform(
|
right_wall.set_transform(
|
||||||
@ -63,36 +63,36 @@ fn main() -> Result<()> {
|
|||||||
* Matrix4x4::rotation_x(PI / 2.)
|
* Matrix4x4::rotation_x(PI / 2.)
|
||||||
* Matrix4x4::scaling(10., 0.01, 10.),
|
* Matrix4x4::scaling(10., 0.01, 10.),
|
||||||
);
|
);
|
||||||
right_wall.set_material(floor.material().clone());
|
right_wall.material = floor.material.clone();
|
||||||
|
|
||||||
let mut middle = Shape::sphere();
|
let mut middle = Shape::sphere();
|
||||||
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
||||||
middle.set_material(Material {
|
middle.material = Material {
|
||||||
color: Color::new(0.1, 1., 0.5),
|
color: Color::new(0.1, 1., 0.5),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.3,
|
specular: 0.3,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut right = Shape::sphere();
|
let mut right = Shape::sphere();
|
||||||
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
|
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
|
||||||
right.set_material(Material {
|
right.material = Material {
|
||||||
color: Color::new(0.5, 1., 0.1),
|
color: Color::new(0.5, 1., 0.1),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.3,
|
specular: 0.3,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut left = Shape::sphere();
|
let mut left = Shape::sphere();
|
||||||
left.set_transform(
|
left.set_transform(
|
||||||
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
|
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
|
||||||
);
|
);
|
||||||
left.set_material(Material {
|
left.material = Material {
|
||||||
color: Color::new(1., 0.8, 0.1),
|
color: Color::new(1., 0.8, 0.1),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.3,
|
specular: 0.3,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut world = World::default();
|
let mut world = World::default();
|
||||||
world.lights = vec![light];
|
world.lights = vec![light];
|
||||||
|
|||||||
@ -53,11 +53,11 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut floor = Shape::sphere();
|
let mut floor = Shape::sphere();
|
||||||
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
||||||
floor.set_material(Material {
|
floor.material = Material {
|
||||||
color: Color::new(1., 0.9, 0.9),
|
color: Color::new(1., 0.9, 0.9),
|
||||||
specular: 0.,
|
specular: 0.,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut left_wall = Shape::sphere();
|
let mut left_wall = Shape::sphere();
|
||||||
left_wall.set_transform(
|
left_wall.set_transform(
|
||||||
@ -66,7 +66,7 @@ fn main() -> Result<()> {
|
|||||||
* Matrix4x4::rotation_x(PI / 2.)
|
* Matrix4x4::rotation_x(PI / 2.)
|
||||||
* Matrix4x4::scaling(10., 0.01, 10.),
|
* Matrix4x4::scaling(10., 0.01, 10.),
|
||||||
);
|
);
|
||||||
left_wall.set_material(floor.material().clone());
|
left_wall.material = floor.material.clone();
|
||||||
|
|
||||||
let mut right_wall = Shape::sphere();
|
let mut right_wall = Shape::sphere();
|
||||||
right_wall.set_transform(
|
right_wall.set_transform(
|
||||||
@ -75,36 +75,36 @@ fn main() -> Result<()> {
|
|||||||
* Matrix4x4::rotation_x(PI / 2.)
|
* Matrix4x4::rotation_x(PI / 2.)
|
||||||
* Matrix4x4::scaling(10., 0.00001, 10.),
|
* Matrix4x4::scaling(10., 0.00001, 10.),
|
||||||
);
|
);
|
||||||
right_wall.set_material(floor.material().clone());
|
right_wall.material = floor.material.clone();
|
||||||
|
|
||||||
let mut middle = Shape::sphere();
|
let mut middle = Shape::sphere();
|
||||||
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
||||||
middle.set_material(Material {
|
middle.material = Material {
|
||||||
color: Color::new(0.1, 1., 0.5),
|
color: Color::new(0.1, 1., 0.5),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.3,
|
specular: 0.3,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut right = Shape::sphere();
|
let mut right = Shape::sphere();
|
||||||
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
|
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
|
||||||
right.set_material(Material {
|
right.material = Material {
|
||||||
color: Color::new(1., 1., 1.),
|
color: Color::new(1., 1., 1.),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.0,
|
specular: 0.0,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut left = Shape::sphere();
|
let mut left = Shape::sphere();
|
||||||
left.set_transform(
|
left.set_transform(
|
||||||
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
|
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
|
||||||
);
|
);
|
||||||
left.set_material(Material {
|
left.material = Material {
|
||||||
color: Color::new(1., 0.8, 0.1),
|
color: Color::new(1., 0.8, 0.1),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.3,
|
specular: 0.3,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
let mut world = World::default();
|
let mut world = World::default();
|
||||||
world.lights = vec![light1, light2, light3];
|
world.lights = vec![light1, light2, light3];
|
||||||
|
|||||||
@ -12,11 +12,14 @@ enum Geometry {
|
|||||||
Sphere,
|
Sphere,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shape represents visible objects. A signal instance of Shape can generically represent one of
|
||||||
|
/// many different shapes based on the value of it's geometry field. Users chose the shape by
|
||||||
|
/// calling the appropriate constructor, i.e. [Shape::sphere].
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Shape {
|
pub struct Shape {
|
||||||
transform: Matrix4x4,
|
transform: Matrix4x4,
|
||||||
inverse_transform: Matrix4x4,
|
inverse_transform: Matrix4x4,
|
||||||
material: Material,
|
pub material: Material,
|
||||||
geometry: Geometry,
|
geometry: Geometry,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,13 +39,13 @@ impl Shape {
|
|||||||
/// assert_eq!(s.transform(), t);
|
/// assert_eq!(s.transform(), t);
|
||||||
///
|
///
|
||||||
/// // Default Sphere has the default material.
|
/// // Default Sphere has the default material.
|
||||||
/// assert_eq!(s.material(), &Material::default());
|
/// assert_eq!(s.material, Material::default());
|
||||||
/// // It can be overridden.
|
/// // It can be overridden.
|
||||||
/// let mut s = Shape::sphere();
|
/// let mut s = Shape::sphere();
|
||||||
/// let mut m = Material::default();
|
/// let mut m = Material::default();
|
||||||
/// m.ambient = 1.;
|
/// m.ambient = 1.;
|
||||||
/// *s.material_mut() = m.clone();
|
/// s.material = m.clone();
|
||||||
/// assert_eq!(s.material(), &m);
|
/// assert_eq!(s.material, m);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn sphere() -> Shape {
|
pub fn sphere() -> Shape {
|
||||||
Shape {
|
Shape {
|
||||||
@ -145,18 +148,6 @@ impl Shape {
|
|||||||
self.transform = t;
|
self.transform = t;
|
||||||
self.inverse_transform = t.inverse();
|
self.inverse_transform = t.inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn material(&self) -> &Material {
|
|
||||||
&self.material
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn material_mut(&mut self) -> &mut Material {
|
|
||||||
&mut self.material
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_material(&mut self, m: Material) {
|
|
||||||
self.material = m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Intersect a ray with a sphere.
|
/// Intersect a ray with a sphere.
|
||||||
|
|||||||
@ -40,12 +40,12 @@ impl World {
|
|||||||
pub fn test_world() -> World {
|
pub fn test_world() -> World {
|
||||||
let light = PointLight::new(Tuple::point(-10., 10., -10.), WHITE);
|
let light = PointLight::new(Tuple::point(-10., 10., -10.), WHITE);
|
||||||
let mut s1 = Shape::sphere();
|
let mut s1 = Shape::sphere();
|
||||||
s1.set_material(Material {
|
s1.material = Material {
|
||||||
color: Color::new(0.8, 1., 0.6),
|
color: Color::new(0.8, 1., 0.6),
|
||||||
diffuse: 0.7,
|
diffuse: 0.7,
|
||||||
specular: 0.2,
|
specular: 0.2,
|
||||||
..Material::default()
|
..Material::default()
|
||||||
});
|
};
|
||||||
let mut s2 = Shape::sphere();
|
let mut s2 = Shape::sphere();
|
||||||
s2.set_transform(Matrix4x4::scaling(0.5, 0.5, 0.5));
|
s2.set_transform(Matrix4x4::scaling(0.5, 0.5, 0.5));
|
||||||
World {
|
World {
|
||||||
@ -137,7 +137,7 @@ impl World {
|
|||||||
.fold(Color::new(0., 0., 0.), |acc, light| {
|
.fold(Color::new(0., 0., 0.), |acc, light| {
|
||||||
let shadowed = self.is_shadowed(comps.over_point, light);
|
let shadowed = self.is_shadowed(comps.over_point, light);
|
||||||
acc + lighting(
|
acc + lighting(
|
||||||
&comps.object.material(),
|
&comps.object.material,
|
||||||
light,
|
light,
|
||||||
comps.over_point,
|
comps.over_point,
|
||||||
comps.eyev,
|
comps.eyev,
|
||||||
@ -177,15 +177,15 @@ impl World {
|
|||||||
/// let w = {
|
/// let w = {
|
||||||
/// let mut w = World::test_world();
|
/// let mut w = World::test_world();
|
||||||
/// let mut outer = &mut w.objects[0];
|
/// let mut outer = &mut w.objects[0];
|
||||||
/// let m = outer.material_mut().ambient = 1.;
|
/// let m = outer.material.ambient = 1.;
|
||||||
/// let inner = &mut w.objects[1];
|
/// let inner = &mut w.objects[1];
|
||||||
/// inner.material_mut().ambient = 1.;
|
/// inner.material.ambient = 1.;
|
||||||
/// w
|
/// w
|
||||||
/// };
|
/// };
|
||||||
/// let inner = &w.objects[1];
|
/// let inner = &w.objects[1];
|
||||||
/// let r = Ray::new(Tuple::point(0., 0., 0.75), Tuple::vector(0., 0., -1.));
|
/// let r = Ray::new(Tuple::point(0., 0., 0.75), Tuple::vector(0., 0., -1.));
|
||||||
/// let c = w.color_at(&r);
|
/// let c = w.color_at(&r);
|
||||||
/// assert_eq!(c, inner.material().color);
|
/// assert_eq!(c, inner.material.color);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn color_at(&self, r: &Ray) -> Color {
|
pub fn color_at(&self, r: &Ray) -> Color {
|
||||||
match self.intersect(r).hit() {
|
match self.intersect(r).hit() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user