use geometry::prelude::*;
use filming;
pub trait Sampler: Clone + Sync + Send
{
fn start_pixel(&mut self, p: Point2<u32>);
fn next(&mut self) -> Float;
#[inline]
fn next_2d(&mut self) -> Point2f {
Point2f::new(self.next(), self.next())
}
#[inline]
fn get_camera_sample(&mut self, idx: Point2<u32>) -> filming::SampleInfo {
filming::SampleInfo{
pfilm: self.next_2d() + idx.cast().to_vec(),
plens: self.next_2d(),
}
}
#[inline]
fn get_light_sample(&mut self) -> filming::SampleInfo {
filming::SampleInfo{
pfilm: self.next_2d(),
plens: self.next_2d(),
}
}
fn request(&mut self, buf: &mut [Float]) {
for f in buf.iter_mut() {
*f = self.next();
}
}
fn request_2d(&mut self, buf: &mut [Point2f]) {
for p in buf.iter_mut() {
*p = self.next_2d();
}
}
#[inline]
fn round_count(&self, n: usize) -> usize {
n
}
fn sample_per_pixel(&self) -> usize;
fn next_sample(&mut self) -> bool;
fn set_sample_index(&mut self, idx: usize) -> bool;
}
pub trait Filter: Send + Sync {
fn radius(&self) -> Vector2f;
#[inline]
fn support(&self) -> BBox2f {
let p = self.radius();
BBox2f::new(Point2f::from_vec(p), Point2f::from_vec(-p))
}
unsafe fn evaluate_unsafe(&self, p: Point2f) -> Float;
#[inline]
fn evaluate(&self, p: Point2f) -> Float {
let bounding = self.support();
if bounding.contain(p) {unsafe {
self.evaluate_unsafe(p)
}} else {
0.0 as Float
}
}
}
#[inline]
pub fn sample_uniform_hemisphere(u: Point2f) -> Vector3f {
let costheta = u.x;
let sintheta = (1.0 as Float - costheta).max(0.0 as Float).sqrt();
let phi = 2.0 as Float * float::pi() * u.y;
Vector3f::new(sintheta*phi.cos(), sintheta*phi.sin(), costheta)
}
#[inline]
pub fn pdf_uniform_hemisphere() -> Float {
0.5 as Float * float::frac_1_pi()
}
#[inline]
pub fn sample_uniform_sphere(u: Point2f) -> Vector3f {
let costheta = 1.0 as Float - 2.0 as Float * u.x;
let sintheta = (1.0 as Float - costheta).max(0.0 as Float).sqrt();
let phi = 2.0 as Float * float::pi() * u.y;
Vector3f::new(sintheta*phi.cos(), sintheta*phi.sin(), costheta)
}
#[inline]
pub fn pdf_uniform_sphere() -> Float {
0.25 as Float * float::frac_1_pi()
}
#[inline]
pub fn sample_concentric_disk(u: Point2f) -> Point2f {
let u = (2.0 as Float * u) - Point2f::new(1.0 as Float, 1.0 as Float);
if u.x == 0.0 as Float && u.y == 0.0 as Float {
Point2f::new(0.0 as Float, 0.0 as Float)
} else {
let (r, theta) = if u.x.abs() > u.y.abs() {
(u.x, float::frac_pi_4() * (u.y/u.x))
} else {
(u.y, float::frac_pi_2() - float::frac_pi_4() * (u.x/u.y))
};
r * Point2f::new(theta.cos(), theta.sin())
}
}
#[inline]
pub fn pdf_concentric_disk() -> Float {
float::pi()
}
#[inline]
pub fn sample_uniform_disk(u: Point2f) -> Point2f {
let r = u.x.sqrt();
let theta = 2.0 as Float * float::pi() * u.y;
Point2f::new(r*theta.cos(), r*theta.sin())
}
#[inline]
pub fn pdf_uniform_disk() -> Float {
float::pi()
}
#[inline]
pub fn sample_cosw_hemisphere(u: Point2f) -> Vector3f {
let d = sample_concentric_disk(u);
let z = (1.0 as Float - d.x*d.x - d.y*d.y).abs().sqrt();
Vector3f::new(d.x, d.y, z)
}
#[inline]
pub fn pdf_cosw_hemisphere(cos_theta: Float) -> Float {
cos_theta * float::frac_1_pi()
}
#[inline]
pub fn sample_uniform_cone(u: Point2f, cos_max: Float) -> Vector3f {
let costheta = (1.0 as Float - u.x) + u.x * cos_max;
let sintheta = (1.0 as Float - costheta*costheta).sqrt();
let phi = u.y * (2.0 as Float * float::pi());
Vector3f::new(sintheta*phi.cos(), sintheta*phi.sin(), costheta)
}
#[inline]
pub fn pdf_uniform_cone(cos_max: Float) -> Float {
1.0 as Float / ((1.0 as Float - cos_max) * 2.0 as Float * float::pi())
}
#[inline]
pub fn sample_uniform_triangle(u: Point2f) -> Vector3f {
let sqrtux = u.x.sqrt();
let x = 1.0 as Float - sqrtux;
let y = sqrtux * u.y;
Vector3f::new(x, y, 1.0 as Float - x - y)
}
#[inline]
pub fn power_heuristic(nf: usize, pdff: Float, ng: usize, pdfg: Float) -> Float {
let f = nf as Float * pdff;
let g = ng as Float * pdfg;
(f*f)/(f*f+g*g)
}
#[inline]
pub fn balance_heuristic(nf: usize, pdff: Float, ng: usize, pdfg: Float) -> Float {
let f = nf as Float * pdff;
let g = ng as Float * pdfg;
f/(f+g)
}
pub mod naive;
pub mod strata;
pub mod filters;
pub mod distribution;
pub mod prelude;
mod sink;