refactor: scene/raytracer/camera logic
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use std::f32::consts::PI;
|
||||
use std::{f32::consts::PI};
|
||||
|
||||
use crate::{ray::Ray, vec3::Vec3};
|
||||
|
||||
@@ -6,18 +6,18 @@ use crate::{ray::Ray, vec3::Vec3};
|
||||
pub struct Camera {
|
||||
// raytracing
|
||||
pub anti_alias_rate: u32,
|
||||
pub pixel00_loc: Vec3,
|
||||
pub pixel_delta_u: Vec3,
|
||||
pub pixel_delta_v: Vec3,
|
||||
pixel00_loc: Vec3,
|
||||
pixel_delta_u: Vec3,
|
||||
pixel_delta_v: Vec3,
|
||||
|
||||
// camera
|
||||
dirty: bool,
|
||||
pub fov: f32,
|
||||
pub look_from: Vec3,
|
||||
pub look_at: Vec3,
|
||||
fov: f32,
|
||||
look_from: Vec3,
|
||||
look_at: Vec3,
|
||||
vup: Vec3,
|
||||
pub defocus_angle: f32,
|
||||
pub focus_dist: f32,
|
||||
defocus_angle: f32,
|
||||
focus_dist: f32,
|
||||
|
||||
// camera helpers
|
||||
u: Vec3,
|
||||
@@ -115,6 +115,14 @@ impl Camera {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_anti_alias_rate(&self) -> u32 {
|
||||
self.anti_alias_rate
|
||||
}
|
||||
|
||||
pub fn get_pixel_tl(&self, x: u32, y: u32) -> Vec3 {
|
||||
return self.pixel00_loc + (x * self.pixel_delta_u) + (y * self.pixel_delta_v);
|
||||
}
|
||||
|
||||
pub fn get_ray(&self, pixel_tl: Vec3, x: u32, y: u32) -> Ray {
|
||||
let pixel_loc = pixel_tl
|
||||
+ (x * self.pixel_delta_u / (self.anti_alias_rate + 1) as f32)
|
||||
|
||||
@@ -2,7 +2,7 @@ use image::{ExtendedColorType, ImageEncoder, codecs::png::PngEncoder};
|
||||
use log::{error, info};
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
use rayon::prelude::*;
|
||||
use std::{fs::File, sync::Arc};
|
||||
use std::{fs::File, sync::Arc, time::Instant};
|
||||
|
||||
use crate::{
|
||||
objects::{hit::Hit, traits::Hittable},
|
||||
@@ -24,8 +24,7 @@ pub fn write_image(filename: &str, pixels: &[u8], width: u32, height: u32) {
|
||||
}
|
||||
|
||||
pub fn render(scene: &mut Scene) {
|
||||
let camera = &mut scene.camera;
|
||||
camera.init(scene.image_width as f32, scene.image_height as f32);
|
||||
scene.init();
|
||||
|
||||
// TODO: currently splits per vertical line, but could be more granular (per chunk)
|
||||
let mut pixels = vec![0 as u8; (scene.image_width * scene.image_height * 3) as usize];
|
||||
@@ -34,9 +33,11 @@ pub fn render(scene: &mut Scene) {
|
||||
.enumerate()
|
||||
.collect();
|
||||
|
||||
let now = Instant::now();
|
||||
scanlines.into_par_iter().for_each(|(i, chunk)| {
|
||||
render_chunk(chunk, scene, i as u32);
|
||||
});
|
||||
info!("rendering took {}.{} seconds.", now.elapsed().as_secs(), now.elapsed().subsec_nanos());
|
||||
|
||||
info!("Writing image file...");
|
||||
write_image(
|
||||
@@ -48,23 +49,22 @@ pub fn render(scene: &mut Scene) {
|
||||
}
|
||||
|
||||
pub fn render_chunk(chunk: &mut [u8], scene: &Scene, y: u32) {
|
||||
let camera = &scene.camera;
|
||||
let camera = &scene.get_camera();
|
||||
let aa_rate = &scene.get_camera().get_anti_alias_rate();
|
||||
|
||||
for i in 0..scene.image_width {
|
||||
let pixel_tl = camera.pixel00_loc + (i * camera.pixel_delta_u) + (y * camera.pixel_delta_v);
|
||||
// THOUGHT: the above seems more efficient (esp for larger aa rates) but can test for a
|
||||
// get_ray_no_tl() function and compare performance.
|
||||
let pixel_tl = camera.get_pixel_tl(i, y);
|
||||
|
||||
let mut pixel_colour = Colour::default();
|
||||
for y in 1..(camera.anti_alias_rate + 1) {
|
||||
for x in 1..(camera.anti_alias_rate + 1) {
|
||||
for y in 1..(aa_rate + 1) {
|
||||
for x in 1..(aa_rate + 1) {
|
||||
let r = camera.get_ray(pixel_tl, x, y);
|
||||
pixel_colour += ray_colour(&scene.objects, &r, scene.max_depth);
|
||||
}
|
||||
}
|
||||
|
||||
let (r, g, b) =
|
||||
(pixel_colour / (camera.anti_alias_rate * camera.anti_alias_rate) as f32).output();
|
||||
(pixel_colour / (aa_rate * aa_rate) as f32).output();
|
||||
chunk[(i * 3) as usize] = r;
|
||||
chunk[(i * 3) as usize + 1] = g;
|
||||
chunk[(i * 3) as usize + 2] = b;
|
||||
|
||||
@@ -38,6 +38,22 @@ impl Scene {
|
||||
max_depth,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_camera(&self) -> &Camera {
|
||||
&self.camera
|
||||
}
|
||||
|
||||
pub fn get_image_width(&self) -> f32 {
|
||||
self.image_width as f32
|
||||
}
|
||||
|
||||
pub fn get_image_height(&self) -> f32 {
|
||||
self.image_height as f32
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
self.camera.init(self.get_image_width(), self.get_image_height());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user