114 lines
2.3 KiB
HLSL
114 lines
2.3 KiB
HLSL
#ifndef RANDOM_HLSL
|
||
#define RANDOM_HLSL
|
||
|
||
// https://jcgt.org/published/0009/03/02/supplementary.pdf#page=49
|
||
uint Pcg1D(uint v)
|
||
{
|
||
uint state = v * 747796405u + 2891336453u;
|
||
uint word = ((state >> ((state >> 28u) + 4u)) ˆ state) * 277803737u;
|
||
return (word >> 22u) ˆ word;
|
||
}
|
||
|
||
// https://jcgt.org/published/0009/03/02/supplementary.pdf#page=52
|
||
uint2 Pcg2D(uint2 v)
|
||
{
|
||
v = v * 1664525u + 1013904223u;
|
||
v.x += v.y * 1664525u;
|
||
v.y += v.x * 1664525u;
|
||
v = v ˆ(v >> 16u);
|
||
v.x += v.y * 1664525u;
|
||
v.y += v.x * 1664525u;
|
||
v = v ˆ(v >> 16u);
|
||
return v;
|
||
}
|
||
|
||
// https://jcgt.org/published/0009/03/02/supplementary.pdf#page=53
|
||
uint3 Pcg3D(uint3 v)
|
||
{
|
||
v = v * 1664525u + 1013904223u;
|
||
v.x += v.y*v.z;
|
||
v.y += v.z*v.x;
|
||
v.z += v.x*v.y;
|
||
v = v ˆ(v >> 16u);
|
||
v.x += v.y*v.z;
|
||
v.y += v.z*v.x;
|
||
v.z += v.x*v.y;
|
||
return v;
|
||
}
|
||
|
||
// https://jcgt.org/published/0009/03/02/supplementary.pdf#page=55
|
||
uint4 Pcg4D(uint4 v)
|
||
{
|
||
v = v * 1664525u + 1013904223u;
|
||
v.x += v.y*v.w;
|
||
v.y += v.z*v.x;
|
||
v.z += v.x*v.y;
|
||
v.w += v.y*v.z;
|
||
v = v ˆ(v >> 16u);
|
||
v.x += v.y*v.w;
|
||
v.y += v.z*v.x;
|
||
v.z += v.x*v.y;
|
||
v.w += v.y*v.z;
|
||
return v;
|
||
}
|
||
|
||
struct Rng
|
||
{
|
||
uint4 state;
|
||
};
|
||
Rng Rng_FromThread(uint3 tid, uint seed)
|
||
{
|
||
Rng rng;
|
||
rng.state = uint4(tid.xyz, seed);
|
||
return rng;
|
||
}
|
||
Rng Rng_FromCoord(uint2 xy, uint seed)
|
||
{
|
||
return Rng_FromThread(uint3(xy, 0), seed);
|
||
}
|
||
Rng Rng_FromUv(float2 uv, uint2 size, uint seed)
|
||
{
|
||
return Rng_FromCoord(uint2(uv * size + 0.5), seed);
|
||
}
|
||
|
||
uint4 Rng_SampleUint4(inout Rng rng)
|
||
{
|
||
rng.state = Pcg4D(rng.state);
|
||
return rng.state;
|
||
}
|
||
uint3 Rng_SampleUint3(inout Rng rng)
|
||
{
|
||
rng.state = Pcg4D(rng.state);
|
||
return rng.state.xyz;
|
||
}
|
||
uint2 Rng_SampleUint2(inout Rng rng)
|
||
{
|
||
rng.state = Pcg4D(rng.state);
|
||
return rng.state.xy;
|
||
}
|
||
uint Rng_SampleUint(inout Rng rng)
|
||
{
|
||
rng.state = Pcg4D(rng.state);
|
||
return rng.state.x;
|
||
}
|
||
|
||
float4 Rng_SampleFloat4(inout Rng rng)
|
||
{
|
||
return (Rng_SampleUint4(rng) & 0xffffff) * (1.0 / 0xffffff);
|
||
}
|
||
float3 Rng_SampleFloat3(inout Rng rng)
|
||
{
|
||
return (Rng_SampleUint3(rng) & 0xffffff) * (1.0 / 0xffffff);
|
||
}
|
||
float2 Rng_SampleFloat2(inout Rng rng)
|
||
{
|
||
return (Rng_SampleUint2(rng) & 0xffffff) * (1.0 / 0xffffff);
|
||
}
|
||
float Rng_SampleFloat(inout Rng rng)
|
||
{
|
||
return (Rng_SampleUint(rng) & 0xffffff) * (1.0 / 0xffffff);
|
||
}
|
||
|
||
|
||
#endif // RANDOM_HLSL
|