Forgot to actually implement FilterTrait
This commit is contained in:
parent
75655ed774
commit
cc557dfa50
7 changed files with 44 additions and 32 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::core::camera::CameraTransform;
|
use crate::core::camera::CameraTransform;
|
||||||
use crate::core::color::{MatrixMulColor, RGB, SRGB, XYZ, white_balance};
|
use crate::core::color::{MatrixMulColor, RGB, SRGB, XYZ, white_balance};
|
||||||
use crate::core::filter::Filter;
|
use crate::core::filter::{Filter, FilterTrait};
|
||||||
use crate::core::geometry::{
|
use crate::core::geometry::{
|
||||||
Bounds2f, Bounds2fi, Bounds2i, Normal3f, Point2f, Point2i, Point3f, Tuple, Vector2f, Vector2fi,
|
Bounds2f, Bounds2fi, Bounds2i, Normal3f, Point2f, Point2i, Point3f, Tuple, Vector2f, Vector2fi,
|
||||||
Vector2i, Vector3f,
|
Vector2i, Vector3f,
|
||||||
|
|
@ -90,7 +90,7 @@ impl RGBFilm {
|
||||||
pub fn get_sensor(&self) -> &PixelSensor {
|
pub fn get_sensor(&self) -> &PixelSensor {
|
||||||
#[cfg(not(target_os = "cuda"))]
|
#[cfg(not(target_os = "cuda"))]
|
||||||
{
|
{
|
||||||
if self.sensor.is_null() {
|
if self.film.sensor.is_null() {
|
||||||
panic!(
|
panic!(
|
||||||
"FilmBase error: PixelSensor pointer is null. This should have been checked during construction."
|
"FilmBase error: PixelSensor pointer is null. This should have been checked during construction."
|
||||||
);
|
);
|
||||||
|
|
@ -208,7 +208,7 @@ struct GBufferPixel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Copy)]
|
||||||
#[cfg_attr(target_os = "cuda", derive(Copy, Clone))]
|
#[cfg_attr(target_os = "cuda", derive(Copy, Clone))]
|
||||||
pub struct GBufferFilm {
|
pub struct GBufferFilm {
|
||||||
pub base: FilmBase,
|
pub base: FilmBase,
|
||||||
|
|
@ -570,7 +570,7 @@ impl VisibleSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default, Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct FilmBase {
|
pub struct FilmBase {
|
||||||
pub full_resolution: Point2i,
|
pub full_resolution: Point2i,
|
||||||
pub pixel_bounds: Bounds2i,
|
pub pixel_bounds: Bounds2i,
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ impl FilterSampler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
pub trait FilterTrait {
|
pub trait FilterTrait {
|
||||||
fn radius(&self) -> Vector2f;
|
fn radius(&self) -> Vector2f;
|
||||||
fn evaluate(&self, p: Point2f) -> Float;
|
fn evaluate(&self, p: Point2f) -> Float;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::Float;
|
use crate::Float;
|
||||||
use crate::core::filter::FilterSample;
|
use crate::core::filter::{FilterSample, FilterTrait};
|
||||||
use crate::core::geometry::{Point2f, Vector2f};
|
use crate::core::geometry::{Point2f, Vector2f};
|
||||||
use crate::utils::math::lerp;
|
use crate::utils::math::lerp;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct BoxFilter {
|
pub struct BoxFilter {
|
||||||
pub radius: Vector2f,
|
pub radius: Vector2f,
|
||||||
}
|
}
|
||||||
|
|
@ -12,12 +13,13 @@ impl BoxFilter {
|
||||||
pub fn new(radius: Vector2f) -> Self {
|
pub fn new(radius: Vector2f) -> Self {
|
||||||
Self { radius }
|
Self { radius }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn radius(&self) -> Vector2f {
|
impl FilterTrait for BoxFilter {
|
||||||
|
fn radius(&self) -> Vector2f {
|
||||||
self.radius
|
self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, p: Point2f) -> Float {
|
fn evaluate(&self, p: Point2f) -> Float {
|
||||||
if p.x().abs() <= self.radius.x() && p.y().abs() <= self.radius.y() {
|
if p.x().abs() <= self.radius.x() && p.y().abs() <= self.radius.y() {
|
||||||
1.
|
1.
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -25,11 +27,11 @@ impl BoxFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integral(&self) -> Float {
|
fn integral(&self) -> Float {
|
||||||
(2.0 * self.radius.x()) * (2.0 * self.radius.y())
|
(2.0 * self.radius.x()) * (2.0 * self.radius.y())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, u: Point2f) -> FilterSample {
|
fn sample(&self, u: Point2f) -> FilterSample {
|
||||||
let p = Point2f::new(
|
let p = Point2f::new(
|
||||||
lerp(u[0], -self.radius.x(), self.radius.x()),
|
lerp(u[0], -self.radius.x(), self.radius.x()),
|
||||||
lerp(u[1], -self.radius.y(), self.radius.y()),
|
lerp(u[1], -self.radius.y(), self.radius.y()),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::Float;
|
use crate::Float;
|
||||||
use crate::core::filter::{FilterSample, FilterSampler};
|
use crate::core::filter::{FilterSample, FilterSampler, FilterTrait};
|
||||||
use crate::core::geometry::{Point2f, Vector2f};
|
use crate::core::geometry::{Point2f, Vector2f};
|
||||||
use crate::utils::math::{gaussian, gaussian_integral};
|
use crate::utils::math::{gaussian, gaussian_integral};
|
||||||
|
|
||||||
|
|
@ -32,24 +32,26 @@ impl GaussianFilter {
|
||||||
sampler,
|
sampler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn radius(&self) -> Vector2f {
|
impl FilterTrait for GaussianFilter {
|
||||||
|
fn radius(&self) -> Vector2f {
|
||||||
self.radius
|
self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, p: Point2f) -> Float {
|
fn evaluate(&self, p: Point2f) -> Float {
|
||||||
(gaussian(p.x(), 0.0, self.sigma) - self.exp_x).max(0.0)
|
(gaussian(p.x(), 0.0, self.sigma) - self.exp_x).max(0.0)
|
||||||
* (gaussian(p.y(), 0.0, self.sigma) - self.exp_y).max(0.0)
|
* (gaussian(p.y(), 0.0, self.sigma) - self.exp_y).max(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integral(&self) -> Float {
|
fn integral(&self) -> Float {
|
||||||
(gaussian_integral(-self.radius.x(), self.radius.x(), 0.0, self.sigma)
|
(gaussian_integral(-self.radius.x(), self.radius.x(), 0.0, self.sigma)
|
||||||
- 2.0 * self.radius.x() * self.exp_x)
|
- 2.0 * self.radius.x() * self.exp_x)
|
||||||
* (gaussian_integral(-self.radius.y(), self.radius.y(), 0.0, self.sigma)
|
* (gaussian_integral(-self.radius.y(), self.radius.y(), 0.0, self.sigma)
|
||||||
- 2.0 * self.radius.y() * self.exp_y)
|
- 2.0 * self.radius.y() * self.exp_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, u: Point2f) -> FilterSample {
|
fn sample(&self, u: Point2f) -> FilterSample {
|
||||||
self.sampler.sample(u)
|
self.sampler.sample(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::Float;
|
use crate::Float;
|
||||||
use crate::core::filter::{FilterSample, FilterSampler};
|
use crate::core::filter::{FilterSample, FilterSampler, FilterTrait};
|
||||||
use crate::core::geometry::{Point2f, Vector2f};
|
use crate::core::geometry::{Point2f, Vector2f};
|
||||||
use crate::utils::math::{lerp, windowed_sinc};
|
use crate::utils::math::{lerp, windowed_sinc};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
@ -24,17 +24,19 @@ impl LanczosSincFilter {
|
||||||
sampler,
|
sampler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn radius(&self) -> Vector2f {
|
impl FilterTrait for LanczosSincFilter {
|
||||||
|
fn radius(&self) -> Vector2f {
|
||||||
self.radius
|
self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, p: Point2f) -> Float {
|
fn evaluate(&self, p: Point2f) -> Float {
|
||||||
windowed_sinc(p.x(), self.radius.x(), self.tau)
|
windowed_sinc(p.x(), self.radius.x(), self.tau)
|
||||||
* windowed_sinc(p.y(), self.radius.y(), self.tau)
|
* windowed_sinc(p.y(), self.radius.y(), self.tau)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integral(&self) -> Float {
|
fn integral(&self) -> Float {
|
||||||
let sqrt_samples = 64;
|
let sqrt_samples = 64;
|
||||||
let n_samples = sqrt_samples * sqrt_samples;
|
let n_samples = sqrt_samples * sqrt_samples;
|
||||||
let area = (2.0 * self.radius.x()) * (2.0 * self.radius.y());
|
let area = (2.0 * self.radius.x()) * (2.0 * self.radius.y());
|
||||||
|
|
@ -57,7 +59,7 @@ impl LanczosSincFilter {
|
||||||
sum / n_samples as Float * area
|
sum / n_samples as Float * area
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, u: Point2f) -> FilterSample {
|
fn sample(&self, u: Point2f) -> FilterSample {
|
||||||
self.sampler.sample(u)
|
self.sampler.sample(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::Float;
|
use crate::Float;
|
||||||
use crate::core::filter::{FilterSample, FilterSampler};
|
use crate::core::filter::{FilterSample, FilterSampler, FilterTrait};
|
||||||
use crate::core::geometry::{Point2f, Vector2f};
|
use crate::core::geometry::{Point2f, Vector2f};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct MitchellFilter {
|
pub struct MitchellFilter {
|
||||||
pub radius: Vector2f,
|
pub radius: Vector2f,
|
||||||
pub b: Float,
|
pub b: Float,
|
||||||
|
|
@ -47,21 +48,23 @@ impl MitchellFilter {
|
||||||
fn mitchell_1d(&self, x: Float) -> Float {
|
fn mitchell_1d(&self, x: Float) -> Float {
|
||||||
Self::mitchell_1d_eval(self.b, self.c, x)
|
Self::mitchell_1d_eval(self.b, self.c, x)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn radius(&self) -> Vector2f {
|
impl FilterTrait for MitchellFilter {
|
||||||
|
fn radius(&self) -> Vector2f {
|
||||||
self.radius
|
self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, p: Point2f) -> Float {
|
fn evaluate(&self, p: Point2f) -> Float {
|
||||||
self.mitchell_1d(2.0 * p.x() / self.radius.x())
|
self.mitchell_1d(2.0 * p.x() / self.radius.x())
|
||||||
* self.mitchell_1d(2.0 * p.y() / self.radius.y())
|
* self.mitchell_1d(2.0 * p.y() / self.radius.y())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integral(&self) -> Float {
|
fn integral(&self) -> Float {
|
||||||
self.radius.x() * self.radius.y() / 4.0
|
self.radius.x() * self.radius.y() / 4.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, u: Point2f) -> FilterSample {
|
fn sample(&self, u: Point2f) -> FilterSample {
|
||||||
self.sampler.sample(u)
|
self.sampler.sample(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::Float;
|
use crate::Float;
|
||||||
use crate::core::filter::FilterSample;
|
use crate::core::filter::{FilterSample, FilterTrait};
|
||||||
use crate::core::geometry::{Point2f, Vector2f};
|
use crate::core::geometry::{Point2f, Vector2f};
|
||||||
use crate::utils::math::sample_tent;
|
use crate::utils::math::sample_tent;
|
||||||
|
|
||||||
|
|
@ -13,20 +13,22 @@ impl TriangleFilter {
|
||||||
pub fn new(radius: Vector2f) -> Self {
|
pub fn new(radius: Vector2f) -> Self {
|
||||||
Self { radius }
|
Self { radius }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn radius(&self) -> Vector2f {
|
impl FilterTrait for TriangleFilter {
|
||||||
|
fn radius(&self) -> Vector2f {
|
||||||
self.radius
|
self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, p: Point2f) -> Float {
|
fn evaluate(&self, p: Point2f) -> Float {
|
||||||
(self.radius.x() - p.x().abs()).max(0.0) * (self.radius.y() - p.y().abs()).max(0.0)
|
(self.radius.x() - p.x().abs()).max(0.0) * (self.radius.y() - p.y().abs()).max(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn integral(&self) -> Float {
|
fn integral(&self) -> Float {
|
||||||
self.radius.x().powi(2) * self.radius.y().powi(2)
|
self.radius.x().powi(2) * self.radius.y().powi(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, u: Point2f) -> FilterSample {
|
fn sample(&self, u: Point2f) -> FilterSample {
|
||||||
let p = Point2f::new(
|
let p = Point2f::new(
|
||||||
sample_tent(u[0], self.radius.x()),
|
sample_tent(u[0], self.radius.x()),
|
||||||
sample_tent(u[1], self.radius.y()),
|
sample_tent(u[1], self.radius.y()),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue