noise_functions/base/
value_cubic.rs

1use crate::base::impl_noise;
2
3#[cfg(feature = "nightly-simd")]
4use core::simd::{f32x2, f32x4};
5
6/// 2/3 dimensional Cubic Value noise.
7#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
8pub struct ValueCubic;
9
10impl_noise!(23 ValueCubic);
11
12impl ValueCubic {
13    #[inline]
14    fn gen2(self, [x, y]: [f32; 2], seed: i32) -> f32 {
15        // implementation from FastNoiseLite
16        use crate::from_fast_noise_lite::{cubic_lerp, floor_to_int, value2, PRIME_X, PRIME_Y};
17
18        let mut x1: i32 = floor_to_int(x);
19        let mut y1: i32 = floor_to_int(y);
20
21        let xs: f32 = x - x1 as f32;
22        let ys: f32 = y - y1 as f32;
23
24        x1 = x1.wrapping_mul(PRIME_X);
25        y1 = y1.wrapping_mul(PRIME_Y);
26
27        let x0: i32 = x1.wrapping_sub(PRIME_X);
28        let y0: i32 = y1.wrapping_sub(PRIME_Y);
29        let x2: i32 = x1.wrapping_add(PRIME_X);
30        let y2: i32 = y1.wrapping_add(PRIME_Y);
31        let x3: i32 = x1.wrapping_add(((PRIME_X as i64).wrapping_shl(1)) as i32);
32        let y3: i32 = y1.wrapping_add(((PRIME_Y as i64).wrapping_shl(1)) as i32);
33
34        cubic_lerp(
35            cubic_lerp(value2(seed, x0, y0), value2(seed, x1, y0), value2(seed, x2, y0), value2(seed, x3, y0), xs),
36            cubic_lerp(value2(seed, x0, y1), value2(seed, x1, y1), value2(seed, x2, y1), value2(seed, x3, y1), xs),
37            cubic_lerp(value2(seed, x0, y2), value2(seed, x1, y2), value2(seed, x2, y2), value2(seed, x3, y2), xs),
38            cubic_lerp(value2(seed, x0, y3), value2(seed, x1, y3), value2(seed, x2, y3), value2(seed, x3, y3), xs),
39            ys,
40        ) * (1.0 / (1.5 * 1.5))
41    }
42
43    #[inline]
44    fn gen3(self, [x, y, z]: [f32; 3], seed: i32) -> f32 {
45        // implementation from FastNoiseLite
46        use crate::from_fast_noise_lite::{cubic_lerp, floor_to_int, value3, PRIME_X, PRIME_Y, PRIME_Z};
47
48        let mut x1: i32 = floor_to_int(x);
49        let mut y1: i32 = floor_to_int(y);
50        let mut z1: i32 = floor_to_int(z);
51
52        let xs: f32 = x - x1 as f32;
53        let ys: f32 = y - y1 as f32;
54        let zs: f32 = z - z1 as f32;
55
56        x1 = x1.wrapping_mul(PRIME_X);
57        y1 = y1.wrapping_mul(PRIME_Y);
58        z1 = z1.wrapping_mul(PRIME_Z);
59
60        let x0: i32 = x1.wrapping_sub(PRIME_X);
61        let y0: i32 = y1.wrapping_sub(PRIME_Y);
62        let z0: i32 = z1.wrapping_sub(PRIME_Z);
63
64        let x2: i32 = x1.wrapping_add(PRIME_X);
65        let y2: i32 = y1.wrapping_add(PRIME_Y);
66        let z2: i32 = z1.wrapping_add(PRIME_Z);
67
68        let x3: i32 = x1.wrapping_add((PRIME_X as i64).wrapping_shl(1) as i32);
69        let y3: i32 = y1.wrapping_add((PRIME_Y as i64).wrapping_shl(1) as i32);
70        let z3: i32 = z1.wrapping_add((PRIME_Z as i64).wrapping_shl(1) as i32);
71
72        cubic_lerp(
73            cubic_lerp(
74                cubic_lerp(value3(seed, x0, y0, z0), value3(seed, x1, y0, z0), value3(seed, x2, y0, z0), value3(seed, x3, y0, z0), xs),
75                cubic_lerp(value3(seed, x0, y1, z0), value3(seed, x1, y1, z0), value3(seed, x2, y1, z0), value3(seed, x3, y1, z0), xs),
76                cubic_lerp(value3(seed, x0, y2, z0), value3(seed, x1, y2, z0), value3(seed, x2, y2, z0), value3(seed, x3, y2, z0), xs),
77                cubic_lerp(value3(seed, x0, y3, z0), value3(seed, x1, y3, z0), value3(seed, x2, y3, z0), value3(seed, x3, y3, z0), xs),
78                ys,
79            ),
80            cubic_lerp(
81                cubic_lerp(value3(seed, x0, y0, z1), value3(seed, x1, y0, z1), value3(seed, x2, y0, z1), value3(seed, x3, y0, z1), xs),
82                cubic_lerp(value3(seed, x0, y1, z1), value3(seed, x1, y1, z1), value3(seed, x2, y1, z1), value3(seed, x3, y1, z1), xs),
83                cubic_lerp(value3(seed, x0, y2, z1), value3(seed, x1, y2, z1), value3(seed, x2, y2, z1), value3(seed, x3, y2, z1), xs),
84                cubic_lerp(value3(seed, x0, y3, z1), value3(seed, x1, y3, z1), value3(seed, x2, y3, z1), value3(seed, x3, y3, z1), xs),
85                ys,
86            ),
87            cubic_lerp(
88                cubic_lerp(value3(seed, x0, y0, z2), value3(seed, x1, y0, z2), value3(seed, x2, y0, z2), value3(seed, x3, y0, z2), xs),
89                cubic_lerp(value3(seed, x0, y1, z2), value3(seed, x1, y1, z2), value3(seed, x2, y1, z2), value3(seed, x3, y1, z2), xs),
90                cubic_lerp(value3(seed, x0, y2, z2), value3(seed, x1, y2, z2), value3(seed, x2, y2, z2), value3(seed, x3, y2, z2), xs),
91                cubic_lerp(value3(seed, x0, y3, z2), value3(seed, x1, y3, z2), value3(seed, x2, y3, z2), value3(seed, x3, y3, z2), xs),
92                ys,
93            ),
94            cubic_lerp(
95                cubic_lerp(value3(seed, x0, y0, z3), value3(seed, x1, y0, z3), value3(seed, x2, y0, z3), value3(seed, x3, y0, z3), xs),
96                cubic_lerp(value3(seed, x0, y1, z3), value3(seed, x1, y1, z3), value3(seed, x2, y1, z3), value3(seed, x3, y1, z3), xs),
97                cubic_lerp(value3(seed, x0, y2, z3), value3(seed, x1, y2, z3), value3(seed, x2, y2, z3), value3(seed, x3, y2, z3), xs),
98                cubic_lerp(value3(seed, x0, y3, z3), value3(seed, x1, y3, z3), value3(seed, x2, y3, z3), value3(seed, x3, y3, z3), xs),
99                ys,
100            ),
101            zs,
102        ) * (1.0 / (1.5 * 1.5 * 1.5))
103    }
104
105    #[inline]
106    #[cfg(feature = "nightly-simd")]
107    fn gen2a(self, point: f32x2, seed: i32) -> f32 {
108        // based on the implementation from FastNoiseLite
109        use crate::from_fast_noise_lite::{cubic_lerp, floor_to_int, splat, value2, PRIME_XY};
110
111        use core::simd::num::SimdInt;
112
113        let v1 = floor_to_int(point);
114        let s = point - v1.cast();
115        let v1 = v1 * PRIME_XY;
116        let v0 = v1 - PRIME_XY;
117        let v2 = v1 + PRIME_XY;
118        let v3 = v1 + (PRIME_XY << splat(1));
119
120        cubic_lerp(
121            cubic_lerp(value2(seed, v0[0], v0[1]), value2(seed, v1[0], v0[1]), value2(seed, v2[0], v0[1]), value2(seed, v3[0], v0[1]), s[0]),
122            cubic_lerp(value2(seed, v0[0], v1[1]), value2(seed, v1[0], v1[1]), value2(seed, v2[0], v1[1]), value2(seed, v3[0], v1[1]), s[0]),
123            cubic_lerp(value2(seed, v0[0], v2[1]), value2(seed, v1[0], v2[1]), value2(seed, v2[0], v2[1]), value2(seed, v3[0], v2[1]), s[0]),
124            cubic_lerp(value2(seed, v0[0], v3[1]), value2(seed, v1[0], v3[1]), value2(seed, v2[0], v3[1]), value2(seed, v3[0], v3[1]), s[0]),
125            s[1],
126        ) * (1.0 / (1.5 * 1.5))
127    }
128
129    #[inline]
130    #[cfg(feature = "nightly-simd")]
131    fn gen3a(self, point: f32x4, seed: i32) -> f32 {
132        // based on the implementation from FastNoiseLite
133        use crate::from_fast_noise_lite::{cubic_lerp, floor_to_int, splat, value3, PRIME_XYZ};
134
135        use core::simd::num::SimdInt;
136
137        let v1 = floor_to_int(point);
138        let s = point - v1.cast();
139        let v1 = v1 * PRIME_XYZ;
140        let v0 = v1 - PRIME_XYZ;
141        let v2 = v1 + PRIME_XYZ;
142        let v3 = v1 + (PRIME_XYZ << splat(1));
143
144        cubic_lerp(
145            cubic_lerp(
146                cubic_lerp(
147                    value3(seed, v0[0], v0[1], v0[2]),
148                    value3(seed, v1[0], v0[1], v0[2]),
149                    value3(seed, v2[0], v0[1], v0[2]),
150                    value3(seed, v3[0], v0[1], v0[2]),
151                    s[0],
152                ),
153                cubic_lerp(
154                    value3(seed, v0[0], v1[1], v0[2]),
155                    value3(seed, v1[0], v1[1], v0[2]),
156                    value3(seed, v2[0], v1[1], v0[2]),
157                    value3(seed, v3[0], v1[1], v0[2]),
158                    s[0],
159                ),
160                cubic_lerp(
161                    value3(seed, v0[0], v2[1], v0[2]),
162                    value3(seed, v1[0], v2[1], v0[2]),
163                    value3(seed, v2[0], v2[1], v0[2]),
164                    value3(seed, v3[0], v2[1], v0[2]),
165                    s[0],
166                ),
167                cubic_lerp(
168                    value3(seed, v0[0], v3[1], v0[2]),
169                    value3(seed, v1[0], v3[1], v0[2]),
170                    value3(seed, v2[0], v3[1], v0[2]),
171                    value3(seed, v3[0], v3[1], v0[2]),
172                    s[0],
173                ),
174                s[1],
175            ),
176            cubic_lerp(
177                cubic_lerp(
178                    value3(seed, v0[0], v0[1], v1[2]),
179                    value3(seed, v1[0], v0[1], v1[2]),
180                    value3(seed, v2[0], v0[1], v1[2]),
181                    value3(seed, v3[0], v0[1], v1[2]),
182                    s[0],
183                ),
184                cubic_lerp(
185                    value3(seed, v0[0], v1[1], v1[2]),
186                    value3(seed, v1[0], v1[1], v1[2]),
187                    value3(seed, v2[0], v1[1], v1[2]),
188                    value3(seed, v3[0], v1[1], v1[2]),
189                    s[0],
190                ),
191                cubic_lerp(
192                    value3(seed, v0[0], v2[1], v1[2]),
193                    value3(seed, v1[0], v2[1], v1[2]),
194                    value3(seed, v2[0], v2[1], v1[2]),
195                    value3(seed, v3[0], v2[1], v1[2]),
196                    s[0],
197                ),
198                cubic_lerp(
199                    value3(seed, v0[0], v3[1], v1[2]),
200                    value3(seed, v1[0], v3[1], v1[2]),
201                    value3(seed, v2[0], v3[1], v1[2]),
202                    value3(seed, v3[0], v3[1], v1[2]),
203                    s[0],
204                ),
205                s[1],
206            ),
207            cubic_lerp(
208                cubic_lerp(
209                    value3(seed, v0[0], v0[1], v2[2]),
210                    value3(seed, v1[0], v0[1], v2[2]),
211                    value3(seed, v2[0], v0[1], v2[2]),
212                    value3(seed, v3[0], v0[1], v2[2]),
213                    s[0],
214                ),
215                cubic_lerp(
216                    value3(seed, v0[0], v1[1], v2[2]),
217                    value3(seed, v1[0], v1[1], v2[2]),
218                    value3(seed, v2[0], v1[1], v2[2]),
219                    value3(seed, v3[0], v1[1], v2[2]),
220                    s[0],
221                ),
222                cubic_lerp(
223                    value3(seed, v0[0], v2[1], v2[2]),
224                    value3(seed, v1[0], v2[1], v2[2]),
225                    value3(seed, v2[0], v2[1], v2[2]),
226                    value3(seed, v3[0], v2[1], v2[2]),
227                    s[0],
228                ),
229                cubic_lerp(
230                    value3(seed, v0[0], v3[1], v2[2]),
231                    value3(seed, v1[0], v3[1], v2[2]),
232                    value3(seed, v2[0], v3[1], v2[2]),
233                    value3(seed, v3[0], v3[1], v2[2]),
234                    s[0],
235                ),
236                s[1],
237            ),
238            cubic_lerp(
239                cubic_lerp(
240                    value3(seed, v0[0], v0[1], v3[2]),
241                    value3(seed, v1[0], v0[1], v3[2]),
242                    value3(seed, v2[0], v0[1], v3[2]),
243                    value3(seed, v3[0], v0[1], v3[2]),
244                    s[0],
245                ),
246                cubic_lerp(
247                    value3(seed, v0[0], v1[1], v3[2]),
248                    value3(seed, v1[0], v1[1], v3[2]),
249                    value3(seed, v2[0], v1[1], v3[2]),
250                    value3(seed, v3[0], v1[1], v3[2]),
251                    s[0],
252                ),
253                cubic_lerp(
254                    value3(seed, v0[0], v2[1], v3[2]),
255                    value3(seed, v1[0], v2[1], v3[2]),
256                    value3(seed, v2[0], v2[1], v3[2]),
257                    value3(seed, v3[0], v2[1], v3[2]),
258                    s[0],
259                ),
260                cubic_lerp(
261                    value3(seed, v0[0], v3[1], v3[2]),
262                    value3(seed, v1[0], v3[1], v3[2]),
263                    value3(seed, v2[0], v3[1], v3[2]),
264                    value3(seed, v3[0], v3[1], v3[2]),
265                    s[0],
266                ),
267                s[1],
268            ),
269            s[2],
270        ) * (1.0 / (1.5 * 1.5 * 1.5))
271    }
272}