use anyhow::Result; use rtchallenge::{ canvas::Canvas, lights::PointLight, materials::{lighting, Material}, rays::Ray, shapes::{intersect, Shape}, tuples::{Color, Tuple}, Float, WHITE, }; 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 Float; let half = wall_size / 2.; let mut shape = Shape::sphere(); shape.material = Material { color: Color::new(1., 0.2, 1.).into(), specular: 0.5, diffuse: 0.7, shininess: 30., ..Material::default() }; let light_position = Tuple::point(-10., 10., -10.); let light_color = WHITE; let light = PointLight::new(light_position, light_color); let in_shadow = false; for y in 0..h { let world_y = half - pixel_size * y as Float; for x in 0..w { let world_x = -half + pixel_size * x as Float; 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, &hit.object, &light, point, eye, normal, in_shadow, ); c.set(x, y, color); } } } let path = "/tmp/eoc6.png"; println!("saving output to {}", path); c.write_to_file(path)?; Ok(()) }