Control those Uniform distributions
I wanted to make the Uniform's into `const`s that live at the global scope. Rust can do global const, but the `Uniform::new()` function can't be used in that context. As an intermediate to a *helpful* solution, I've just pushed them into a struct. One less parameter to name even though it's the same stuff. The compiler should be smart enough to hoist the initialization outside the function and leave them around, but maybe not. After all, the function isn't defined to work in such a way with the `const` keyword :v
This commit is contained in:
30
src/main.rs
30
src/main.rs
@@ -24,8 +24,8 @@ fn main() {
|
|||||||
// image
|
// image
|
||||||
let aspect_ratio = 3.0 / 2.0;
|
let aspect_ratio = 3.0 / 2.0;
|
||||||
let image = (
|
let image = (
|
||||||
400,
|
1920,
|
||||||
(400.0 / aspect_ratio) as i32
|
(1920.0 / aspect_ratio) as i32
|
||||||
);
|
);
|
||||||
let samples_per_pixel: u32 = 10;
|
let samples_per_pixel: u32 = 10;
|
||||||
let max_depth = 50;
|
let max_depth = 50;
|
||||||
@@ -66,7 +66,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
thread::scope(|s| {
|
thread::scope(|s| {
|
||||||
let (mut dispatcher, scanline_receiver) = thread_utils::Dispatcher::new(&small_rng, 4);
|
let (mut dispatcher, scanline_receiver) = thread_utils::Dispatcher::new(&small_rng, 12);
|
||||||
|
|
||||||
s.spawn(move || {
|
s.spawn(move || {
|
||||||
for y in (0..image.1).rev() {
|
for y in (0..image.1).rev() {
|
||||||
@@ -147,19 +147,31 @@ pub struct RenderContext{
|
|||||||
camera: Camera,
|
camera: Camera,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_line(y: i32, small_rng: &mut SmallRng, context: RenderContext) -> Vec<Vec3> {
|
pub struct DistributionContianer {
|
||||||
|
distrib_zero_one: Uniform<f32>,
|
||||||
|
distrib_plusminus_one: Uniform<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DistributionContianer {
|
||||||
|
fn new() -> Self {
|
||||||
|
DistributionContianer {
|
||||||
|
distrib_zero_one: Uniform::new(0.0, 1.0),
|
||||||
|
distrib_plusminus_one: Uniform::new(-1.0, 1.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_line(y: i32, small_rng: &mut SmallRng, context: RenderContext, distr: &DistributionContianer) -> Vec<Vec3> {
|
||||||
//TODO: Ensure that the compiler hoists the distribution's out as constants
|
//TODO: Ensure that the compiler hoists the distribution's out as constants
|
||||||
// else, do so manually
|
// else, do so manually
|
||||||
let distrib_zero_one = Uniform::new(0.0, 1.0);
|
|
||||||
let distrib_plusminus_one = Uniform::new(-1.0, 1.0);
|
|
||||||
(0..context.image.0).map(|x| {
|
(0..context.image.0).map(|x| {
|
||||||
(0..context.samples_per_pixel).into_iter().fold(
|
(0..context.samples_per_pixel).into_iter().fold(
|
||||||
Vec3::zero(),
|
Vec3::zero(),
|
||||||
|color, _sample| {
|
|color, _sample| {
|
||||||
let u = ((x as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.0 - 1) as f32);
|
let u = ((x as f32) + small_rng.sample(distr.distrib_zero_one)) / ((context.image.0 - 1) as f32);
|
||||||
let v = ((y as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.1 - 1) as f32);
|
let v = ((y as f32) + small_rng.sample(distr.distrib_zero_one)) / ((context.image.1 - 1) as f32);
|
||||||
let ray = context.camera.get_ray(u, v, small_rng);
|
let ray = context.camera.get_ray(u, v, small_rng);
|
||||||
color + ray_color(ray, &context.world, context.max_depth, small_rng, distrib_plusminus_one)
|
color + ray_color(ray, &context.world, context.max_depth, small_rng, distr.distrib_plusminus_one)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}).collect()
|
}).collect()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
use crate::RenderContext;
|
use crate::RenderContext;
|
||||||
use crate::Vec3;
|
use crate::Vec3;
|
||||||
use crate::render_line;
|
use crate::{render_line, DistributionContianer};
|
||||||
|
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@@ -76,7 +76,7 @@ impl Dispatcher {
|
|||||||
|
|
||||||
let mut srng = srng.clone();
|
let mut srng = srng.clone();
|
||||||
let threads_result_tx = render_tx.clone();
|
let threads_result_tx = render_tx.clone();
|
||||||
|
let distribs = DistributionContianer::new();
|
||||||
let thread_handle = thread::spawn(move || {
|
let thread_handle = thread::spawn(move || {
|
||||||
while let Ok(job) = command_rx.recv() {
|
while let Ok(job) = command_rx.recv() {
|
||||||
match job {
|
match job {
|
||||||
@@ -84,7 +84,7 @@ impl Dispatcher {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RenderCommand::Line { line_num, context } => {
|
RenderCommand::Line { line_num, context } => {
|
||||||
let line = render_line(line_num, &mut srng, context);
|
let line = render_line(line_num, &mut srng, context, &distribs);
|
||||||
let result = RenderResult { line_num, line };
|
let result = RenderResult { line_num, line };
|
||||||
threads_result_tx.send(result).unwrap();
|
threads_result_tx.send(result).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user