noise_functions/
noise.rs

1#[cfg(feature = "nightly-simd")]
2use core::simd::{f32x2, f32x4};
3
4use crate::{
5    modifiers::{
6        Abs, Add, AddSeed, Ceil, Clamp, Cos, Div, Fbm, Floor, Frequency, Lerp, Map, Max, Min, Mul, MulSeed, Neg, Pow, Rem, Ridged, Round, Seeded, Sin, Sqrt, Sub, Tan, Tileable, TranslateX,
7        TranslateXy, TranslateXyz, TranslateXyzw, TriangleWave,
8    },
9    Sample, ValueOrNoise,
10};
11
12/// Provides utility methods for noise types.
13pub trait Noise {
14    /// Samples the noise in 2D.
15    fn sample2<Point>(&self, point: Point) -> f32
16    where
17        Self: Sized + Sample<2>,
18        Point: Into<[f32; 2]>,
19    {
20        self.sample_with_seed(point.into(), 0)
21    }
22
23    /// Samples the noise in 3D.
24    fn sample3<Point>(&self, point: Point) -> f32
25    where
26        Self: Sized + Sample<3>,
27        Point: Into<[f32; 3]>,
28    {
29        self.sample_with_seed(point.into(), 0)
30    }
31
32    /// Samples the noise in 3D.
33    fn sample4<Point>(&self, point: Point) -> f32
34    where
35        Self: Sized + Sample<4>,
36        Point: Into<[f32; 4]>,
37    {
38        self.sample_with_seed(point.into(), 0)
39    }
40
41    /// Samples the noise in 2D.
42    #[cfg(feature = "nightly-simd")]
43    fn sample2a<Point>(&self, point: Point) -> f32
44    where
45        Self: Sized + Sample<2, f32x2>,
46        Point: Into<f32x2>,
47    {
48        self.sample_with_seed(point.into(), 0)
49    }
50
51    /// Samples the noise in 3D.
52    #[cfg(feature = "nightly-simd")]
53    fn sample3a<Point>(&self, point: Point) -> f32
54    where
55        Self: Sized + Sample<3, f32x4>,
56        Point: Into<f32x4>,
57    {
58        self.sample_with_seed(point.into(), 0)
59    }
60
61    /// Samples the noise in 4D.
62    #[cfg(feature = "nightly-simd")]
63    fn sample4a<Point>(&self, point: Point) -> f32
64    where
65        Self: Sized + Sample<4, f32x4>,
66        Point: Into<f32x4>,
67    {
68        self.sample_with_seed(point.into(), 0)
69    }
70
71    /// Overwrites the seed to be sampled with.
72    ///
73    /// For the sake of composition it can be better to use [`add_seed`](Self::add_seed) instead.
74    #[inline(always)]
75    fn seed(self, seed: i32) -> Seeded<Self>
76    where
77        Self: Sized,
78    {
79        Seeded { noise: self, seed }
80    }
81
82    /// Adds `value` to the seed.
83    #[inline(always)]
84    fn add_seed(self, value: i32) -> AddSeed<Self>
85    where
86        Self: Sized,
87    {
88        AddSeed { noise: self, value }
89    }
90
91    /// Multiplies the seed by `value`.
92    #[inline(always)]
93    fn mul_seed(self, value: i32) -> MulSeed<Self>
94    where
95        Self: Sized,
96    {
97        MulSeed { noise: self, value }
98    }
99
100    /// Modifies a noise with a frequency multiplier.
101    ///
102    /// This multiplies the point by the provided `frequency` before sampling.
103    #[inline(always)]
104    fn frequency<F>(self, frequency: F) -> Frequency<Self, F::Noise>
105    where
106        Self: Sized,
107        F: ValueOrNoise,
108    {
109        Frequency {
110            noise: self,
111            frequency: frequency.into_noise(),
112        }
113    }
114
115    /// Creates a fractal from this noise with the provided `octaves`, `gain`
116    /// and `lacunarity`.
117    ///
118    /// The seed, with which the fractal is sampled with, will be incremented
119    /// after each octave.
120    // TODO: explain the parameters
121    #[inline(always)]
122    fn fbm(self, octaves: u32, gain: f32, lacunarity: f32) -> Fbm<Self>
123    where
124        Self: Sized,
125    {
126        Fbm::new(self, octaves, gain, lacunarity)
127    }
128
129    /// Modifies a noise to create a peak at 0.
130    ///
131    /// This outputs values is in the [-1, 1] range.
132    ///
133    /// **Note:** This modifier assumes `self` returns values in the [-1, 1] range.
134    #[inline(always)]
135    fn ridged(self) -> Ridged<Self>
136    where
137        Self: Sized,
138    {
139        Ridged { noise: self }
140    }
141
142    /// Applies a triangle wave to the output of a noise function.
143    ///
144    /// This outputs values is in the [-1, 1] range.
145    ///
146    /// **Note:** This modifier assumes `self` returns values in the [-1, 1] range.
147    #[inline(always)]
148    fn triangle_wave<F>(self, frequency: F) -> TriangleWave<Self, F::Noise>
149    where
150        Self: Sized,
151        F: ValueOrNoise,
152    {
153        TriangleWave {
154            noise: self,
155            frequency: frequency.into_noise(),
156        }
157    }
158
159    /// Creates a tileable 2D noise from a 4D noise.
160    ///
161    /// The parameters `width` and `height` describe the size of the repeating tile.
162    #[inline(always)]
163    fn tileable(self, width: f32, height: f32) -> Tileable<Self>
164    where
165        Self: Sized,
166    {
167        Tileable::new(self, width, height)
168    }
169
170    /// Translates the point before it is used to sample `self`.
171    fn translate_x<X>(self, x: X) -> TranslateX<Self, X::Noise>
172    where
173        Self: Sized,
174        X: ValueOrNoise,
175    {
176        TranslateX { noise: self, x: x.into_noise() }
177    }
178
179    /// Translates the point before it is used to sample `self`.
180    fn translate_xy<X, Y>(self, x: X, y: Y) -> TranslateXy<Self, X::Noise, Y::Noise>
181    where
182        Self: Sized,
183        X: ValueOrNoise,
184        Y: ValueOrNoise,
185    {
186        TranslateXy {
187            noise: self,
188            x: x.into_noise(),
189            y: y.into_noise(),
190        }
191    }
192
193    /// Translates the point before it is used to sample `self`.
194    fn translate_xyz<X, Y, Z>(self, x: X, y: Y, z: Z) -> TranslateXyz<Self, X::Noise, Y::Noise, Z::Noise>
195    where
196        Self: Sized,
197        X: ValueOrNoise,
198        Y: ValueOrNoise,
199        Z: ValueOrNoise,
200    {
201        TranslateXyz {
202            noise: self,
203            x: x.into_noise(),
204            y: y.into_noise(),
205            z: z.into_noise(),
206        }
207    }
208
209    /// Translates the point before it is used to sample `self`.
210    fn translate_xyzw<X, Y, Z, W>(self, x: X, y: Y, z: Z, w: W) -> TranslateXyzw<Self, X::Noise, Y::Noise, Z::Noise, W::Noise>
211    where
212        Self: Sized,
213        X: ValueOrNoise,
214        Y: ValueOrNoise,
215        Z: ValueOrNoise,
216        W: ValueOrNoise,
217    {
218        TranslateXyzw {
219            noise: self,
220            x: x.into_noise(),
221            y: y.into_noise(),
222            z: z.into_noise(),
223            w: w.into_noise(),
224        }
225    }
226
227    /// Adds the output values.
228    fn add<Rhs>(self, rhs: Rhs) -> Add<Self, Rhs::Noise>
229    where
230        Self: Sized,
231        Rhs: ValueOrNoise,
232    {
233        Add { lhs: self, rhs: rhs.into_noise() }
234    }
235
236    /// Subtracts one output value from the other.
237    fn sub<Rhs>(self, rhs: Rhs) -> Sub<Self, Rhs::Noise>
238    where
239        Self: Sized,
240        Rhs: ValueOrNoise,
241    {
242        Sub { lhs: self, rhs: rhs.into_noise() }
243    }
244
245    /// Multiplies the output values.
246    fn mul<Rhs>(self, rhs: Rhs) -> Mul<Self, Rhs::Noise>
247    where
248        Self: Sized,
249        Rhs: ValueOrNoise,
250    {
251        Mul { lhs: self, rhs: rhs.into_noise() }
252    }
253
254    /// Divides one output value by the other.
255    fn div<Rhs>(self, rhs: Rhs) -> Div<Self, Rhs::Noise>
256    where
257        Self: Sized,
258        Rhs: ValueOrNoise,
259    {
260        Div { lhs: self, rhs: rhs.into_noise() }
261    }
262
263    /// Calculates the remainder from dividing one output value by the other.
264    fn rem<Rhs>(self, rhs: Rhs) -> Rem<Self, Rhs::Noise>
265    where
266        Self: Sized,
267        Rhs: ValueOrNoise,
268    {
269        Rem { lhs: self, rhs: rhs.into_noise() }
270    }
271
272    /// Computes the minimum of the two output values.
273    fn min<Rhs>(self, rhs: Rhs) -> Min<Self, Rhs::Noise>
274    where
275        Self: Sized,
276        Rhs: ValueOrNoise,
277    {
278        Min { lhs: self, rhs: rhs.into_noise() }
279    }
280
281    /// Computes the maximum of the two output values.
282    fn max<Rhs>(self, rhs: Rhs) -> Max<Self, Rhs::Noise>
283    where
284        Self: Sized,
285        Rhs: ValueOrNoise,
286    {
287        Max { lhs: self, rhs: rhs.into_noise() }
288    }
289
290    /// Returns `max` if `value` is greater than `max` and `min` if `value` is less than `min`.
291    /// Otherwise this will return `value`.
292    ///
293    /// Unlike [`f32::clamp`], this modifier won't panic if `!(min <= max)`.
294    fn clamp<Min, Max>(self, min: Min, max: Max) -> Clamp<Self, Min::Noise, Max::Noise>
295    where
296        Self: Sized,
297        Min: ValueOrNoise,
298        Max: ValueOrNoise,
299    {
300        Clamp {
301            value: self,
302            min: min.into_noise(),
303            max: max.into_noise(),
304        }
305    }
306
307    /// Linearly interpolates between `self` and `b`.
308    #[doc(alias = "mix")]
309    #[doc(alias = "blend")]
310    fn lerp<B, T>(self, b: B, t: T) -> Lerp<Self, B::Noise, T::Noise>
311    where
312        Self: Sized,
313        B: ValueOrNoise,
314        T: ValueOrNoise,
315    {
316        Lerp {
317            a: self,
318            b: b.into_noise(),
319            t: t.into_noise(),
320        }
321    }
322
323    /// Raises the output value to a power.
324    fn pow<Rhs>(self, rhs: Rhs) -> Pow<Self, Rhs::Noise>
325    where
326        Self: Sized,
327        Rhs: ValueOrNoise,
328    {
329        Pow { lhs: self, rhs: rhs.into_noise() }
330    }
331
332    /// Performs negation on the output value.
333    fn neg(self) -> Neg<Self>
334    where
335        Self: Sized,
336    {
337        Neg { noise: self }
338    }
339
340    /// Computes the absolute value of the output value.
341    fn abs(self) -> Abs<Self>
342    where
343        Self: Sized,
344    {
345        Abs { noise: self }
346    }
347
348    /// Returns the square root of a number.
349    ///
350    /// Returns NaN if `self` is a negative number other than `-0.0`.
351    fn sqrt(self) -> Sqrt<Self>
352    where
353        Self: Sized,
354    {
355        Sqrt { noise: self }
356    }
357
358    /// Computes the largest integer less than or equal to the output value.
359    fn floor(self) -> Floor<Self>
360    where
361        Self: Sized,
362    {
363        Floor { noise: self }
364    }
365
366    /// Computes the smallest integer greater than or equal to self.
367    fn ceil(self) -> Ceil<Self>
368    where
369        Self: Sized,
370    {
371        Ceil { noise: self }
372    }
373
374    /// Computes the nearest integer to the output value.
375    /// If a value is half-way between two integers, round away from 0.0.
376    fn round(self) -> Round<Self>
377    where
378        Self: Sized,
379    {
380        Round { noise: self }
381    }
382
383    /// Computes the sine of the output value (in radians).
384    fn sin(self) -> Sin<Self>
385    where
386        Self: Sized,
387    {
388        Sin { noise: self }
389    }
390
391    /// Computes the cosine of the output value (in radians).
392    fn cos(self) -> Cos<Self>
393    where
394        Self: Sized,
395    {
396        Cos { noise: self }
397    }
398
399    /// Computes the tangent of the output value (in radians).
400    fn tan(self) -> Tan<Self>
401    where
402        Self: Sized,
403    {
404        Tan { noise: self }
405    }
406
407    /// Maps the output value.
408    #[inline(always)]
409    fn map<F>(self, f: F) -> Map<Self, F>
410    where
411        Self: Sized,
412        F: Fn(f32) -> f32,
413    {
414        Map { noise: self, f }
415    }
416
417    /// Returns the `Noise` by reference.
418    ///
419    /// This reference also implements `Noise`.
420    ///
421    /// # Examples
422    /// ```
423    /// # use noise_functions::{Noise, Sample};
424    /// fn my_noise(base_noise: impl Sample<2>, point: [f32; 2]) -> f32 {
425    ///     // If we weren't using `by_ref` then `add_seed` would consume `base_noise`
426    ///     // and we couldn't use it again in the next line.
427    ///     let a = base_noise.by_ref().add_seed(1).sample2(point);
428    ///     let b = base_noise.by_ref().add_seed(2).sample2(point);
429    ///     a + b
430    /// }
431    /// ```
432    fn by_ref(&self) -> &Self
433    where
434        Self: Sized,
435    {
436        self
437    }
438}
439
440impl<N: Noise> Noise for &N {}
441
442#[cfg(feature = "alloc")]
443impl<N: Noise + ?Sized> Noise for alloc::boxed::Box<N> {}