Search code examples
shadermetal

metal shader language random numbers


In metal shader language , using metals standard library for functions is pretty straightforward eg, a step within a fragment function can be called:

float borderRed = step(150, position.x);

What Im trying to find is any kind of metal function that return a random number (preferably between 0.0 and 1.0) which is along the same usage lines as fract floor e.t.c

anyone know of one?


Solution

  • I ported the pseudo-random Gold Noise to Metal. It will produce "random" values per frame provided you pass it a unique number each pass for the seed parameter.

    For instance, you can pass your shader a frame counter, a time stamp or one random number to use for the seed.

    If you want the same initial "random" values, just use the same seed.

    // Gold Noise ©2015 [email protected]
    //  - based on the Golden Ratio, PI and Square Root of Two
    //  - superior distribution
    //  - fastest noise generator function
    
    constant float PHI = 1.61803398874989484820459 * 00000.1; // Golden Ratio
    constant float PI_factor  = 3.14159265358979323846264 * 00000.1; // PI
    constant float SQ2 = 1.41421356237309504880169 * 10000.0; // Square Root of Two
    
    //Note: I added `* 00000.1` and `* 10000.0` because IIRC I was getting overflows.
    
    float goldNoise(float2 coordinate, float seed) {
        return fract(tan(distance(coordinate * (seed + PHI), float2(PHI, PI_factor))) * SQ2);
    }
    

    I use this too, with xy from the shader and a different seed per pass:

    float rand0to1(int x, int y, int passSeed)
    {
        int seed = x + y * 57 + passSeed * 241;
        seed = (seed<< 13) ^ seed;
        return (( 1.f - ( (seed * (seed * seed * 15731 + 789221) + 1376312589) & 2147483647) / 1073741824.0f) + 1.0f) / 2.0f;
    }