PDA

View Full Version : simple fast PRNG's

mireazma
10-01-2013, 10:44 AM
I've been (re)searching for a prng on the web. I came up with the following (excuse my syntax -- I'm a newbie in shading):

A few depending on bitwise operations:
1.

float rnd(vec2 v)
{
int n = int(v.x * 40.0 + v.y * 6400.0);
n = (n << 13) ^ n;
return 1.0 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0;
}
It supposedly returns normalized values.

2.

int LFSR_Rand_Gen(int n)
{
n = (n << 13) ^ n;
return (n * (n*n*15731+789221) + 1376312589) & 0x7fffffff;
}

This belongs to George Marsaglia (hope I've written the code right):

3.

int rando(ivec2 p)
{
p.x = 36969*(p.x & 65535) + (p.x >> 16);
p.y = 18000*(p.y & 65535) + (p.y >> 16);
return (p.x << 16) + p.y;
}

There also is the xorshift (http://en.wikipedia.org/wiki/Xorshift) but uses static vars.

I can't enable the appropriate extension in my software. I didn't want it anyway as I like to keep things simple. And I don't want such a large period / perfect distribution, either.

Here's one of unknown origin which looks suspicious due to the sin() for which reason I'll refrain from using it, namely "one-liner":

4.

float rand(vec2 co)
{
return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
}

and finally, the most fitted prng for myself that I found was (*rolling drums*):

Lehmer random number generator, which accepts different setup values from which I chose:

5.

int lcg_rand(int a)
{
return (a * 75) % 65537;
}

The trouble with this last prng (and not only) is that the returned value must be saved as the seed for the next call.
So, how can it be saved? Is there a static qualifier or some workaround, so the function could be called from within the fragment shader and each subsequent call to set the "static" seed for the next?
OR
Does anybody know of a fast short prng which pops the random number based on, say, one of the texCoord floats?
Or any other ideas?

The whole idea goes towards generating fast 1D / 2D noise with under 10 lines code.