Threads pass back small images instead of sharing large image
This commit is contained in:
parent
a04f51998c
commit
0574dff685
|
|
@ -6,10 +6,11 @@ use super::integrators::{DirectionalLight, Integrator, WhittedIntegrator};
|
||||||
use super::raycasting::Ray;
|
use super::raycasting::Ray;
|
||||||
use super::sampler::Sampler;
|
use super::sampler::Sampler;
|
||||||
use super::scene::Scene;
|
use super::scene::Scene;
|
||||||
|
use super::util::Tile;
|
||||||
|
|
||||||
use crate::Real;
|
use crate::Real;
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
struct ImageSampler<T: Real> {
|
struct ImageSampler<T: Real> {
|
||||||
image_height_pixels: usize,
|
image_height_pixels: usize,
|
||||||
|
|
@ -66,22 +67,13 @@ impl<T: Real> ImageSampler<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_scene<T: Real>(output_image: Arc<Mutex<ImageRgbF<T>>>, scene: Arc<Scene<T>>) {
|
|
||||||
let height = output_image.lock().unwrap().get_height();
|
|
||||||
let width = output_image.lock().unwrap().get_width();
|
|
||||||
partial_render_scene(output_image, scene, 0, height, 0, width, height, width)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn partial_render_scene<T: Real>(
|
pub fn partial_render_scene<T: Real>(
|
||||||
output_image: Arc<Mutex<ImageRgbF<T>>>,
|
|
||||||
scene: Arc<Scene<T>>,
|
scene: Arc<Scene<T>>,
|
||||||
row_start: usize,
|
tile: Tile,
|
||||||
row_end: usize,
|
|
||||||
column_start: usize,
|
|
||||||
column_end: usize,
|
|
||||||
height: usize,
|
height: usize,
|
||||||
width: usize,
|
width: usize,
|
||||||
) {
|
) -> (Tile, ImageRgbF<T>) {
|
||||||
|
let mut output_image_tile = ImageRgbF::new(tile.width(), tile.height());
|
||||||
let image_sampler = ImageSampler::new(width, height, scene.camera_location);
|
let image_sampler = ImageSampler::new(width, height, scene.camera_location);
|
||||||
let ambient_intensity: T = convert(0.0);
|
let ambient_intensity: T = convert(0.0);
|
||||||
let directional_intensity1: T = convert(7.0);
|
let directional_intensity1: T = convert(7.0);
|
||||||
|
|
@ -105,18 +97,18 @@ pub fn partial_render_scene<T: Real>(
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
let sampler = Sampler { scene: &scene };
|
let sampler = Sampler { scene: &scene };
|
||||||
for column in column_start..column_end {
|
for column in 0..tile.width() {
|
||||||
for row in row_start..row_end {
|
for row in 0..tile.height() {
|
||||||
let ray = image_sampler.ray_for_pixel(row, column);
|
let ray = image_sampler.ray_for_pixel(tile.start_row + row, tile.end_column + column);
|
||||||
let hit = sampler.sample(&ray);
|
let hit = sampler.sample(&ray);
|
||||||
let colour = match hit {
|
let colour = match hit {
|
||||||
None => ColourRgbF::from_named(NamedColour::Black),
|
None => ColourRgbF::from_named(NamedColour::Black),
|
||||||
Some(intersection_info) => integrator.integrate(&sampler, &intersection_info),
|
Some(intersection_info) => integrator.integrate(&sampler, &intersection_info),
|
||||||
};
|
};
|
||||||
let mut locked_image = output_image.lock().unwrap();
|
output_image_tile.set_colour(row, column, colour);
|
||||||
locked_image.set_colour(row, column, colour);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(tile, output_image_tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
44
src/main.rs
44
src/main.rs
|
|
@ -3,6 +3,7 @@ use rayon::prelude::*;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::pixels::PixelFormatEnum;
|
use sdl2::pixels::PixelFormatEnum;
|
||||||
|
use sdl2::rect::Rect;
|
||||||
use sdl2::render::{Canvas, Texture};
|
use sdl2::render::{Canvas, Texture};
|
||||||
use sdl2::Sdl;
|
use sdl2::Sdl;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
@ -11,21 +12,26 @@ use nalgebra::{Point3, Vector3};
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use vanrijn::camera::partial_render_scene;
|
use vanrijn::camera::partial_render_scene;
|
||||||
use vanrijn::colour::{ColourRgbF, NamedColour};
|
use vanrijn::colour::{ColourRgbF, NamedColour};
|
||||||
use vanrijn::image::{ClampingToneMapper, ImageRgbF, ImageRgbU8, ToneMapper};
|
use vanrijn::image::{ClampingToneMapper, ImageRgbU8, ToneMapper};
|
||||||
use vanrijn::materials::{LambertianMaterial, PhongMaterial, ReflectiveMaterial};
|
use vanrijn::materials::{LambertianMaterial, PhongMaterial, ReflectiveMaterial};
|
||||||
use vanrijn::mesh::load_obj;
|
use vanrijn::mesh::load_obj;
|
||||||
use vanrijn::raycasting::{Plane, Primitive, Sphere};
|
use vanrijn::raycasting::{Plane, Primitive, Sphere};
|
||||||
use vanrijn::scene::Scene;
|
use vanrijn::scene::Scene;
|
||||||
use vanrijn::util::TileIterator;
|
use vanrijn::util::{Tile, TileIterator};
|
||||||
|
|
||||||
fn update_texture(image: &ImageRgbU8, texture: &mut Texture) {
|
fn update_texture(tile: &Tile, image: &ImageRgbU8, texture: &mut Texture) {
|
||||||
texture
|
texture
|
||||||
.update(
|
.update(
|
||||||
None,
|
Rect::new(
|
||||||
|
tile.start_column as i32,
|
||||||
|
texture.query().height as i32 - (tile.start_row as i32 + tile.height() as i32),
|
||||||
|
tile.width() as u32,
|
||||||
|
tile.height() as u32,
|
||||||
|
),
|
||||||
image.get_pixel_data().as_slice(),
|
image.get_pixel_data().as_slice(),
|
||||||
(image.get_width() * ImageRgbU8::num_channels()) as usize,
|
(image.get_width() * ImageRgbU8::num_channels()) as usize,
|
||||||
)
|
)
|
||||||
|
|
@ -61,7 +67,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
image_width as u32,
|
image_width as u32,
|
||||||
image_height as u32,
|
image_height as u32,
|
||||||
)?;
|
)?;
|
||||||
let output_image = Arc::new(Mutex::new(ImageRgbF::<f64>::new(image_width, image_height)));
|
|
||||||
|
|
||||||
let scene = Arc::new(Scene {
|
let scene = Arc::new(Scene {
|
||||||
camera_location: Point3::new(-2.0, 1.0, -5.0),
|
camera_location: Point3::new(-2.0, 1.0, -5.0),
|
||||||
|
|
@ -121,38 +126,27 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let (tile_tx, tile_rx) = mpsc::channel();
|
let (tile_tx, tile_rx) = mpsc::channel();
|
||||||
let mut tile_rx = Some(tile_rx);
|
let mut tile_rx = Some(tile_rx);
|
||||||
|
|
||||||
let output_image_workers = Arc::clone(&output_image);
|
|
||||||
let worker_boss = std::thread::spawn(move || {
|
let worker_boss = std::thread::spawn(move || {
|
||||||
TileIterator::new(image_width as usize, image_height as usize, 16)
|
TileIterator::new(image_width as usize, image_height as usize, 8)
|
||||||
.map(move |tile| (tile, tile_tx.clone()))
|
.map(move |tile| (tile, tile_tx.clone()))
|
||||||
.par_bridge()
|
.par_bridge()
|
||||||
.try_for_each(|(tile, tx)| {
|
.try_for_each(|(tile, tx)| {
|
||||||
let image_ptr = Arc::clone(&output_image_workers);
|
|
||||||
let scene_ptr = scene.clone();
|
let scene_ptr = scene.clone();
|
||||||
partial_render_scene(
|
let rendered_tile =
|
||||||
image_ptr,
|
partial_render_scene(scene_ptr, tile, image_height, image_width);
|
||||||
scene_ptr,
|
|
||||||
tile.start_row,
|
|
||||||
tile.end_row,
|
|
||||||
tile.start_column,
|
|
||||||
tile.end_column,
|
|
||||||
image_height,
|
|
||||||
image_width,
|
|
||||||
);
|
|
||||||
|
|
||||||
// There's nothing we can do if this fails, and we're already
|
// There's nothing we can do if this fails, and we're already
|
||||||
// at the end of the function anyway, so just ignore result.
|
// at the end of the function anyway, so just ignore result.
|
||||||
tx.send(tile).ok()
|
tx.send(rendered_tile).ok()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
'running: loop {
|
'running: loop {
|
||||||
if let Some(ref tile_rx) = tile_rx {
|
if let Some(ref tile_rx) = tile_rx {
|
||||||
for tile in tile_rx.try_iter() {
|
for (tile, tile_image) in tile_rx.try_iter() {
|
||||||
let locked_image = output_image.lock().unwrap();
|
let mut tile_image_rgbu8 = ImageRgbU8::new(tile.width(), tile.height());
|
||||||
let mut output_image_rgbu8 = ImageRgbU8::new(image_width, image_height);
|
ClampingToneMapper {}.apply_tone_mapping(&tile_image, &mut tile_image_rgbu8);
|
||||||
ClampingToneMapper {}.apply_tone_mapping(&locked_image, &mut output_image_rgbu8);
|
update_texture(&tile, &tile_image_rgbu8, &mut rendered_image_texture);
|
||||||
update_texture(&output_image_rgbu8, &mut rendered_image_texture);
|
|
||||||
canvas.copy(&rendered_image_texture, None, None).unwrap();
|
canvas.copy(&rendered_image_texture, None, None).unwrap();
|
||||||
canvas.present();
|
canvas.present();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use nalgebra::{Point2, Point3};
|
use nalgebra::Point3;
|
||||||
|
|
||||||
use crate::Real;
|
use crate::Real;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,15 @@ pub struct Tile {
|
||||||
pub end_row: usize,
|
pub end_row: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Tile {
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
self.end_column - self.start_column
|
||||||
|
}
|
||||||
|
pub fn height(&self) -> usize {
|
||||||
|
self.end_row - self.start_row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TileIterator {
|
pub struct TileIterator {
|
||||||
tile_size: usize,
|
tile_size: usize,
|
||||||
total_height: usize,
|
total_height: usize,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue