Release Notes for v0.8.3
2020-10-11License
Even though this is a minor release (because 0.8.x was all about improving the performance) I did change the license to be more in line with the Rust ecosystem:
Licensed under either of
- Apache License, Version 2.0,
- MIT license
at your option.
I did ask my contributors (only two so far) about this license change and they were fine with it.
There is also a
license.html
shipping with the source code now, which can be best viewed in a
browser (after cloning the
repository),
and lists the licenses of the crates rs-pbrt
currently depends on.
I used cargo-about to create that file:
cd ~/git/github/rs_pbrt
cargo about generate about.hbs > license.html
Files Changed
98 files changed, 7120 insertions(+), 4768 deletions(-)
...
Documentation
First of all the documentation style changed from:
to this (including a release number and a new color scheme):
Branches
Currently there are still some branches, but this release mainly introduced the arena branch and I hope to merge it for the next release.
The original C++ code uses Arena-Based
Allocation
in several places. I did ask questions about this
topic
on the Rust Users Forum before, but for that arena branch I
decided that I just want to collect Bsdf
and Bxdf
in vectors
and access them via an index:
impl SamplerIntegrator {
...
pub fn render(&mut self, scene: &Scene, num_threads: u8) {
...
crossbeam::scope(|scope| {
let (pixel_tx, pixel_rx) = crossbeam_channel::bounded(num_cores);
// spawn worker threads
for _ in 0..num_cores {
let pixel_tx = pixel_tx.clone();
let mut tile_sampler: Box<Sampler> = sampler.clone_with_seed(0_u64);
scope.spawn(move |_| {
let mut arena_bsdf: Vec<Bsdf> = Vec::with_capacity(128);
let mut arena_bxdf: Vec<Bxdf> = Vec::with_capacity(128);
while let Some((x, y)) = bq.next() {
...
for pixel in &tile_bounds {
...
while !done {
...
l = integrator.li(
&mut ray,
scene,
&mut tile_sampler,
&mut arena_bsdf,
&mut arena_bxdf,
0_i32,
);
...
arena_bsdf.clear();
arena_bxdf.clear();
done = !tile_sampler.start_next_sample();
}
}
// send the tile through the channel to main thread
pixel_tx
.send(film_tile)
.unwrap_or_else(|_| panic!("Failed to send tile"));
}
});
}
// spawn thread to collect pixels and render image to file
scope.spawn(move |_| {
for _ in pbr::PbIter::new(0..bq.len()) {
let film_tile = pixel_rx.recv().unwrap();
// merge image tile into _Film_
film.merge_film_tile(&film_tile);
}
});
})
.unwrap();
}
film.write_image(1.0 as Float);
}
I spare you the details, but in theory the Bsdf
and Bxdf
instances
are created while rendering, kept in both vectors, accessed via
indices until the whole vector gets freed. The hope was to speed up
the executable, but so far I did not decide if the performance is
really improving that much for all integrators and related methods.
Issues
But there were two issues (fixed in both branches - master
and
arena
):
-
For Bidirectional Path Tracing (BDPT) the C++ version did render differently from the Rust version (see issue #127). This happened somewhere after release v0.7.3. I did pinpoint the commit introducing the bug and fixed it in both branches.
-
A similar problem was never detected before regarding the Stochastic Progressive Photon Mapping (SPPM) algorithm. For the
master
branch I simply fixed the code showing up in the difference image between C++ and Rust (see issue #128). For thearena
branch the code panicked at some point, so I had to fix parts of the code which uses the arena vectors, but indexed into them incorrectly.
The End
I hope I didn't forget anything important. Have fun and enjoy the v0.8.3 release.