noiselib/
simplex.rs

1use crate::prelude::*;
2
3//
4// Simplex noise
5//
6
7pub fn simplex_noise_1d(_rng: &mut UniformRandomGen, x: f32, seed: u32) -> f32 {
8    let mut ix = x.floor() as i32;
9    let fx = x - ix as f32;
10
11    ix += NOISE_PERM[(seed & (N_PERM as u32 - 1)) as usize];
12
13    let ixp1 = ix & (N_PERM - 1);
14    let ixp2 = (ix / N_PERM) & (N_PERM - 1);
15
16    let h1 = NOISE_PERM[NOISE_PERM[ixp1 as usize] as usize + ixp2 as usize] & 15;
17    let h2 = NOISE_PERM[NOISE_PERM[ixp1 as usize + 1] as usize + ixp2 as usize] & 15;
18
19    let mut t0 = 1.0 - fx * fx;
20    t0 *= t0;
21
22    let mut t1 = fx * (2.0 - fx);
23    t1 *= t1;
24
25    t0 * t0 * GRAD1[h1 as usize] + t1 * t1 * GRAD1[h2 as usize]
26}
27
28const F2: f32 = 0.3660254;
29const G2: f32 = 0.211325;
30
31pub fn simplex_noise_2d(_rng: &mut UniformRandomGen, x: f32, y: f32, mut seed: u32) -> f32 {
32    let skew = (x + y) * F2;
33    let mut ix = (x + skew).floor() as i32;
34    let mut iy = (y + skew).floor() as i32;
35
36    let unskew = (ix + iy) as f32 * G2;
37
38    let fx = x - (ix as f32 - unskew);
39    let fy = y - (iy as f32 - unskew);
40
41    let off = if fx > fy { 1.0 } else { 0.0 };
42
43    let x1 = fx - off + G2;
44    let y1 = fy - (1.0 - off) + G2;
45    let x2 = fx - 1.0 + 2.0 * G2;
46    let y2 = fy - 1.0 + 2.0 * G2;
47
48    seed &= N_PERM as u32 - 1;
49    ix += NOISE_PERM[seed as usize];
50    iy += NOISE_PERM[seed as usize + 1];
51
52    ix &= N_PERM - 1;
53    iy &= N_PERM - 1;
54
55    let mut sum = 0.0;
56
57    let mut t = 0.5 - fx * fx - fy * fy;
58
59    if t > 0.0 {
60        t *= t;
61        sum += t * t * grad2(ix, iy, fx, fy);
62    }
63
64    t = 0.5 - x1 * x1 - y1 * y1;
65
66    if t > 0.0 {
67        t *= t;
68        sum += t * t * grad2(ix + off as i32, iy + (1.0 - off) as i32, x1, y1);
69    }
70
71    t = 0.5 - x2 * x2 - y2 * y2;
72
73    if t > 0.0 {
74        t *= t;
75        sum += t * t * grad2(ix + 1, iy + 1, x2, y2);
76    }
77
78    sum * 49.5
79}
80
81const F3: f32 = 1.0 / 3.0;
82const G3: f32 = 1.0 / 6.0;
83
84pub fn simplex_noise_3d(_rng: &mut UniformRandomGen, x: f32, y: f32, z: f32, mut seed: u32) -> f32 {
85    let skew = (x + y + z) * F3;
86    let mut ix = (x + skew).floor() as i32;
87    let mut iy = (y + skew).floor() as i32;
88    let mut iz = (z + skew).floor() as i32;
89
90    let unskew = (ix + iy + iz) as f32 * G3;
91
92    let mut fx: [f32; 4] = [0.0; 4];
93    let mut fy: [f32; 4] = [0.0; 4];
94    let mut fz: [f32; 4] = [0.0; 4];
95
96    fx[0] = x - (ix as f32 - unskew);
97    fy[0] = y - (iy as f32 - unskew);
98    fz[0] = z - (iz as f32 - unskew);
99
100    let mut i: [i32; 4] = [0; 4];
101    let mut j: [i32; 4] = [0; 4];
102    let mut k: [i32; 4] = [0; 4];
103
104    i[0] = 0;
105    j[0] = 0;
106    k[0] = 0;
107    i[3] = 1;
108    j[3] = 1;
109    k[3] = 1;
110
111    if fx[0] >= fy[0] {
112        if fy[0] >= fz[0] {
113            i[1] = 1;
114            i[2] = 1;
115            j[2] = 1;
116            j[1] = 0;
117            k[1] = 0;
118            k[2] = 0;
119        } else if fx[0] >= fz[0] {
120            i[1] = 1;
121            i[2] = 1;
122            k[2] = 1;
123            j[1] = 0;
124            j[2] = 0;
125            k[1] = 0;
126        } else {
127            i[2] = 1;
128            k[1] = 1;
129            k[2] = 1;
130            i[1] = 0;
131            j[1] = 0;
132            j[2] = 0;
133        }
134    } else if fy[0] < fz[0] {
135        j[2] = 1;
136        k[1] = 1;
137        k[2] = 1;
138        i[1] = 0;
139        i[2] = 0;
140        j[1] = 0;
141    } else if fx[0] < fz[0] {
142        j[1] = 1;
143        j[2] = 1;
144        k[2] = 1;
145        i[1] = 0;
146        i[2] = 0;
147        k[1] = 0;
148    } else {
149        i[2] = 1;
150        j[1] = 1;
151        j[2] = 1;
152        i[1] = 0;
153        k[1] = 0;
154        k[2] = 0;
155    }
156
157    for idx in 1..4 {
158        fx[idx] = fx[0] - i[idx] as f32 + idx as f32 * G3;
159        fy[idx] = fy[0] - j[idx] as f32 + idx as f32 * G3;
160        fz[idx] = fz[0] - k[idx] as f32 + idx as f32 * G3;
161    }
162
163    seed &= N_PERM as u32 - 1;
164    ix += NOISE_PERM[seed as usize];
165    iy += NOISE_PERM[seed as usize + 1];
166    iz += NOISE_PERM[seed as usize + 2];
167
168    ix &= N_PERM - 1;
169    iy &= N_PERM - 1;
170    iz &= N_PERM - 1;
171
172    let mut sum = 0.0;
173
174    for idx in 0..4 {
175        let mut t = 0.6 - fx[idx] * fx[idx] - fy[idx] * fy[idx] - fz[idx] * fz[idx];
176
177        if t > 0.0 {
178            t *= t;
179            sum += t
180                * t
181                * grad3(
182                    ix + i[idx],
183                    iy + j[idx],
184                    iz + k[idx],
185                    fx[idx],
186                    fy[idx],
187                    fz[idx],
188                );
189        }
190    }
191
192    sum * 32.5
193}
194
195static SIMPLEX: [[u8; 4]; 64] = [
196    [0, 1, 2, 3],
197    [0, 1, 3, 2],
198    [0, 0, 0, 0],
199    [0, 2, 3, 1],
200    [0, 0, 0, 0],
201    [0, 0, 0, 0],
202    [0, 0, 0, 0],
203    [1, 2, 3, 0],
204    [0, 2, 1, 3],
205    [0, 0, 0, 0],
206    [0, 3, 1, 2],
207    [0, 3, 2, 1],
208    [0, 0, 0, 0],
209    [0, 0, 0, 0],
210    [0, 0, 0, 0],
211    [1, 3, 2, 0],
212    [0, 0, 0, 0],
213    [0, 0, 0, 0],
214    [0, 0, 0, 0],
215    [0, 0, 0, 0],
216    [0, 0, 0, 0],
217    [0, 0, 0, 0],
218    [0, 0, 0, 0],
219    [0, 0, 0, 0],
220    [1, 2, 0, 3],
221    [0, 0, 0, 0],
222    [1, 3, 0, 2],
223    [0, 0, 0, 0],
224    [0, 0, 0, 0],
225    [0, 0, 0, 0],
226    [2, 3, 0, 1],
227    [2, 3, 1, 0],
228    [1, 0, 2, 3],
229    [1, 0, 3, 2],
230    [0, 0, 0, 0],
231    [0, 0, 0, 0],
232    [0, 0, 0, 0],
233    [2, 0, 3, 1],
234    [0, 0, 0, 0],
235    [2, 1, 3, 0],
236    [0, 0, 0, 0],
237    [0, 0, 0, 0],
238    [0, 0, 0, 0],
239    [0, 0, 0, 0],
240    [0, 0, 0, 0],
241    [0, 0, 0, 0],
242    [0, 0, 0, 0],
243    [0, 0, 0, 0],
244    [2, 0, 1, 3],
245    [0, 0, 0, 0],
246    [0, 0, 0, 0],
247    [0, 0, 0, 0],
248    [3, 0, 1, 2],
249    [3, 0, 2, 1],
250    [0, 0, 0, 0],
251    [3, 1, 2, 0],
252    [2, 1, 0, 3],
253    [0, 0, 0, 0],
254    [0, 0, 0, 0],
255    [0, 0, 0, 0],
256    [3, 1, 0, 2],
257    [0, 0, 0, 0],
258    [3, 2, 0, 1],
259    [3, 2, 1, 0],
260];
261
262const F4: f32 = 0.309017;
263const G4: f32 = 0.1381966;
264
265pub fn simplex_noise_4d(
266    _rng: &mut UniformRandomGen,
267    x: f32,
268    y: f32,
269    z: f32,
270    t: f32,
271    mut seed: u32,
272) -> f32 {
273    let skew = (x + y + z + t) * F4;
274    let mut ix = (x + skew).floor() as i32;
275    let mut iy = (y + skew).floor() as i32;
276    let mut iz = (z + skew).floor() as i32;
277    let mut it = (t + skew).floor() as i32;
278
279    let unskew = (ix + iy + iz + it) as f32 * G4;
280
281    let mut fx: [f32; 5] = [0.0; 5];
282    let mut fy: [f32; 5] = [0.0; 5];
283    let mut fz: [f32; 5] = [0.0; 5];
284    let mut ft: [f32; 5] = [0.0; 5];
285
286    fx[0] = x - (ix as f32 - unskew);
287    fy[0] = y - (iy as f32 - unskew);
288    fz[0] = z - (iz as f32 - unskew);
289    ft[0] = t - (it as f32 - unskew);
290
291    let mut i: [i32; 5] = [0; 5];
292    let mut j: [i32; 5] = [0; 5];
293    let mut k: [i32; 5] = [0; 5];
294    let mut l: [i32; 5] = [0; 5];
295
296    i[0] = 0;
297    j[0] = 0;
298    k[0] = 0;
299    l[0] = 0;
300    i[4] = 1;
301    j[4] = 1;
302    k[4] = 1;
303    l[4] = 1;
304
305    let c = if fx > fy { 32 } else { 0 }
306        | if fx > fz { 16 } else { 0 }
307        | if fy > fz { 8 } else { 0 }
308        | if fx > ft { 4 } else { 0 }
309        | if fy > ft { 2 } else { 0 }
310        | if fz > ft { 1 } else { 0 };
311
312    for idx in 1..5 {
313        if idx < 4 {
314            i[idx] = if SIMPLEX[c][0] as usize >= 4 - idx {
315                1
316            } else {
317                0
318            };
319            j[idx] = if SIMPLEX[c][1] as usize >= 4 - idx {
320                1
321            } else {
322                0
323            };
324            k[idx] = if SIMPLEX[c][2] as usize >= 4 - idx {
325                1
326            } else {
327                0
328            };
329            l[idx] = if SIMPLEX[c][3] as usize >= 4 - idx {
330                1
331            } else {
332                0
333            };
334        }
335
336        fx[idx] = fx[0] - i[idx] as f32 + idx as f32 * G4;
337        fy[idx] = fy[0] - j[idx] as f32 + idx as f32 * G4;
338        fz[idx] = fz[0] - k[idx] as f32 + idx as f32 * G4;
339        ft[idx] = ft[0] - l[idx] as f32 + idx as f32 * G4;
340    }
341
342    seed &= N_PERM as u32 - 1;
343    ix += NOISE_PERM[seed as usize];
344    iy += NOISE_PERM[seed as usize + 1];
345    iz += NOISE_PERM[seed as usize + 2];
346    it += NOISE_PERM[seed as usize + 3];
347
348    ix &= N_PERM - 1;
349    iy &= N_PERM - 1;
350    iz &= N_PERM - 1;
351    it &= N_PERM - 1;
352
353    let mut sum = 0.0;
354
355    for idx in 0..5 {
356        let mut w =
357            0.6 - fx[idx] * fx[idx] - fy[idx] * fy[idx] - fz[idx] * fz[idx] - ft[idx] * ft[idx];
358
359        if w > 0.0 {
360            w *= w;
361            sum += w
362                * w
363                * grad4(
364                    ix + i[idx],
365                    iy + j[idx],
366                    iz + k[idx],
367                    it + l[idx],
368                    fx[idx],
369                    fy[idx],
370                    fz[idx],
371                    ft[idx],
372                );
373        }
374    }
375
376    sum * 23.0
377}