random.wgsl

webgpu-based path tracer

src/shaders/random.wgsl

1.22 KB
fn init_random(state: ptr<function, u32>, value: u32) {
    * state ^= value;
    * state = pcg(*state);
}

fn pcg(n: u32) -> u32 {
    var h = n * 747796405u + 2891336453u;
    h = ((h >> ((h >> 28u) + 4u)) ^ h) * 277803737u;
    return (h >> 22u) ^ h;
}

fn uniform_uint(state: ptr<function, u32>, max: u32) -> u32 {
    * state = pcg(*state);
    return * state % max;
}

fn uniform_float(state: ptr<function, u32>) -> f32 {
    * state = pcg(*state);
    return f32(*state) / 4294967295.0;
}

fn animated_blue_noise(coord: vec2<i32>, frame_count: u32, frame_count_cycle: u32) -> vec2f {
    // spatial 
    let tex_size = vec2<u32>(textureDimensions(blueNoiseTexture).xy);
    let wrapped_coord = vec2<i32>((coord.x % i32(tex_size.x) + i32(tex_size.x)) % i32(tex_size.x), (coord.y % i32(tex_size.y) + i32(tex_size.y)) % i32(tex_size.y));
    let blue_noise = textureLoad(blueNoiseTexture, wrapped_coord).xy;
    let idx = (f32(wrapped_coord.y) % blue_noise.y) * blue_noise.x + (f32(wrapped_coord.x) % blue_noise.x);
    // temporal
    let n = frame_count % frame_count_cycle;
    let a1 = 0.7548776662466927f;
    let a2 = 0.5698402909980532f;
    let r2_seq = fract(vec2(a1 * f32(n), a2 * f32(n)));
    return fract(blue_noise + r2_seq);
}