81 lines
2.2 KiB
Rust
81 lines
2.2 KiB
Rust
use crate::Float;
|
|
use crate::core::geometry::{Point2f, VectorLike};
|
|
use crate::core::texture::{
|
|
FloatTexture, SpectrumTexture, TextureEvalContext, TextureMapping2D,
|
|
};
|
|
use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths};
|
|
use crate::utils::Ptr;
|
|
use crate::utils::math::square;
|
|
use crate::utils::noise::noise_2d;
|
|
use num_traits::Float as NumFloat;
|
|
|
|
fn inside_polka_dot(st: Point2f) -> bool {
|
|
let s_cell = (st[0] + 0.5).floor();
|
|
let t_cell = (st[1] + 0.5).floor();
|
|
if noise_2d(s_cell + 0.5, t_cell + 0.5) > 0. {
|
|
let radius = 0.35;
|
|
let max_shift = 0.5 + radius;
|
|
let s_center = s_cell + max_shift * noise_2d(s_cell + 1.5, t_cell + 2.8);
|
|
let t_center = t_cell + max_shift * noise_2d(s_cell + 4.5, t_cell + 9.8);
|
|
let dst = st - Point2f::new(s_center, t_center);
|
|
if dst.norm_squared() < square(radius) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct FloatDotsTexture {
|
|
pub mapping: TextureMapping2D,
|
|
pub outside_dot: Ptr<FloatTexture>,
|
|
pub inside_dot: Ptr<FloatTexture>,
|
|
}
|
|
|
|
impl FloatDotsTexture {
|
|
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
|
|
let c = self.mapping.map(ctx);
|
|
let target_texture = if inside_polka_dot(c.st) {
|
|
self.inside_dot
|
|
} else {
|
|
self.outside_dot
|
|
};
|
|
|
|
if !target_texture.is_null() {
|
|
target_texture.evaluate(ctx)
|
|
} else {
|
|
0.0
|
|
}
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub struct SpectrumDotsTexture {
|
|
pub mapping: TextureMapping2D,
|
|
pub outside_dot: Ptr<SpectrumTexture>,
|
|
pub inside_dot: Ptr<SpectrumTexture>,
|
|
}
|
|
|
|
impl SpectrumDotsTexture {
|
|
pub fn evaluate(
|
|
&self,
|
|
ctx: &TextureEvalContext,
|
|
lambda: &SampledWavelengths,
|
|
) -> SampledSpectrum {
|
|
let c = self.mapping.map(ctx);
|
|
|
|
let target_texture = if inside_polka_dot(c.st) {
|
|
self.inside_dot
|
|
} else {
|
|
self.outside_dot
|
|
};
|
|
|
|
if !target_texture.is_null() {
|
|
target_texture.evaluate(ctx, lambda)
|
|
} else {
|
|
SampledSpectrum::new(0.0)
|
|
}
|
|
}
|
|
}
|