Skip to content

Instantly share code, notes, and snippets.

@Nyrox
Created September 27, 2018 10:01
Show Gist options
  • Save Nyrox/febc7008efdf91649837761f35e651e5 to your computer and use it in GitHub Desktop.
Save Nyrox/febc7008efdf91649837761f35e651e5 to your computer and use it in GitHub Desktop.
pub fn render_tiled(scene: Scene, settings: Settings) -> mpsc::Receiver<super::Tile> {
let queue = Arc::new(MsQueue::new());
let (sender, receiver) = mpsc::channel();
// Split the backbuffer into tiles and push them into the queue
{
let mut x = 0;
let mut y = 0;
'gen_tiles: loop {
let tile_min = (x, y);
let tile_max = (
(x + tile_size.0).min(self.width - 1),
(y + tile_size.1).min(self.height - 1),
);
let width = tile_max.0 - tile_min.0;
let height = tile_max.1 - tile_min.1;
queue.push(super::Tile {
sample_count: 0,
left: tile_min.0,
top: tile_min.1,
width,
height,
data: vec![Vector3::new(0.0, 0.0, 0.0); width * height],
});
y += tile_size.1;
if y >= self.height {
y = 0;
x += tile_size.0;
}
if x >= self.width {
break 'gen_tiles;
}
}
}
for i in 0..settings.worker_count {
let queue = queue.clone();
let sender = sender.clone();
// We clone both our scene and settings
// This simplifies implementation
let context = TraceContext {
scene: scene.clone(),
settings: settings.clone(),
};
thread::spawn(move || loop {
let tile = queue.try_pop()?;
for y in tile.top..(tile.top + tile.height) {
for x in tile.left..(tile.left + tile.width) {
let primary = generate_primary_ray(x, y, context.settings.camera_settings);
let sample = trace(primary, &context);
// Map the global pixel indices to the local tile buffer and store the sample
tile.data[(x - tile.left) + (y - tile.top) * tile.width] += sample;
}
}
tile.sample_count += 1;
// Check if we are done
if tile.sample_count == context.settings.sample_count {
sender.send(tile);
return Ok(());
}
// Check if we want to send our tile down the pipe
if context.settings.samples_per_iteration != 0
&& tile.sample_count % context.settings.samples_per_iteration == 0
{
sender.send(tile);
}
queue.push(tile);
});
}
return receiver;
}
struct TraceContext {
pub scene: Scene,
pub settings: Settings,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment