Skip to content

Instantly share code, notes, and snippets.

@mattdesl
Last active July 2, 2024 14:30
Show Gist options
  • Save mattdesl/e72d39a1d80b3c1faca81d7425903715 to your computer and use it in GitHub Desktop.
Save mattdesl/e72d39a1d80b3c1faca81d7425903715 to your computer and use it in GitHub Desktop.
high quality deterministic PRNG in WebGPU & WGSL (xorshift128) - MIT licensed
// each pixel is assigned 4 random u32 values per frame
@group(0) @binding(1)
var<storage, read> rnd_state: array<u32>;
// the current state within this pixel
var<private> local_rnd_state:vec4u;
fn random_u32(state:ptr<private,vec4u>) -> u32 {
var st:vec4u = *state;
/* Algorithm "xor128" from p. 5 of Marsaglia, "Xorshift RNGs" */
// Load the state from the storage buffer
var t: u32 = st.w;
var s: u32 = st.x;
t ^= t << 11;
t ^= t >> 8;
var x:u32 = t ^ s ^ (s >> 19);
*state = vec4u(
x, s, st.y, st.z
);
return x;
}
fn random() -> f32 {
return f32(random_u32(&local_rnd_state)) / 0x100000000;
}
fn my_main () {
var idx:u32 = /* index of this pixel into your rnd_state buffer */;
// each pixel is assigned its own set of 4 random u32 for xorshift
// then this is stored in a local private space, so that each time
// random() is called, state will be shifted forward with xorshift
local_rnd_state = vec4u(
rnd_state[idx * 4 + 0],
rnd_state[idx * 4 + 1],
rnd_state[idx * 4 + 2],
rnd_state[idx * 4 + 3]
);
// now you are ready to call random() as many times as you like!
out_color = vec4(
random(),
random(),
random(),
1.0
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment