-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create SamplerTrait and two Samplers: blue noise and random
- Loading branch information
Showing
10 changed files
with
275 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod draw_cpu; | ||
pub mod sampler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use std::fmt::Display; | ||
|
||
use clap::ValueEnum; | ||
use clovers::{wavelength::Wavelength, Float, Vec2}; | ||
|
||
pub mod blue; | ||
pub mod random; | ||
|
||
pub trait SamplerTrait<'scene> { | ||
// TODO: better types | ||
fn sample(&mut self, i: i32, j: i32, index: i32) -> Sample; | ||
} | ||
|
||
/// A collection of random values to be used for each sample. Returned as a struct to ensure the correct sampling order for the underlying source of randomness. | ||
pub struct Sample { | ||
/// Intra-pixel x,y offset. Used for antialiasing. | ||
pub pixel_offset: Vec2, | ||
/// The x,y offset used in the lens equations for aperture / depth-of-field simulation | ||
pub lens_offset: Vec2, | ||
/// The time of the ray, in range 0..1 | ||
pub time: Float, | ||
/// Wavelength of the ray | ||
pub wavelength: Wavelength, | ||
} | ||
|
||
#[derive(Clone, Debug, PartialEq, ValueEnum)] | ||
pub enum Sampler { | ||
Blue, | ||
Random, | ||
} | ||
|
||
impl Display for Sampler { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let s = match self { | ||
Sampler::Blue => "blue", | ||
Sampler::Random => "random", | ||
}; | ||
write!(f, "{s}") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use clovers::{wavelength::sample_wavelength, Float, RenderOpts, Vec2}; | ||
|
||
use super::{Sample, SamplerTrait}; | ||
|
||
pub struct BlueSampler { | ||
get: fn(i32, i32, i32, i32) -> Float, | ||
} | ||
|
||
impl<'scene> BlueSampler { | ||
pub fn new(opts: &'scene RenderOpts) -> Self { | ||
let get = match opts.samples { | ||
1 => blue_sample_spp1, | ||
2 => blue_sample_spp2, | ||
4 => blue_sample_spp4, | ||
8 => blue_sample_spp8, | ||
16 => blue_sample_spp16, | ||
32 => blue_sample_spp32, | ||
64 => blue_sample_spp64, | ||
128 => blue_sample_spp128, | ||
256 => blue_sample_spp256, | ||
_ => unimplemented!( | ||
"blue sampler only supports sample-per-pixel counts that are powers of two of and up to 256" | ||
), | ||
}; | ||
Self { get } | ||
} | ||
} | ||
|
||
impl<'scene> SamplerTrait<'scene> for BlueSampler { | ||
fn sample(&mut self, i: i32, j: i32, index: i32) -> Sample { | ||
let pixel_offset = Vec2::new((self.get)(i, j, index, 0), (self.get)(i, j, index, 1)); | ||
let lens_offset = Vec2::new((self.get)(i, j, index, 2), (self.get)(i, j, index, 3)); | ||
let time = (self.get)(i, j, index, 4); | ||
// TODO: verify uniformity & correctness for math? | ||
let wavelength = sample_wavelength((self.get)(i, j, index, 5)); | ||
|
||
Sample { | ||
pixel_offset, | ||
lens_offset, | ||
time, | ||
wavelength, | ||
} | ||
} | ||
} | ||
|
||
macro_rules! define_blue_sampler { | ||
($spp:ident) => { | ||
::paste::paste! { | ||
pub fn [<blue_sample_ $spp>]( | ||
mut pixel_i: i32, | ||
mut pixel_j: i32, | ||
mut sample_index: i32, | ||
mut sample_dimension: i32) -> Float { | ||
use blue_noise_sampler::$spp::*; | ||
|
||
// Adapted from <https://dl.acm.org/doi/10.1145/3306307.3328191> and <https://github.com/Jasper-Bekkers/blue-noise-sampler> | ||
|
||
// wrap arguments | ||
pixel_i &= 127; | ||
pixel_j &= 127; | ||
sample_index &= 255; | ||
sample_dimension &= 255; | ||
|
||
// xor index based on optimized ranking | ||
// jb: 1spp blue noise has all 0 in g_blueNoiseRankingTile so we can skip the load | ||
let index = sample_dimension + (pixel_i + pixel_j * 128) * 8; | ||
let index = index as usize; | ||
let ranked_sample_index = sample_index ^ RANKING_TILE[index]; | ||
|
||
// fetch value in sequence | ||
let index = sample_dimension + ranked_sample_index * 256; | ||
let index = index as usize; | ||
let value = SOBOL[index]; | ||
|
||
// If the dimension is optimized, xor sequence value based on optimized scrambling | ||
let index = (sample_dimension % 8) + (pixel_i + pixel_j * 128) * 8; | ||
let index = index as usize; | ||
let value = value ^ SCRAMBLING_TILE[index]; | ||
|
||
// convert to float and return | ||
let v: Float = (0.5 + value as Float) / 256.0; | ||
v | ||
} | ||
} | ||
}; | ||
} | ||
|
||
define_blue_sampler!(spp1); | ||
define_blue_sampler!(spp2); | ||
define_blue_sampler!(spp4); | ||
define_blue_sampler!(spp8); | ||
define_blue_sampler!(spp16); | ||
define_blue_sampler!(spp32); | ||
define_blue_sampler!(spp64); | ||
define_blue_sampler!(spp128); | ||
define_blue_sampler!(spp256); |
Oops, something went wrong.