Skip to content

Commit

Permalink
Render low resolution image after camera change
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Oom committed Jul 4, 2024
1 parent 6b0af8d commit f20dd95
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 27 deletions.
2 changes: 1 addition & 1 deletion kdtree-tester-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ fn main() {
"Testing up to {} rays...",
args.size.width * args.size.height * args.bounces
);
let camera = Pinhole::new(&scene.cameras[0], args.size.width, args.size.height);
let camera = Pinhole::new(scene.cameras[0].clone(), args.size.width, args.size.height);
let bouncer = RayBouncer {
scene,
kdtree,
Expand Down
2 changes: 1 addition & 1 deletion pathtracer-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ fn main() {
"Rendering {} px image with {} thread(s) and {} total iteration(s)...",
args.size, args.threads, total_iterations,
);
let camera = Pinhole::new(&scene.cameras[0], args.size.width, args.size.height);
let camera = Pinhole::new(scene.cameras[0].clone(), args.size.width, args.size.height);
let pathtracer = Pathtracer {
max_bounces: args.max_bounces,
scene,
Expand Down
13 changes: 7 additions & 6 deletions pathtracer-gui/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ impl PathtracerGui {
"pathtracer-gui",
Default::default(),
Box::new(move |_cc| {
let pinhole = Pinhole::new(&self.camera, self.size.x as u32, self.size.y as u32);
let pinhole =
Pinhole::new(self.camera.clone(), self.size.x as u32, self.size.y as u32);
let (thread, tx, rx) = spawn_worker(pathtracer, pinhole);
self.worker_thread = Some(thread);
self.worker_tx = Some(tx);
Expand Down Expand Up @@ -118,10 +119,10 @@ impl PathtracerGui {
}

pub fn update_pinhole(&mut self) {
let pinhole = Pinhole::new(&self.camera, self.size.x as u32, self.size.y as u32);
self.worker_tx
.iter()
.for_each(|tx| tx.send(pinhole.clone()).unwrap());
let pinhole = Pinhole::new(self.camera.clone(), self.size.x as u32, self.size.y as u32);
if let Some(tx) = &self.worker_tx {
tx.send(pinhole).unwrap()
}
}

pub fn stop_worker_thread(&mut self) {
Expand Down Expand Up @@ -213,7 +214,7 @@ impl eframe::App for PathtracerGui {
self.set_size(ui.available_size());
}
if let Some(texture) = &self.texture {
ui.image(texture);
ui.add(egui::Image::from_texture(texture).fit_to_exact_size(self.size));
}
},
);
Expand Down
44 changes: 33 additions & 11 deletions pathtracer-gui/src/workers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
use scene::camera::Pinhole;
use tracing::{
image_buffer::ImageBuffer,
measure::measure,
pathtracer::Pathtracer,
raylogger::{RayLoggerWithIteration, RayLoggerWriter},
};
Expand All @@ -31,6 +32,12 @@ fn render_subdivided(
) -> ImageBuffer {
let count_x = pinhole.width / sub_size.x;
let count_y = pinhole.height / sub_size.y;
eprintln!(
"Rendering size={:?} sub_size={:?} count={:?}",
pinhole.size().as_slice(),
sub_size.as_slice(),
[count_x, count_y]
);
(0..count_x * count_y)
.into_par_iter()
.fold(
Expand All @@ -41,13 +48,13 @@ fn render_subdivided(
)
},
|(mut rng, mut buffer), i| {
let pixel = Vector2::new(i % sub_size.x, i / sub_size.x);
let pixel = Vector2::new(i % count_x * sub_size.x, i / count_x * sub_size.y);
let mut ray_logger = RayLoggerWithIteration {
writer: &mut RayLoggerWriter::None(),
iteration: 0,
};
pathtracer.render_subdivided_mut(
&pinhole,
pinhole,
&mut ray_logger,
&mut rng,
&mut buffer,
Expand Down Expand Up @@ -75,7 +82,12 @@ fn worker_loop(
loop {
match rx.try_recv() {
Ok(new_pinhole) => {
eprintln!("Resetting buffer {new_pinhole:?}");
eprintln!(
"New pinhole position={:?} direction={:?} size={:?}",
new_pinhole.camera.position.as_slice(),
new_pinhole.camera.direction.as_slice(),
new_pinhole.size().as_slice(),
);
pinhole = new_pinhole;
combined_buffer = ImageBuffer::new(pinhole.width, pinhole.height);
iteration = 0;
Expand All @@ -84,15 +96,25 @@ fn worker_loop(
Err(mpsc::TryRecvError::Disconnected) => return,
}
}
eprintln!(
"Rendering {}x{} iteration {}",
pinhole.width, pinhole.height, iteration
);
let t1 = time::Instant::now();
let buffer = render_subdivided(&pathtracer, &pinhole, Vector2::new(128, 128));
if iteration == 0 {
let pinhole_small = Pinhole::new(
pinhole.camera.clone(),
64,
64 * pinhole.height / pinhole.width,
);
let (duration, buffer) = measure(|| {
render_subdivided(&pathtracer, &pinhole_small, pinhole_small.size() / 3)
});
let _ = tx.send(RenderResult {
iteration: 1,
duration,
image: buffer,
});
}

let (duration, buffer) =
measure(|| render_subdivided(&pathtracer, &pinhole, pinhole.size() / 4));
combined_buffer.add_mut(&buffer);
let t2 = time::Instant::now();
let duration = t2 - t1;
iteration += 1;
let _ = tx.send(RenderResult {
iteration,
Expand Down
2 changes: 1 addition & 1 deletion raytracer-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn main() {
);

println!("Rendering...");
let camera = Pinhole::new(&scene.cameras[0], args.size.width, args.size.height);
let camera = Pinhole::new(scene.cameras[0].clone(), args.size.width, args.size.height);
let raytracer = Raytracer {
scene,
kdtree,
Expand Down
12 changes: 6 additions & 6 deletions scene/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ pub struct Camera {

impl Camera {
pub fn new(
position: &Vector3<f32>,
position: Vector3<f32>,
target: &Vector3<f32>,
up: &Vector3<f32>,
fov_degrees: f32,
) -> Camera {
let direction = UnitVector3::new_normalize(target - position);
Camera {
position: *position,
position,
direction,
up: UnitVector3::new_normalize(*up),
right: UnitVector3::new_normalize(direction.cross(up)),
Expand All @@ -40,26 +40,26 @@ impl Camera {

#[derive(Clone, Debug)]
pub struct Pinhole {
pub camera: Camera,
pub width: u32,
pub height: u32,
pub position: Vector3<f32>,
pub plane: Vector3<f32>,
pub dx: Vector3<f32>,
pub dy: Vector3<f32>,
}

impl Pinhole {
pub fn new(camera: &Camera, width: u32, height: u32) -> Pinhole {
pub fn new(camera: Camera, width: u32, height: u32) -> Pinhole {
let aspect_ratio = width as f32 / height as f32;
let half_fov_radians = camera.fov_degrees * std::f32::consts::PI / 360.0;
let x = camera.right.into_inner() * (half_fov_radians.sin() * aspect_ratio);
let y = camera.up.into_inner() * half_fov_radians.sin();
let z = camera.direction.into_inner() * half_fov_radians.cos();

Pinhole {
camera,
width,
height,
position: camera.position,
plane: z + y - x,
dx: 2.0 * x,
dy: -2.0 * y,
Expand All @@ -74,7 +74,7 @@ impl Pinhole {
#[inline]
pub fn ray(&self, x: f32, y: f32) -> Ray {
Ray {
origin: self.position,
origin: self.camera.position,
direction: self.plane + x * self.dx + y * self.dy,
}
}
Expand Down
2 changes: 1 addition & 1 deletion scene/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fn collect_cameras(mtl: &mtl::Mtl) -> Vec<Camera> {
.iter()
.map(|camera| {
Camera::new(
&camera.position.into(),
camera.position.into(),
&camera.target.into(),
&camera.up.into(),
camera.fov,
Expand Down
1 change: 1 addition & 0 deletions tracing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod image_buffer;
pub mod material;
pub mod measure;
pub mod pathtracer;
pub mod raylogger;
pub mod raytracer;
Expand Down
11 changes: 11 additions & 0 deletions tracing/src/measure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use std::time;

pub fn measure<F, O>(f: F) -> (time::Duration, O)
where
F: FnOnce() -> O,
{
let t1 = time::Instant::now();
let output = f();
let t2 = time::Instant::now();
(t2 - t1, output)
}

0 comments on commit f20dd95

Please sign in to comment.