Skip to main content

pfx_post/
hash.rs

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}