camera: protoype supersampling for rayon render pass.

This commit is contained in:
2021-07-18 16:31:07 -07:00
parent ce998c68eb
commit 599f484dff
3 changed files with 106 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ use std::{
thread,
};
use rand::Rng;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use serde::Deserialize;
use structopt::StructOpt;
@@ -114,6 +115,31 @@ impl Camera {
pub fn pixel_size(&self) -> f32 {
self.pixel_size
}
pub fn supersample_rays_for_pixel(&self, px: usize, py: usize, samples: usize) -> Vec<Ray> {
let mut rng = rand::thread_rng();
(0..samples)
.map(|_| {
// The offset from the edge of the canvas to the pixel's corner.
let xoffset = (px as f32 + rng.gen::<f32>()) * self.pixel_size;
let yoffset = (py as f32 + rng.gen::<f32>()) * self.pixel_size;
// The untransformed coordinates of the pixle in world space.
// (Remember that the camera looks toward -z, so +x is to the left.)
let world_x = self.half_width - xoffset;
let world_y = self.half_height - yoffset;
// Using the camera matrix, transofmrm the canvas point and the origin,
// and then compute the ray's direction vector.
// (Remember that the canvas is at z>=-1).
let pixel = self.inverse_transform * Tuple::point(world_x, world_y, -1.);
let origin = self.inverse_transform * Tuple::point(0., 0., 0.);
let direction = (pixel - origin).normalize();
Ray::new(origin, direction)
})
.collect()
}
/// Calculate ray that starts at the camera and passes through the (x,y)
/// pixel on the canvas.
@@ -297,9 +323,19 @@ impl Camera {
(0..self.vsize).into_par_iter().for_each(|y| {
let mut row_image = Canvas::new(self.hsize, 1, BLACK);
for x in 0..self.hsize {
let ray = self.ray_for_pixel(x, y);
let color = w.color_at(&ray);
row_image.set(x, 0, color);
const SAMPLES: usize = 0;
if SAMPLES > 0 {
let color = self
.supersample_rays_for_pixel(x, y, SAMPLES)
.iter()
.map(|ray| w.color_at(&ray))
.fold(BLACK, |acc, c| acc + c);
row_image.set(x, 0, color / SAMPLES as f32);
} else {
let ray = self.ray_for_pixel(x, y);
let color = w.color_at(&ray);
row_image.set(x, 0, color);
}
}
// TODO(wathiede): create a row based setter for memcpying the row as a whole.
let mut image = image_mu.lock().expect("failed to lock image mutex");