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

114 lines
2.3 KiB
HLSL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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