2019年7月6日土曜日

Pseudo Random Number Generator for GPUs

I slightly modify a method in a Nathan's post.
//From https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key/12996028#12996028
//It seems that a hash function for seeding don't make an impact.
uint hash(uint x)
{
    x = ((x >> 16) ^ x) * 0x119de1f3;
    x = ((x >> 16) ^ x) * 0x119de1f3;
    x = (x >> 16) ^ x;
    return x;
}

uint xorshift32_state;

void xorshift32_srand(uint seed)
{
    xorshift32_state = hash(seed);
}

uint xorshift32_rand()
{
    xorshift32_state ^= xorshift32_state << 13;
 xorshift32_state ^= xorshift32_state >> 17;
 xorshift32_state ^= xorshift32_state << 5;
 return xorshift32_state;
}

float xorshift32_frand()
{
    return float(xorshift32_rand()) * (1.0 / 4294967296.0);
}

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width,height;
    textureResult.GetDimensions(width, height);

    xorshift32_srand(id.x+id.y*width);
    textureResult[id.xy] = xorshift32_frand();
}