diff --git a/rtchallenge/examples/eoc6.rs b/rtchallenge/examples/eoc6.rs new file mode 100644 index 0000000..3035639 --- /dev/null +++ b/rtchallenge/examples/eoc6.rs @@ -0,0 +1,56 @@ +use anyhow::Result; + +use rtchallenge::{ + canvas::Canvas, + lights::PointLight, + materials::{lighting, Material}, + rays::Ray, + spheres::{intersect, Sphere}, + tuples::{Color, Tuple}, +}; + +fn main() -> Result<()> { + let w = 640; + let h = w; + let bg = Color::new(0.2, 0.2, 0.2); + let mut c = Canvas::new(w, h, bg); + let ray_origin = Tuple::point(0., 0., -5.); + let wall_z = 10.; + let wall_size = 7.; + let pixel_size = wall_size / w as f32; + let half = wall_size / 2.; + let mut shape = Sphere::default(); + shape.material = Material { + color: Color::new(1., 0.2, 1.), + specular: 0.5, + diffuse: 0.7, + shininess: 30., + ..Material::default() + }; + let light_position = Tuple::point(-10., 10., -10.); + let light_color = Color::new(1., 1., 1.); + let light = PointLight::new(light_position, light_color); + + for y in 0..h { + let world_y = half - pixel_size * y as f32; + for x in 0..w { + let world_x = -half + pixel_size * x as f32; + let position = Tuple::point(world_x, world_y, wall_z); + let direction = (position - ray_origin).normalize(); + let r = Ray::new(ray_origin, direction); + let xs = intersect(&shape, &r); + if let Some(hit) = xs.hit() { + let point = r.position(hit.t); + let normal = hit.object.normal_at(point); + let eye = -r.direction; + let color = lighting(&hit.object.material, &light, point, eye, normal); + c.set(x, y, color); + } + } + } + + let path = "/tmp/eoc6.png"; + println!("saving output to {}", path); + c.write_to_file(path)?; + Ok(()) +}