I'm trying to use parallelization in a small raytracer I'm implementing.
The idea is that I generate a image pixel by pixel using a function cast_ray()
, so I would like to spawn a new thread for each pixel to speed up calculation.
Basically, I am computing an 2D array of a given size. I uses Messages to update an array with the color values.
My renderer function looks like this (I deleted some parts for clarity):
pub fn render_parallel(scene: Scene) -> Vec<Vec<(u8, u8, u8)>> {
// A small 100x100 2D array
let mut image = vec![vec![(0, 0, 0); 100]; 100];
let (tx, rx) = mpsc::channel();
for x in -50..50 {
for y in -50..50 {
// Clone the message emitter
let tx_cell = tx.clone();
// Spawn a new thread for the pixel
thread::spawn(move || {
let ray = ... // A new ray from the camera ;
let color = cast_ray(
&ray,
&scene);
// Send the coordinates & values to the receiver
tx_cell.send((
((24 - y) as usize, (25 + x) as usize),
(color.r, color.g, color.b)))
.unwrap();
});
}
}
for ((i, j), (r, g, b)) in rx {
image[i][j] = (r, g, b)
}
image
}
pub struct Scene {
pub primitives: Vec<Box<dyn Primitive + Sync>>,
pub lights: Vec<Box<dyn Light + Sync>>,
}
pub trait Primitive : Send + Sync {
// Some functions...
}
pub trait Light: Send + Sync {
// Some functions...
}
The thing is, it doesn't work, and Rust is throwing me the following error :
413 | pub fn render_parallel(scene: Scene) -> Vec<Vec<(u8, u8, u8)>>{
| ----- move occurs because `scene` has type `Scene`, which does not implement the `Copy` trait
...
421 | thread::spawn(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
...
428 | &scene,
| ----- use occurs due to use in closure
I don't understand why the value is moved when I'm only using a reference to it.
My other version of render()
without using threads is the same as above, without the tx
, rx
and thread::spawn()
and doesn't run into any issue, which confuses me more.
How can I use the scene
variable in multiple simultaneous closures (if I'm understanding the problem correctly)?