How to use a random number within WGSL?

1.5k Views Asked by At

I'm trying to create a fragment shader in a WebGPU application for rendering a black white image noise.

White_noise (wikipedia)

For this I just want each pixel to have a random color value like this:

[[stage(fragment)]]
fn main() -> [[location(0)]] vec4<f32> {
  let color: f32 = random();
  return vec4<f32>(color, color, color, 1.0);
}

But WGSL does not seem to provide a function that returns random numbers. At least I could not find anything in the specifications.

Is there a way to get random numbers into the fragment shader for each fragment?

2

There are 2 best solutions below

0
On BEST ANSWER

There is no random functionality in WGSL or GLSL, so you have to implement your own RNG. There are different approaches to implement it either via CPU generated numbers and feed into the shader via an uniform or via algorithm within the shader, as @skmr has described.

On possible algorithm could be: https://indico.cern.ch/event/93877/contributions/2118070/attachments/1104200/1575343/acat3_revised_final.pdf

1
On

I hit the same problem when porting some parallel code from CUDA (which provides cuRand) to OpenCL a number of years ago. I found a very nice solution in the random123 library: https://github.com/DEShawResearch/random123. This library provides a number of "counter-based random number generators," which are functions that provide the Nth pseudo-random number in a sequence when passed the index N (as opposed to traditional RNGs that compute the next value from the previous value, and so are not parallelizable).

Update: I have ported the "threefry2x32" random number generator (from the random123 library) from C to javascript/WGSL and it works nicely. I plan to correspond with the random123 author/maintainer to see if they might like to integrate this into their repository. I want to be sure not to run afoul of their copyright.