forked from vv/efemra
1
0
Fork 0
efemra/src/shaders/random.hlsl

114 lines
2.3 KiB
HLSL
Raw Normal View History

#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