camera: protoype supersampling for rayon render pass.
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user