noise_functions/
lib.rs

1//!
2//! A collection of fast and lightweight noise functions.
3//!
4//! Check out the [live demo][demo] and [node editor][playground] (experimental)!
5//!
6//! [demo]: https://bluurryy.github.io/noise-functions-demo/
7//! [playground]: https://bluurryy.github.io/noise-functions-playground/
8//!
9//! ## Examples
10//! ```
11//! use noise_functions::{ Noise, OpenSimplexNoise, Perlin, CellDistance, OpenSimplex2s, NoiseFn };
12//!
13//! let point = [1.0, 2.0];
14//!
15//! // perlin noise
16//! let value = Perlin.sample2(point);
17//!
18//! // seeded perlin noise
19//! let value = Perlin.seed(42).sample2(point);
20//!
21//! // fractal perlin noise
22//! let value = Perlin.fbm(3, 0.5, 3.0).sample2(point);
23//!
24//! // seeded fractal perlin noise
25//! let value = Perlin.fbm(3, 0.5, 3.0).seed(42).sample2(point);
26//!
27//! // perlin noise with adjusted frequency
28//! let value = Perlin.frequency(3.0).sample2(point);
29//!
30//! // cell distance (voronoi/worley) noise
31//! let value = CellDistance::default().sample2(point);
32//!
33//! // cell distance (voronoi/worley) noise with jitter multiplier
34//! let value = CellDistance::default().jitter(0.5).sample2(point);
35//!
36//! // domain warped OpenSimplex2s noise
37//! let noise = OpenSimplex2s.translate_xy(OpenSimplex2s.seed(1), OpenSimplex2s.seed(2));
38//! let value = noise.sample2(point);
39//!
40//! let point = [1.0, 2.0, 3.0];
41//!
42//! // 3d OpenSimplex2s noise
43//! let value = OpenSimplex2s.sample3(point);
44//!
45//! // 3d OpenSimplex2s noise with improved isotropy in the xy plane
46//! let value = OpenSimplex2s.improve3_xy().sample3(point);
47//! ```
48//!
49//! ## Feature flags
50#![no_std]
51#![cfg_attr(
52    feature = "document-features",
53    cfg_attr(doc, doc = ::document_features::document_features!())
54)]
55#![cfg_attr(feature = "nightly-simd", feature(portable_simd))]
56#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(no_global_oom_handling, feature = "nightly-const-fn-float")))]
57#![allow(clippy::excessive_precision, clippy::needless_late_init, clippy::too_many_arguments, clippy::approx_constant)]
58
59#[cfg(any(feature = "std", test))]
60extern crate std;
61
62#[cfg(feature = "alloc")]
63extern crate alloc;
64
65#[cfg(all(not(feature = "std"), not(feature = "libm")))]
66compile_error!(r#"`noise-functions` crate: either the "std" or "libm" feature must be enabled"#);
67
68mod base;
69mod cellular;
70mod constant;
71mod from_fast_noise_2;
72mod from_fast_noise_lite;
73mod from_open_simplex_2;
74mod lookup_table;
75mod math;
76/// Noise modifiers.
77pub mod modifiers;
78mod noise;
79mod noise_fn;
80mod open_simplex_2;
81mod sample;
82#[cfg(test)]
83mod tests;
84mod value_or_noise;
85
86pub use base::{CellDistance, CellDistanceSq, CellValue, OpenSimplex2, OpenSimplex2s, Perlin, Simplex, Value, ValueCubic};
87pub use constant::Constant;
88pub use noise::Noise;
89pub use noise_fn::NoiseFn;
90pub use open_simplex_2::OpenSimplexNoise;
91pub use sample::Sample;
92pub use value_or_noise::ValueOrNoise;
93
94#[inline(always)]
95#[cfg(feature = "nightly-simd")]
96fn array_4_take_3<T>(array: &[T; 4]) -> &[T; 3] {
97    array[..3].try_into().unwrap()
98}
99
100macro_rules! simple_enum {
101	(
102		enum $name:ident {
103			$(
104                $(#[$variant_attr:meta])*
105                $variant:ident $(= $variant_expr:expr)?
106            ),* $(,)?
107		}
108	) => {
109		#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
110		pub enum $name {
111			$(
112                $(#[$variant_attr])*
113                $variant $(= $variant_expr)?,
114            )*
115		}
116
117		impl core::str::FromStr for $name {
118			type Err = $crate::errors::EnumFromStrError;
119
120			fn from_str(s: &str) -> Result<Self, Self::Err> {
121				Ok(match s {
122					$(stringify!($variant) => Self::$variant,)*
123					_ => return Err($crate::errors::EnumFromStrError),
124				})
125			}
126		}
127
128		impl $name {
129            #[expect(dead_code)]
130			pub const VARIANTS: &'static [Self] = &[
131				$(Self::$variant,)*
132			];
133
134			pub fn to_str(self) -> &'static str {
135				[$(stringify!($variant)),*][self as usize]
136			}
137		}
138
139		impl core::fmt::Debug for $name {
140			fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
141				f.write_str(self.to_str())
142			}
143		}
144
145		impl core::fmt::Display for $name {
146			fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
147				f.write_str(self.to_str())
148			}
149		}
150	};
151}
152
153pub(crate) use simple_enum;
154
155/// Error types.
156pub mod errors {
157    #[derive(Debug, Clone, Copy)]
158    pub struct EnumFromStrError;
159
160    impl core::fmt::Display for EnumFromStrError {
161        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162            f.write_str("can't convert string to enum")
163        }
164    }
165}