iterators baby

This commit is contained in:
wires 2025-05-27 22:53:44 -04:00
parent 90af446508
commit 726dded047
Signed by: wires
SSH key fingerprint: SHA256:9GtP+M3O2IivPDlw1UY872UPUuJH2gI0yG6ExBxaaiM
2 changed files with 28 additions and 19 deletions

View file

@ -41,11 +41,8 @@ impl Scene {
let by = i as u32 / width;
let mut rgb = Vector::ZERO;
// TODO: there's a way to make this more idiomatic with iterators
sampler.start_pixel(bx, by);
for _ in 0..samples {
let (offset_x, offset_y) = sampler.get_pixel_2d();
for (offset_x, offset_y, _) in sampler.pixel(bx, by, samples) {
let x = bx as f32 + offset_x;
let y = by as f32 + offset_y;
@ -55,7 +52,6 @@ impl Scene {
if let Some(h) = self.intersect(self.camera.ray(cx, cy)) {
rgb += h.normal.normalize() * 0.5 + Vector::new(0.5, 0.5, 0.5);
}
sampler.next_sample();
}
rgb /= samples as f32;

View file

@ -47,8 +47,13 @@ impl Sampler {
}
}
pub fn start_pixel(&mut self, x: u32, y: u32) {
let mut index = 0;
pub fn pixel(
&mut self,
x: u32,
y: u32,
samples: u32,
) -> impl Iterator<Item = (f32, f32, Sample)> {
let mut base = 0;
let sample_stride = self.y_scale as u32 * self.x_scale as u32;
if sample_stride > 1 {
@ -58,24 +63,32 @@ impl Sampler {
let x_offset = inverse_radical_inverse(mx, 2, self.x_exponent as u32);
let y_offset = inverse_radical_inverse(my, 3, self.y_exponent as u32);
index += x_offset * (sample_stride / self.x_scale as u32) * self.x_inverse as u32;
index += y_offset * (sample_stride / self.y_scale as u32) * self.y_inverse as u32;
base += x_offset * (sample_stride / self.x_scale as u32) * self.x_inverse as u32;
base += y_offset * (sample_stride / self.y_scale as u32) * self.y_inverse as u32;
index %= sample_stride;
base %= sample_stride;
}
self.index = index;
(0..samples).map(move |i| {
let index = base + i * sample_stride;
let x_offset = radical_inverse(0, index >> self.x_exponent);
let y_offset = radical_inverse(1, index / self.y_scale as u32);
(x_offset, y_offset, Sample::new(index))
})
}
}
pub fn next_sample(&mut self) {
self.index += self.x_scale as u32 * self.y_scale as u32;
}
pub struct Sample {
index: u32,
dimension: u32,
}
pub fn get_pixel_2d(&self) -> (f32, f32) {
(
radical_inverse(0, self.index >> self.x_exponent),
radical_inverse(1, self.index / self.y_scale as u32),
)
impl Sample {
fn new(index: u32) -> Self {
Self {
index,
dimension: 2,
}
}
pub fn get_1d(&mut self) -> f32 {