ft: 8: anti-aliasing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
output.png
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::{
|
|||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
image_width: u32,
|
image_width: u32,
|
||||||
image_height: u32,
|
image_height: u32,
|
||||||
|
anti_alias_rate: u32,
|
||||||
center: Vec3,
|
center: Vec3,
|
||||||
pixel00_loc: Vec3,
|
pixel00_loc: Vec3,
|
||||||
pixel_delta_u: Vec3,
|
pixel_delta_u: Vec3,
|
||||||
@@ -19,6 +20,9 @@ pub struct Camera {
|
|||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
pub fn new(aspect_ratio: f32, image_width: u32) -> 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);
|
let image_height = max(1, (image_width as f32 / aspect_ratio) as u32);
|
||||||
|
|
||||||
//camera
|
//camera
|
||||||
@@ -34,13 +38,13 @@ impl Camera {
|
|||||||
let pixel_delta_u = viewport_u / image_width as f32;
|
let pixel_delta_u = viewport_u / image_width as f32;
|
||||||
let pixel_delta_v = viewport_v / image_height 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;
|
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 {
|
Camera {
|
||||||
image_width: image_width,
|
image_width: image_width,
|
||||||
image_height: image_height,
|
image_height: image_height,
|
||||||
|
anti_alias_rate: anti_alias_rate,
|
||||||
center: camera_center,
|
center: camera_center,
|
||||||
pixel00_loc: pixel00_loc,
|
pixel00_loc: pixel00_loc,
|
||||||
pixel_delta_u: pixel_delta_u,
|
pixel_delta_u: pixel_delta_u,
|
||||||
@@ -55,13 +59,24 @@ impl Camera {
|
|||||||
for j in 0..self.image_height {
|
for j in 0..self.image_height {
|
||||||
info!("{}\tScanlines remaining.", (self.image_height - j));
|
info!("{}\tScanlines remaining.", (self.image_height - j));
|
||||||
for i in 0..self.image_width {
|
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);
|
self.pixel00_loc + (i * self.pixel_delta_u) + (j * self.pixel_delta_v);
|
||||||
let ray_dir = pixel_center - self.center;
|
|
||||||
|
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);
|
let r = Ray::new(self.center, ray_dir);
|
||||||
|
pixel_colour += self.ray_colour(&hittables, &r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let pixel = imgbuf.get_pixel_mut(i, j);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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., 0., -0.1), 0.01));
|
||||||
world.push(Sphere::new(Vec3::new(0., -100.5, -1.), 100.));
|
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);
|
c.render(&world);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ impl Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn output(self) -> image::Rgb<u8> {
|
pub fn output(self) -> image::Rgb<u8> {
|
||||||
let ir = (255.599 * self.r) as u8;
|
let ir = (255.599 * self.r.clamp(0., 1.)) as u8;
|
||||||
let ig = (255.599 * self.g) as u8;
|
let ig = (255.599 * self.g.clamp(0., 1.)) as u8;
|
||||||
let ib = (255.599 * self.b) as u8;
|
let ib = (255.599 * self.b.clamp(0., 1.)) as u8;
|
||||||
|
|
||||||
image::Rgb([ir, ig, ib])
|
image::Rgb([ir, ig, ib])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user