1use glam::{Vec2, Vec3};
9
10const PERM_BASE: [u8; 256] = [
16 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
17 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
18 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
19 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
20 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
21 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
22 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
23 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
24 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
25 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
26 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
27 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
28 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
29 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
30 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
31 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180,
32];
33
34const P: [u8; 512] = {
35 let mut out = [0u8; 512];
36 let mut i = 0usize;
37 while i < 256 { out[i] = PERM_BASE[i]; out[i + 256] = PERM_BASE[i]; i += 1; }
38 out
39};
40
41#[inline(always)] fn p(i: usize) -> usize { P[i & 511] as usize }
42#[inline(always)] fn fade(t: f32) -> f32 { t * t * t * (t * (t * 6.0 - 15.0) + 10.0) }
43#[inline(always)] fn lerp(a: f32, b: f32, t: f32) -> f32 { a + t * (b - a) }
44
45#[inline(always)]
50fn grad1(h: usize, x: f32) -> f32 { if h & 1 == 0 { x } else { -x } }
51
52pub fn perlin1(x: f32) -> f32 {
54 let xi = x.floor() as i32 as usize & 255;
55 let xf = x - x.floor();
56 let u = fade(xf);
57 lerp(grad1(p(xi), xf), grad1(p(xi + 1), xf - 1.0), u)
58}
59
60#[inline(always)]
65fn grad2(h: usize, x: f32, y: f32) -> f32 {
66 match h & 3 { 0 => x + y, 1 => -x + y, 2 => x - y, _ => -x - y }
67}
68
69pub fn perlin2(x: f32, y: f32) -> f32 {
71 let xi = x.floor() as i32 as usize & 255;
72 let yi = y.floor() as i32 as usize & 255;
73 let xf = x - x.floor();
74 let yf = y - y.floor();
75 let u = fade(xf); let v = fade(yf);
76
77 let aa = p(p(xi) + yi); let ba = p(p(xi + 1) + yi);
78 let ab = p(p(xi) + yi + 1); let bb = p(p(xi + 1) + yi + 1);
79
80 lerp(
81 lerp(grad2(aa, xf, yf), grad2(ba, xf - 1.0, yf), u),
82 lerp(grad2(ab, xf, yf - 1.0), grad2(bb, xf - 1.0, yf - 1.0), u),
83 v,
84 )
85}
86
87#[inline(always)]
92fn grad3(h: usize, x: f32, y: f32, z: f32) -> f32 {
93 match h & 15 {
94 0 => x + y, 1 => -x + y, 2 => x - y, 3 => -x - y,
95 4 => x + z, 5 => -x + z, 6 => x - z, 7 => -x - z,
96 8 => y + z, 9 => -y + z, 10 => y - z, 11 => -y - z,
97 12 => y + x, 13 => -y + z, 14 => y - x, _ => -y - z,
98 }
99}
100
101pub fn perlin3(x: f32, y: f32, z: f32) -> f32 {
103 let xi = x.floor() as i32 as usize & 255;
104 let yi = y.floor() as i32 as usize & 255;
105 let zi = z.floor() as i32 as usize & 255;
106 let xf = x - x.floor(); let yf = y - y.floor(); let zf = z - z.floor();
107 let u = fade(xf); let v = fade(yf); let w = fade(zf);
108
109 let aaa = p(p(p(xi)+yi)+zi); let baa = p(p(p(xi+1)+yi)+zi);
110 let aba = p(p(p(xi)+yi+1)+zi); let bba = p(p(p(xi+1)+yi+1)+zi);
111 let aab = p(p(p(xi)+yi)+zi+1); let bab = p(p(p(xi+1)+yi)+zi+1);
112 let abb = p(p(p(xi)+yi+1)+zi+1); let bbb = p(p(p(xi+1)+yi+1)+zi+1);
113
114 let x1 = lerp(grad3(aaa,xf,yf,zf), grad3(baa,xf-1.0,yf,zf), u);
115 let x2 = lerp(grad3(aba,xf,yf-1.0,zf),grad3(bba,xf-1.0,yf-1.0,zf),u);
116 let x3 = lerp(grad3(aab,xf,yf,zf-1.0),grad3(bab,xf-1.0,yf,zf-1.0),u);
117 let x4 = lerp(grad3(abb,xf,yf-1.0,zf-1.0),grad3(bbb,xf-1.0,yf-1.0,zf-1.0),u);
118
119 lerp(lerp(x1, x2, v), lerp(x3, x4, v), w)
120}
121
122const F2: f32 = 0.366025403784439; const G2: f32 = 0.211324865405187; fn grad2s(h: usize, x: f32, y: f32) -> f32 {
130 let h4 = h & 7;
131 let (u, v) = if h4 < 4 { (x, y) } else { (y, x) };
132 let su = if h4 & 1 != 0 { -u } else { u };
133 let sv = if h4 & 2 != 0 { -2.0 * v } else { 2.0 * v };
134 su + sv
135}
136
137pub fn simplex2(x: f32, y: f32) -> f32 {
139 let s = (x + y) * F2;
140 let i = (x + s).floor() as i32;
141 let j = (y + s).floor() as i32;
142 let t = (i + j) as f32 * G2;
143 let x0 = x - (i as f32 - t);
144 let y0 = y - (j as f32 - t);
145
146 let (i1, j1) = if x0 > y0 { (1i32, 0i32) } else { (0i32, 1i32) };
147 let x1 = x0 - i1 as f32 + G2;
148 let y1 = y0 - j1 as f32 + G2;
149 let x2 = x0 - 1.0 + 2.0 * G2;
150 let y2 = y0 - 1.0 + 2.0 * G2;
151
152 let ii = (i & 255) as usize;
153 let jj = (j & 255) as usize;
154 let gi0 = p(ii + p(jj));
155 let gi1 = p(ii + i1 as usize + p(jj + j1 as usize));
156 let gi2 = p(ii + 1 + p(jj + 1));
157
158 let contrib = |gi: usize, dx: f32, dy: f32| -> f32 {
159 let t = 0.5 - dx * dx - dy * dy;
160 if t < 0.0 { 0.0 } else { let t2 = t * t; t2 * t2 * grad2s(gi, dx, dy) }
161 };
162 70.0 * (contrib(gi0, x0, y0) + contrib(gi1, x1, y1) + contrib(gi2, x2, y2))
163}
164
165const F3: f32 = 1.0 / 3.0;
170const G3: f32 = 1.0 / 6.0;
171
172pub fn simplex3(x: f32, y: f32, z: f32) -> f32 {
174 let s = (x + y + z) * F3;
175 let i = (x + s).floor() as i32;
176 let j = (y + s).floor() as i32;
177 let k = (z + s).floor() as i32;
178 let t = (i + j + k) as f32 * G3;
179 let x0 = x - (i as f32 - t);
180 let y0 = y - (j as f32 - t);
181 let z0 = z - (k as f32 - t);
182
183 let (i1,j1,k1,i2,j2,k2) = if x0 >= y0 {
184 if y0 >= z0 { (1,0,0, 1,1,0) } else if x0 >= z0 { (1,0,0, 1,0,1) } else { (0,0,1, 1,0,1) }
185 } else {
186 if y0 < z0 { (0,0,1, 0,1,1) } else if x0 < z0 { (0,1,0, 0,1,1) } else { (0,1,0, 1,1,0) }
187 };
188
189 let g3 = G3;
190 let (x1,y1,z1) = (x0-i1 as f32+g3, y0-j1 as f32+g3, z0-k1 as f32+g3);
191 let (x2,y2,z2) = (x0-i2 as f32+2.0*g3, y0-j2 as f32+2.0*g3, z0-k2 as f32+2.0*g3);
192 let (x3,y3,z3) = (x0-1.0+3.0*g3, y0-1.0+3.0*g3, z0-1.0+3.0*g3);
193
194 let ii = (i & 255) as usize; let jj = (j & 255) as usize; let kk = (k & 255) as usize;
195 let gi0 = p(ii + p(jj + p(kk)));
196 let gi1 = p(ii+i1 as usize + p(jj+j1 as usize + p(kk+k1 as usize)));
197 let gi2 = p(ii+i2 as usize + p(jj+j2 as usize + p(kk+k2 as usize)));
198 let gi3 = p(ii+1 + p(jj+1 + p(kk+1)));
199
200 let contrib = |gi: usize, dx: f32, dy: f32, dz: f32| -> f32 {
201 let t = 0.6 - dx*dx - dy*dy - dz*dz;
202 if t < 0.0 { 0.0 } else { let t2 = t*t; t2*t2*grad3(gi, dx, dy, dz) }
203 };
204 32.0 * (contrib(gi0,x0,y0,z0) + contrib(gi1,x1,y1,z1) + contrib(gi2,x2,y2,z2) + contrib(gi3,x3,y3,z3))
205}
206
207pub fn fbm(x: f32, y: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
217 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
218 for _ in 0..octaves {
219 v += perlin2(x * freq, y * freq) * amp; norm += amp; amp *= persistence; freq *= lacunarity;
220 }
221 v / norm
222}
223
224pub fn fbm3(x: f32, y: f32, z: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
226 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
227 for _ in 0..octaves {
228 v += perlin3(x*freq,y*freq,z*freq) * amp; norm += amp; amp *= persistence; freq *= lacunarity;
229 }
230 v / norm
231}
232
233pub fn fbm_simplex(x: f32, y: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
235 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
236 for _ in 0..octaves {
237 v += simplex2(x*freq, y*freq) * amp; norm += amp; amp *= persistence; freq *= lacunarity;
238 }
239 v / norm
240}
241
242pub fn fbm1(t: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
244 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
245 for _ in 0..octaves {
246 v += perlin1(t * freq) * amp; norm += amp; amp *= persistence; freq *= lacunarity;
247 }
248 v / norm
249}
250
251pub fn ridged(x: f32, y: f32, octaves: u8, lacunarity: f32, gain: f32, offset: f32) -> f32 {
258 let mut value = 0.0f32;
259 let mut freq = 1.0f32;
260 let mut amp = 0.5f32;
261 let mut weight = 1.0f32;
262
263 for _ in 0..octaves {
264 let mut signal = perlin2(x * freq, y * freq);
265 signal = (offset - signal.abs()).powi(2);
266 signal *= weight;
267 weight = (signal * gain).clamp(0.0, 1.0);
268 value += signal * amp;
269 freq *= lacunarity;
270 amp *= 0.5;
271 }
272 value
273}
274
275pub fn ridged3(x: f32, y: f32, z: f32, octaves: u8, lacunarity: f32, gain: f32) -> f32 {
277 let mut value = 0.0f32;
278 let mut freq = 1.0f32;
279 let mut amp = 0.5f32;
280 let mut weight = 1.0f32;
281
282 for _ in 0..octaves {
283 let mut signal = perlin3(x*freq, y*freq, z*freq);
284 signal = (1.0 - signal.abs()).powi(2);
285 signal *= weight;
286 weight = (signal * gain).clamp(0.0, 1.0);
287 value += signal * amp;
288 freq *= lacunarity;
289 amp *= 0.5;
290 }
291 value
292}
293
294pub fn billow(x: f32, y: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
301 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
302 for _ in 0..octaves {
303 v += (perlin2(x*freq, y*freq).abs() * 2.0 - 1.0) * amp;
304 norm += amp; amp *= persistence; freq *= lacunarity;
305 }
306 v / norm
307}
308
309pub fn turbulence1(t: f32, octaves: u8) -> f32 {
315 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
316 for _ in 0..octaves {
317 v += perlin1(t * freq).abs() * amp; norm += amp; amp *= 0.5; freq *= 2.0;
318 }
319 v / norm
320}
321
322pub fn turbulence(x: f32, y: f32, octaves: u8) -> f32 {
324 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
325 for _ in 0..octaves {
326 v += perlin2(x * freq, y * freq).abs() * amp; norm += amp; amp *= 0.5; freq *= 2.0;
327 }
328 v / norm
329}
330
331fn cell_point_2d(ix: i32, iy: i32) -> (f32, f32) {
337 let h = ((ix as i64).wrapping_mul(1031) ^ (iy as i64).wrapping_mul(1099)) as u64;
338 let h = h.wrapping_mul(0x9e3779b97f4a7c15_u64);
339 let px = ((h >> 32) as f32) / u32::MAX as f32;
340 let py = ((h & 0xFFFF_FFFF) as f32) / u32::MAX as f32;
341 (ix as f32 + px, iy as f32 + py)
342}
343
344fn cell_point_3d(ix: i32, iy: i32, iz: i32) -> (f32, f32, f32) {
346 let h = ((ix as i64).wrapping_mul(1031)
347 ^ (iy as i64).wrapping_mul(1099)
348 ^ (iz as i64).wrapping_mul(853)) as u64;
349 let h1 = h.wrapping_mul(0x9e3779b97f4a7c15_u64);
350 let h2 = h1.wrapping_mul(0x6c62272e07bb0142_u64);
351 let h3 = h2.wrapping_mul(0x62b821756295c58d_u64);
352 (
353 ix as f32 + (h1 >> 32) as f32 / u32::MAX as f32,
354 iy as f32 + (h2 >> 32) as f32 / u32::MAX as f32,
355 iz as f32 + (h3 >> 32) as f32 / u32::MAX as f32,
356 )
357}
358
359pub fn worley2(x: f32, y: f32) -> (f32, f32) {
362 let ix = x.floor() as i32;
363 let iy = y.floor() as i32;
364 let mut f1 = f32::MAX;
365 let mut f2 = f32::MAX;
366 for dy in -2..=2i32 {
367 for dx in -2..=2i32 {
368 let (px, py) = cell_point_2d(ix + dx, iy + dy);
369 let d = ((x - px).powi(2) + (y - py).powi(2)).sqrt();
370 if d < f1 { f2 = f1; f1 = d; } else if d < f2 { f2 = d; }
371 }
372 }
373 (f1, f2)
374}
375
376pub fn worley3(x: f32, y: f32, z: f32) -> (f32, f32) {
378 let ix = x.floor() as i32; let iy = y.floor() as i32; let iz = z.floor() as i32;
379 let mut f1 = f32::MAX; let mut f2 = f32::MAX;
380 for dz in -2..=2i32 { for dy in -2..=2i32 { for dx in -2..=2i32 {
381 let (px,py,pz) = cell_point_3d(ix+dx, iy+dy, iz+dz);
382 let d = ((x-px).powi(2)+(y-py).powi(2)+(z-pz).powi(2)).sqrt();
383 if d < f1 { f2 = f1; f1 = d; } else if d < f2 { f2 = d; }
384 }}}
385 (f1, f2)
386}
387
388pub fn worley_f1(x: f32, y: f32) -> f32 { worley2(x, y).0.clamp(0.0, 1.0) }
390
391pub fn worley_crackle(x: f32, y: f32) -> f32 { let (f1,f2) = worley2(x,y); (f2-f1).clamp(0.0,1.0) }
393
394pub fn worley_fbm(x: f32, y: f32, octaves: u8, persistence: f32, lacunarity: f32) -> f32 {
396 let mut v = 0.0f32; let mut amp = 1.0f32; let mut freq = 1.0f32; let mut norm = 0.0f32;
397 for _ in 0..octaves {
398 let (f1, _) = worley2(x * freq, y * freq);
399 v += f1 * amp; norm += amp; amp *= persistence; freq *= lacunarity;
400 }
401 v / norm
402}
403
404pub fn curl2(x: f32, y: f32, frequency: f32) -> Vec2 {
411 let eps = 0.001f32;
412 let f = frequency;
413 let dndx = (perlin2((x+eps)*f, y*f) - perlin2((x-eps)*f, y*f)) / (2.0*eps);
414 let dndy = (perlin2(x*f, (y+eps)*f) - perlin2(x*f, (y-eps)*f)) / (2.0*eps);
415 Vec2::new(dndy, -dndx)
417}
418
419pub fn curl2_fbm(x: f32, y: f32, frequency: f32, octaves: u8) -> Vec2 {
421 let eps = 0.001f32;
422 let f = frequency;
423 let noise = |nx: f32, ny: f32| fbm(nx, ny, octaves, 0.5, 2.0);
424 let dndx = (noise((x+eps)*f, y*f) - noise((x-eps)*f, y*f)) / (2.0*eps);
425 let dndy = (noise(x*f, (y+eps)*f) - noise(x*f, (y-eps)*f)) / (2.0*eps);
426 Vec2::new(dndy, -dndx)
427}
428
429pub fn curl3(pos: Vec3, frequency: f32) -> Vec3 {
432 let eps = 0.001f32;
433 let f = frequency;
434 let (x,y,z) = (pos.x, pos.y, pos.z);
435
436 let px = |a: f32, b: f32, c: f32| perlin3(a*f + 7.3, b*f + 1.7, c*f + 4.1);
438 let py = |a: f32, b: f32, c: f32| perlin3(a*f + 2.9, b*f + 8.5, c*f + 3.2);
439 let pz = |a: f32, b: f32, c: f32| perlin3(a*f + 5.1, b*f + 6.3, c*f + 9.7);
440
441 let dpz_dy = (pz(x,y+eps,z) - pz(x,y-eps,z)) / (2.0*eps);
443 let dpy_dz = (py(x,y,z+eps) - py(x,y,z-eps)) / (2.0*eps);
444 let dpx_dz = (px(x,y,z+eps) - px(x,y,z-eps)) / (2.0*eps);
445 let dpz_dx = (pz(x+eps,y,z) - pz(x-eps,y,z)) / (2.0*eps);
446 let dpy_dx = (py(x+eps,y,z) - py(x-eps,y,z)) / (2.0*eps);
447 let dpx_dy = (px(x,y+eps,z) - px(x,y-eps,z)) / (2.0*eps);
448
449 Vec3::new(dpz_dy - dpy_dz, dpx_dz - dpz_dx, dpy_dx - dpx_dy)
450}
451
452pub fn domain_warp(x: f32, y: f32, octaves: u8, warp_strength: f32) -> f32 {
460 let qx = fbm(x, y, octaves, 0.5, 2.0);
461 let qy = fbm(x + 5.2, y + 1.3, octaves, 0.5, 2.0);
462 let rx = fbm(x + warp_strength * qx + 1.7, y + warp_strength * qy + 9.2, octaves, 0.5, 2.0);
463 let ry = fbm(x + warp_strength * qx + 8.3, y + warp_strength * qy + 2.8, octaves, 0.5, 2.0);
464 fbm(x + warp_strength * rx, y + warp_strength * ry, octaves, 0.5, 2.0)
465}
466
467pub fn domain_warp2(x: f32, y: f32, octaves: u8, strength: f32) -> f32 {
469 let w1 = domain_warp(x, y, octaves, strength * 0.5);
470 domain_warp(x + w1 * strength, y + w1 * strength * 0.7, octaves, strength * 0.5)
471}
472
473pub fn domain_warp3(pos: Vec3, octaves: u8, strength: f32) -> f32 {
475 let qx = perlin3(pos.x, pos.y, pos.z);
476 let qy = perlin3(pos.x + 3.7, pos.y + 1.9, pos.z + 7.1);
477 let qz = perlin3(pos.x + 8.2, pos.y + 5.4, pos.z + 2.3);
478 fbm3(pos.x + strength * qx, pos.y + strength * qy, pos.z + strength * qz,
479 octaves, 0.5, 2.0)
480}
481
482pub fn noise1(t: f32) -> f32 {
488 let i = t.floor() as i64;
489 let f = t - t.floor();
490 let a = hash_1d(i);
491 let b = hash_1d(i + 1);
492 lerp(a, b, fade(f))
493}
494
495fn hash_1d(i: i64) -> f32 {
496 let x = (i ^ (i >> 13)) as u64;
497 let x = x.wrapping_mul(0x9e3779b97f4a7c15);
498 ((x >> 32) as f32) / u32::MAX as f32
499}
500
501pub fn tiled_perlin2(x: f32, y: f32, tile_w: u32, tile_h: u32) -> f32 {
508 let tw = tile_w as usize;
509 let th = tile_h as usize;
510 let xi = x.floor() as i32 as usize;
511 let yi = y.floor() as i32 as usize;
512 let xf = x - x.floor();
513 let yf = y - y.floor();
514 let u = fade(xf); let v = fade(yf);
515 let aa = p(p(xi % tw) + yi % th);
516 let ba = p(p((xi+1) % tw) + yi % th);
517 let ab = p(p(xi % tw) + (yi+1) % th);
518 let bb = p(p((xi+1) % tw) + (yi+1) % th);
519 lerp(
520 lerp(grad2(aa, xf, yf), grad2(ba, xf-1.0, yf), u),
521 lerp(grad2(ab, xf, yf-1.0), grad2(bb, xf-1.0, yf-1.0), u),
522 v,
523 )
524}
525
526#[inline] pub fn to_01(n: f32) -> f32 { n * 0.5 + 0.5 }
532#[inline] pub fn from_01(n: f32) -> f32 { n * 2.0 - 1.0 }
534
535pub fn sample3(pos: Vec3, frequency: f32) -> f32 {
537 perlin3(pos.x * frequency, pos.y * frequency, pos.z * frequency)
538}
539
540pub fn sample_fbm3(pos: Vec3, frequency: f32, octaves: u8) -> f32 {
542 fbm3(pos.x*frequency, pos.y*frequency, pos.z*frequency, octaves, 0.5, 2.0)
543}
544
545pub fn sample_curl3(pos: Vec3, frequency: f32) -> Vec3 { curl3(pos, frequency) }
547
548pub fn quick_noise(x: f32, y: f32) -> f32 {
551 to_01(fbm(x, y, 4, 0.5, 2.0))
552}
553
554pub fn animated_noise(x: f32, y: f32, time: f32, frequency: f32, octaves: u8) -> f32 {
557 fbm3(x * frequency, y * frequency, time * 0.1, octaves, 0.5, 2.0)
558}
559
560pub fn gradient_2d(x: f32, y: f32, frequency: f32) -> Vec2 {
562 let eps = 0.001f32;
563 let f = frequency;
564 let dndx = (perlin2((x+eps)*f, y*f) - perlin2((x-eps)*f, y*f)) / (2.0*eps);
565 let dndy = (perlin2(x*f, (y+eps)*f) - perlin2(x*f, (y-eps)*f)) / (2.0*eps);
566 Vec2::new(dndx, dndy)
567}
568
569pub fn gradient_3d(pos: Vec3, frequency: f32) -> Vec3 {
571 let eps = 0.001f32;
572 let f = frequency;
573 let (x,y,z) = (pos.x, pos.y, pos.z);
574 let gx = (perlin3((x+eps)*f,y*f,z*f) - perlin3((x-eps)*f,y*f,z*f)) / (2.0*eps);
575 let gy = (perlin3(x*f,(y+eps)*f,z*f) - perlin3(x*f,(y-eps)*f,z*f)) / (2.0*eps);
576 let gz = (perlin3(x*f,y*f,(z+eps)*f) - perlin3(x*f,y*f,(z-eps)*f)) / (2.0*eps);
577 Vec3::new(gx, gy, gz)
578}