pbrt/src/filters/mitchell.rs

42 lines
1.2 KiB
Rust

use crate::core::filter::CreateFilterSampler;
use shared::Float;
use shared::core::filter::FilterSampler;
use shared::core::geometry::{Point2f, Vector2f};
use shared::filters::MitchellFilter;
#[derive(Clone, Debug, Device)]
#[device(name = "MitchellFilter")]
pub struct MitchellFilterHost {
pub radius: Vector2f,
pub b: Float,
pub c: Float,
#[device(flatten)]
pub sampler: FilterSampler,
}
impl MitchellFilterHost {
pub fn new(radius: Vector2f, b: Float, c: Float) -> Self {
let sampler = FilterSampler::new(radius, move |p: Point2f| {
mitchell_1d(p.x() / radius.x(), b, c) * mitchell_1d(p.y() / radius.y(), b, c)
});
Self { radius, b, c, sampler }
}
}
fn mitchell_1d(x: Float, b: Float, c: Float) -> Float {
let x = (2.0 * x).abs();
if x <= 1.0 {
((12.0 - 9.0 * b - 6.0 * c) * x * x * x
+ (-18.0 + 12.0 * b + 6.0 * c) * x * x
+ (6.0 - 2.0 * b))
/ 6.0
} else if x <= 2.0 {
((-b - 6.0 * c) * x * x * x
+ (6.0 * b + 30.0 * c) * x * x
+ (-12.0 * b - 48.0 * c) * x
+ (8.0 * b + 24.0 * c))
/ 6.0
} else {
0.0
}
}