From abf401afb5f5815e2387e44d9b9fc1384df38305 Mon Sep 17 00:00:00 2001 From: djairoh Date: Wed, 15 Apr 2026 14:44:30 +0200 Subject: [PATCH] ft: 8: anti-aliasing --- .gitignore | 1 + src/camera.rs | 27 +++++++++++++++++++++------ src/main.rs | 2 +- src/vec3.rs | 6 +++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..7ed91ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +output.png diff --git a/src/camera.rs b/src/camera.rs index 1a7f8ca..f802efe 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -11,6 +11,7 @@ use crate::{ pub struct Camera { image_width: u32, image_height: u32, + anti_alias_rate: u32, center: Vec3, pixel00_loc: Vec3, pixel_delta_u: Vec3, @@ -19,6 +20,9 @@ pub struct Camera { impl Camera { pub fn new(aspect_ratio: f32, image_width: u32) -> Camera { + Camera::new_aa(aspect_ratio, image_width, 1) + } + pub fn new_aa(aspect_ratio: f32, image_width: u32, anti_alias_rate: u32) -> Camera { let image_height = max(1, (image_width as f32 / aspect_ratio) as u32); //camera @@ -34,13 +38,13 @@ impl Camera { let pixel_delta_u = viewport_u / image_width as f32; let pixel_delta_v = viewport_v / image_height as f32; - let viewport_upper_left = + let pixel00_loc = camera_center - Vec3::new(0., 0., focal_length) - viewport_u / 2 - viewport_v / 2; - let pixel00_loc = viewport_upper_left + 0.5 * (pixel_delta_u + pixel_delta_v); Camera { image_width: image_width, image_height: image_height, + anti_alias_rate: anti_alias_rate, center: camera_center, pixel00_loc: pixel00_loc, pixel_delta_u: pixel_delta_u, @@ -55,13 +59,24 @@ impl Camera { for j in 0..self.image_height { info!("{}\tScanlines remaining.", (self.image_height - j)); for i in 0..self.image_width { - let pixel_center = + let pixel_tl = self.pixel00_loc + (i * self.pixel_delta_u) + (j * self.pixel_delta_v); - let ray_dir = pixel_center - self.center; - let r = Ray::new(self.center, ray_dir); + + let mut pixel_colour = Colour::nil(); + for y in 1..(self.anti_alias_rate + 1) { + for x in 1..(self.anti_alias_rate + 1) { + let pixel_loc = pixel_tl + + (x * self.pixel_delta_u / (self.anti_alias_rate + 1) as f32) + + (y * self.pixel_delta_v / (self.anti_alias_rate + 1) as f32); + let ray_dir = pixel_loc - self.center; + let r = Ray::new(self.center, ray_dir); + pixel_colour += self.ray_colour(&hittables, &r); + } + } let pixel = imgbuf.get_pixel_mut(i, j); - *pixel = self.ray_colour(&hittables, &r).output(); + *pixel = + (pixel_colour / (self.anti_alias_rate * self.anti_alias_rate) as f32).output(); } } diff --git a/src/main.rs b/src/main.rs index c3e9028..e588d88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,6 @@ fn main() { world.push(Sphere::new(Vec3::new(0., 0., -0.1), 0.01)); world.push(Sphere::new(Vec3::new(0., -100.5, -1.), 100.)); - let c = Camera::new(16. / 9., 400); + let c = Camera::new_aa(16. / 9., 400, 2); c.render(&world); } diff --git a/src/vec3.rs b/src/vec3.rs index f67018d..d4ebd29 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -67,9 +67,9 @@ impl Vec3 { } pub fn output(self) -> image::Rgb { - let ir = (255.599 * self.r) as u8; - let ig = (255.599 * self.g) as u8; - let ib = (255.599 * self.b) as u8; + let ir = (255.599 * self.r.clamp(0., 1.)) as u8; + let ig = (255.599 * self.g.clamp(0., 1.)) as u8; + let ib = (255.599 * self.b.clamp(0., 1.)) as u8; image::Rgb([ir, ig, ib]) }