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)) <EFBFBD> state) * 277803737u;
|
|||
|
return (word >> 22u) <EFBFBD> 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 <EFBFBD>(v >> 16u);
|
|||
|
v.x += v.y * 1664525u;
|
|||
|
v.y += v.x * 1664525u;
|
|||
|
v = v <EFBFBD>(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 <EFBFBD>(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 <EFBFBD>(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
|