Skip to main content

noiz/
misc_noise.rs

1//! A grab bag of miscellaneous noise functions that have no better place to be.
2
3use core::{
4    marker::PhantomData,
5    ops::{Add, Mul},
6};
7
8use bevy_math::{Curve, HasTangent, Vec2, Vec3, Vec3A, Vec4, curve::derivatives::SampleDerivative};
9
10use crate::{NoiseFunction, cells::WithGradient, rng::NoiseRng};
11
12/// A [`NoiseFunction`] that wraps an inner [`NoiseFunction`] `N` and produces values of the same type as the input with random elements sourced from `N`.
13///
14/// This is most commonly used for domain warping:
15///
16/// ```
17/// # use noiz::prelude::*;
18/// # use bevy_math::prelude::*;
19/// # use noiz::misc_noise::{RandomElements, Offset};
20/// let noise = Noise::<(Offset<RandomElements<common_noise::Value>>, common_noise::Perlin)>::default();
21/// let value = noise.sample_for::<f32>(Vec2::new(1.0, -1.0));
22/// ```
23#[derive(Default, Clone, Copy, PartialEq)]
24#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
25#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
26#[cfg_attr(feature = "debug", derive(Debug))]
27pub struct RandomElements<N>(pub N);
28
29impl<N: NoiseFunction<Vec2, Output = f32>> NoiseFunction<Vec2> for RandomElements<N> {
30    type Output = Vec2;
31
32    #[inline]
33    fn evaluate(&self, input: Vec2, seeds: &mut NoiseRng) -> Self::Output {
34        let x = self.0.evaluate(input, seeds);
35        seeds.re_seed();
36        let y = self.0.evaluate(input, seeds);
37        seeds.re_seed();
38        Vec2::new(x, y)
39    }
40}
41
42impl<N: NoiseFunction<Vec3, Output = f32>> NoiseFunction<Vec3> for RandomElements<N> {
43    type Output = Vec3;
44
45    #[inline]
46    fn evaluate(&self, input: Vec3, seeds: &mut NoiseRng) -> Self::Output {
47        let x = self.0.evaluate(input, seeds);
48        seeds.re_seed();
49        let y = self.0.evaluate(input, seeds);
50        seeds.re_seed();
51        let z = self.0.evaluate(input, seeds);
52        seeds.re_seed();
53        Vec3::new(x, y, z)
54    }
55}
56
57impl<N: NoiseFunction<Vec3A, Output = f32>> NoiseFunction<Vec3A> for RandomElements<N> {
58    type Output = Vec3A;
59
60    #[inline]
61    fn evaluate(&self, input: Vec3A, seeds: &mut NoiseRng) -> Self::Output {
62        let x = self.0.evaluate(input, seeds);
63        seeds.re_seed();
64        let y = self.0.evaluate(input, seeds);
65        seeds.re_seed();
66        let z = self.0.evaluate(input, seeds);
67        seeds.re_seed();
68        Vec3A::new(x, y, z)
69    }
70}
71
72impl<N: NoiseFunction<Vec4, Output = f32>> NoiseFunction<Vec4> for RandomElements<N> {
73    type Output = Vec4;
74
75    #[inline]
76    fn evaluate(&self, input: Vec4, seeds: &mut NoiseRng) -> Self::Output {
77        let x = self.0.evaluate(input, seeds);
78        seeds.re_seed();
79        let y = self.0.evaluate(input, seeds);
80        seeds.re_seed();
81        let z = self.0.evaluate(input, seeds);
82        seeds.re_seed();
83        let w = self.0.evaluate(input, seeds);
84        seeds.re_seed();
85        Vec4::new(x, y, z, w)
86    }
87}
88
89/// A [`NoiseFunction`] that pushes its input by some offset calculated by an inner [`NoiseFunction`] `N`.
90///
91/// This is most commonly used for domain warping:
92///
93/// ```
94/// # use noiz::prelude::*;
95/// # use bevy_math::prelude::*;
96/// # use noiz::misc_noise::{RandomElements, Offset};
97/// let noise = Noise::<(Offset<RandomElements<common_noise::Value>>, common_noise::Perlin)>::default();
98/// let value = noise.sample_for::<f32>(Vec2::new(1.0, -1.0));
99/// ```
100#[derive(Clone, Copy, PartialEq)]
101#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
102#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
103#[cfg_attr(feature = "debug", derive(Debug))]
104pub struct Offset<N> {
105    /// The inner [`NoiseFunction`].
106    pub offseter: N,
107    /// The offset's strength/multiplier.
108    pub offset_strength: f32,
109}
110
111impl<N: Default> Default for Offset<N> {
112    fn default() -> Self {
113        Self {
114            offseter: N::default(),
115            offset_strength: 1.0,
116        }
117    }
118}
119
120impl<I: Add<N::Output> + Copy, N: NoiseFunction<I, Output: Mul<f32, Output = N::Output>>>
121    NoiseFunction<I> for Offset<N>
122{
123    type Output = I::Output;
124
125    #[inline]
126    fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
127        let offset = self.offseter.evaluate(input, seeds) * self.offset_strength;
128        input + offset
129    }
130}
131
132/// A [`NoiseFunction`] that scales/multiplies its input by some factor `T`.
133///
134/// If you want this to be [`NoiseFunction`] based, see [`Masked`].
135#[derive(Clone, Copy, PartialEq, Eq, Default)]
136#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
137#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
138#[cfg_attr(feature = "debug", derive(Debug))]
139pub struct Scaled<T>(pub T);
140
141impl<I: Mul<T>, T: Copy> NoiseFunction<I> for Scaled<T> {
142    type Output = I::Output;
143
144    #[inline]
145    fn evaluate(&self, input: I, _seeds: &mut NoiseRng) -> Self::Output {
146        input * self.0
147    }
148}
149
150/// A [`NoiseFunction`] that translates/adds its input by some offset `T`.
151///
152/// If you want this to be [`NoiseFunction`] based, see [`Offset`].
153#[derive(Clone, Copy, PartialEq, Eq, Default)]
154#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
155#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
156#[cfg_attr(feature = "debug", derive(Debug))]
157pub struct Translated<T>(pub T);
158
159impl<I: Add<T>, T: Copy> NoiseFunction<I> for Translated<T> {
160    type Output = I::Output;
161
162    #[inline]
163    fn evaluate(&self, input: I, _seeds: &mut NoiseRng) -> Self::Output {
164        input + self.0
165    }
166}
167
168/// A [`NoiseFunction`] always returns a constant `T`.
169#[derive(Default, Clone, Copy, PartialEq, Eq)]
170#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
171#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
172#[cfg_attr(feature = "debug", derive(Debug))]
173pub struct Constant<T>(pub T);
174
175impl<I, T: Copy> NoiseFunction<I> for Constant<T> {
176    type Output = T;
177
178    #[inline]
179    fn evaluate(&self, _input: I, _seeds: &mut NoiseRng) -> Self::Output {
180        self.0
181    }
182}
183
184/// A [`NoiseFunction`] that multiplies the result of two [`NoiseFunction`]s evaluated at the same input.
185///
186/// This is generally commutative, so `N` and `M` can swap without changing what kind of noise it is (though due to rng, the results may differ).
187/// If you need to mask more than two noise functions, you can nest `M` or `N` in another [`Masked`].
188/// If you only need to mask one, see [`SelfMasked`].
189#[derive(Default, Clone, Copy, PartialEq, Eq)]
190#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
191#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
192#[cfg_attr(feature = "debug", derive(Debug))]
193pub struct Masked<N, M>(pub N, pub M);
194
195impl<I: Copy, N: NoiseFunction<I>, M: NoiseFunction<I, Output: Mul<N::Output>>> NoiseFunction<I>
196    for Masked<N, M>
197{
198    type Output = <M::Output as Mul<N::Output>>::Output;
199
200    #[inline]
201    fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
202        self.1.evaluate(input, seeds) * self.0.evaluate(input, seeds)
203    }
204}
205
206/// A [`NoiseFunction`] that multiplies two distinct results of an inner [`NoiseFunction`]s at each input.
207#[derive(Default, Clone, Copy, PartialEq, Eq)]
208#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
209#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
210#[cfg_attr(feature = "debug", derive(Debug))]
211pub struct SelfMasked<N>(pub N);
212
213impl<I: Copy, N: NoiseFunction<I, Output: Mul<N::Output>>> NoiseFunction<I> for SelfMasked<N> {
214    type Output = <N::Output as Mul<N::Output>>::Output;
215
216    #[inline]
217    fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
218        self.0.evaluate(input, seeds) * self.0.evaluate(input, seeds)
219    }
220}
221
222/// A [`NoiseFunction`] that just [`NoiseRng::re_seed`]s the seed.
223/// This is useful if one [`NoiseFunction`] is being used back to back and you want the two to be additionally disjoint.
224#[derive(Default, Clone, Copy, PartialEq, Eq)]
225#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
226#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
227#[cfg_attr(feature = "debug", derive(Debug))]
228pub struct ExtraRng;
229
230impl<T> NoiseFunction<T> for ExtraRng {
231    type Output = T;
232
233    #[inline]
234    fn evaluate(&self, input: T, seeds: &mut NoiseRng) -> Self::Output {
235        seeds.re_seed();
236        input
237    }
238}
239
240/// A [`NoiseFunction`] that changes the seed of an inner [`NoiseFunction`] `N` based on the output of another [`NoiseFunction`] `P`.
241/// This creates an effect where multiple layers of noise seem to be being peeled back on each other.
242#[derive(Clone, Copy, PartialEq)]
243#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
244#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
245#[cfg_attr(feature = "debug", derive(Debug))]
246pub struct Peeled<N, P> {
247    /// The [`NoiseFunction`] that determines where to peel the seed.
248    pub peeler: P,
249    /// The inner [`NoiseFunction`].
250    pub noise: N,
251    /// How many layers to peel off.
252    pub layers: f32,
253}
254
255impl<N: Default, P: Default> Default for Peeled<N, P> {
256    fn default() -> Self {
257        Self {
258            peeler: P::default(),
259            noise: N::default(),
260            layers: 2.0,
261        }
262    }
263}
264
265impl<I: Copy, N: NoiseFunction<I>, P: NoiseFunction<I, Output = f32>> NoiseFunction<I>
266    for Peeled<N, P>
267{
268    type Output = N::Output;
269
270    #[inline]
271    fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
272        let layer = (self.peeler.evaluate(input, seeds) * self.layers).floor() as i32;
273        let mut layered = NoiseRng(seeds.rand_u32(layer as u32));
274        self.noise.evaluate(input, &mut layered)
275    }
276}
277
278/// A [`NoiseFunction`] changes it's input to an aligned version if one is available.
279/// Ex, this will convert [`Vec3`] to [`Vec3A`]. This enables SIMD instructions but consumes more memory.
280/// Justify this with a benchmark. See also [`DisAligned`].
281#[derive(Clone, Copy, PartialEq, Eq)]
282#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
283#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
284#[cfg_attr(feature = "debug", derive(Debug))]
285pub struct Aligned;
286
287impl NoiseFunction<Vec2> for Aligned {
288    type Output = Vec2;
289
290    #[inline(always)]
291    fn evaluate(&self, input: Vec2, _seeds: &mut NoiseRng) -> Self::Output {
292        input
293    }
294}
295
296impl NoiseFunction<Vec3> for Aligned {
297    type Output = Vec3A;
298
299    #[inline(always)]
300    fn evaluate(&self, input: Vec3, _seeds: &mut NoiseRng) -> Self::Output {
301        input.into()
302    }
303}
304
305impl NoiseFunction<Vec3A> for Aligned {
306    type Output = Vec3A;
307
308    #[inline(always)]
309    fn evaluate(&self, input: Vec3A, _seeds: &mut NoiseRng) -> Self::Output {
310        input
311    }
312}
313
314impl NoiseFunction<Vec4> for Aligned {
315    type Output = Vec4;
316
317    #[inline(always)]
318    fn evaluate(&self, input: Vec4, _seeds: &mut NoiseRng) -> Self::Output {
319        input
320    }
321}
322
323/// A [`NoiseFunction`] changes it's input to an un-aligned version if one is available.
324/// Ex, this will convert [`Vec3A`] to [`Vec3`]. This disables SIMD instructions but reduces memory.
325/// Justify this with a benchmark. See also [`Aligned`].
326#[derive(Clone, Copy, PartialEq, Eq)]
327#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
328#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
329#[cfg_attr(feature = "debug", derive(Debug))]
330pub struct DisAligned;
331
332impl NoiseFunction<Vec2> for DisAligned {
333    type Output = Vec2;
334
335    #[inline(always)]
336    fn evaluate(&self, input: Vec2, _seeds: &mut NoiseRng) -> Self::Output {
337        input
338    }
339}
340
341impl NoiseFunction<Vec3> for DisAligned {
342    type Output = Vec3;
343
344    #[inline(always)]
345    fn evaluate(&self, input: Vec3, _seeds: &mut NoiseRng) -> Self::Output {
346        input
347    }
348}
349
350impl NoiseFunction<Vec3A> for DisAligned {
351    type Output = Vec3;
352
353    #[inline(always)]
354    fn evaluate(&self, input: Vec3A, _seeds: &mut NoiseRng) -> Self::Output {
355        input.into()
356    }
357}
358
359impl NoiseFunction<Vec4> for DisAligned {
360    type Output = Vec4;
361
362    #[inline(always)]
363    fn evaluate(&self, input: Vec4, _seeds: &mut NoiseRng) -> Self::Output {
364        input
365    }
366}
367
368/// A [`NoiseFunction`] that forces a gradient of this value.
369/// This is mathematically arbitrary and will not be an actual derivative/gradient unless you calculate it to be so.
370/// This exists as an escape hatch to use [`crate::layering::NormedByDerivative`] with noise functions that are not differentiable.
371#[derive(Clone, Copy, PartialEq, Eq)]
372#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
373#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
374#[cfg_attr(feature = "debug", derive(Debug))]
375pub struct WithGradientOf<G>(pub G);
376
377impl<T, G: Copy> NoiseFunction<T> for WithGradientOf<G> {
378    type Output = WithGradient<T, G>;
379
380    #[inline(always)]
381    fn evaluate(&self, input: T, _seeds: &mut NoiseRng) -> Self::Output {
382        WithGradient {
383            value: input,
384            gradient: self.0,
385        }
386    }
387}
388
389/// A [`NoiseFunction`] that remaps a scalar input by passing it through a [`Curve`].
390/// If `CLAMP` is `true`, this will use [`Curve::sample_clamped`]; otherwise, it will use [`Curve::sample_unchecked`].
391#[derive(Clone, Copy, PartialEq, Eq)]
392#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
393#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
394#[cfg_attr(feature = "debug", derive(Debug))]
395pub struct RemapCurve<C, T, const CLAMP: bool = true> {
396    /// The [`Curve`] to sample with.
397    pub curve: C,
398    /// The marker data for the [`Curve`]'s output.
399    pub marker: PhantomData<T>,
400}
401
402impl<C, T, const CLAMP: bool> From<C> for RemapCurve<C, T, CLAMP> {
403    fn from(value: C) -> Self {
404        Self {
405            curve: value,
406            marker: PhantomData,
407        }
408    }
409}
410
411impl<C: Default, T, const CLAMP: bool> Default for RemapCurve<C, T, CLAMP> {
412    fn default() -> Self {
413        Self {
414            curve: Default::default(),
415            marker: PhantomData,
416        }
417    }
418}
419
420impl<C: Curve<T>, T, const CLAMP: bool> NoiseFunction<f32> for RemapCurve<C, T, CLAMP> {
421    type Output = T;
422
423    #[inline]
424    fn evaluate(&self, input: f32, _seeds: &mut NoiseRng) -> Self::Output {
425        if CLAMP {
426            self.curve.sample_clamped(input)
427        } else {
428            self.curve.sample_unchecked(input)
429        }
430    }
431}
432
433impl<C: SampleDerivative<T>, T: HasTangent, G: Add<T::Tangent>, const CLAMP: bool>
434    NoiseFunction<WithGradient<f32, G>> for RemapCurve<C, T, CLAMP>
435{
436    type Output = WithGradient<T, G::Output>;
437
438    #[inline]
439    fn evaluate(&self, input: WithGradient<f32, G>, _seeds: &mut NoiseRng) -> Self::Output {
440        let f = if CLAMP {
441            self.curve.sample_with_derivative_clamped(input.value)
442        } else {
443            self.curve.sample_with_derivative_unchecked(input.value)
444        };
445        WithGradient {
446            value: f.value,
447            gradient: input.gradient + f.derivative,
448        }
449    }
450}