1pub const BLUE_NOISE_SIZE: u32 = 64;
2pub static BLUE_NOISE: &[u8] = include_bytes!("blue_noise.bin");
3
4const BAYER8: [u8; 64] = [
5 0, 32, 8, 40, 2, 34, 10, 42, 48, 16, 56, 24, 50, 18, 58, 26, 12, 44, 4, 36, 14, 46, 6, 38, 60,
6 28, 52, 20, 62, 30, 54, 22, 3, 35, 11, 43, 1, 33, 9, 41, 51, 19, 59, 27, 49, 17, 57, 25, 15,
7 47, 7, 39, 13, 45, 5, 37, 63, 31, 55, 23, 61, 29, 53, 21,
8];
9
10pub fn grain_hash(x: u32, y: u32, seed: u32) -> f32 {
11 let mut h =
12 x.wrapping_mul(0x8da6_b343) ^ y.wrapping_mul(0xd816_3841) ^ seed.wrapping_mul(0xcb1a_b31f);
13 h ^= h >> 15;
14 h = h.wrapping_mul(0x2c1b_3c6d);
15 h ^= h >> 12;
16 (h >> 8) as f32 / 16_777_216.0
17}
18
19pub fn mixed(seed: u32, frame: u32) -> u32 {
20 seed ^ frame.wrapping_mul(0x9e37_79b9)
21}
22
23pub fn hash21(x: f32, y: f32) -> f32 {
24 let mut qx = (x * 123.34).fract();
25 let mut qy = (y * 456.21).fract();
26 let d = qx * (qx + 45.32) + qy * (qy + 45.32);
27 qx += d;
28 qy += d;
29 (qx * qy).fract()
30}
31
32pub fn bayer(x: u32, y: u32) -> f32 {
33 let v = BAYER8[((y & 7) * 8 + (x & 7)) as usize];
34 (v as f32 + 0.5) / 64.0
35}
36
37pub fn blue_noise(x: u32, y: u32) -> f32 {
38 let n = BLUE_NOISE_SIZE;
39 let i = ((y % n) * n + (x % n)) as usize;
40 BLUE_NOISE[i] as f32 / 255.0
41}
42
43pub fn value_noise(x: f32, y: f32, seed: u32) -> f32 {
44 let x0 = x.floor();
45 let y0 = y.floor();
46 let tx = {
47 let t = x - x0;
48 t * t * (3.0 - 2.0 * t)
49 };
50 let ty = {
51 let t = y - y0;
52 t * t * (3.0 - 2.0 * t)
53 };
54 let xi = x0 as i32;
55 let yi = y0 as i32;
56 let h = |i: i32, j: i32| grain_hash(i as u32, j as u32, seed);
57 let a = h(xi, yi);
58 let b = h(xi + 1, yi);
59 let c = h(xi, yi + 1);
60 let d = h(xi + 1, yi + 1);
61 let ab = a + (b - a) * tx;
62 let cd = c + (d - c) * tx;
63 ab + (cd - ab) * ty
64}