123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #ifndef UNITY_RANDOM_INCLUDED
- #define UNITY_RANDOM_INCLUDED
- // Safe for GLES2: HLSLcc will emulate the missing operator ^, >> and rcp
- float Hash(uint s)
- {
- s = s ^ 2747636419u;
- s = s * 2654435769u;
- s = s ^ (s >> 16);
- s = s * 2654435769u;
- s = s ^ (s >> 16);
- s = s * 2654435769u;
- return float(s) * rcp(4294967296.0); // 2^-32
- }
- #if !defined(SHADER_API_GLES)
- // A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm.
- uint JenkinsHash(uint x)
- {
- x += (x << 10u);
- x ^= (x >> 6u);
- x += (x << 3u);
- x ^= (x >> 11u);
- x += (x << 15u);
- return x;
- }
- // Compound versions of the hashing algorithm.
- uint JenkinsHash(uint2 v)
- {
- return JenkinsHash(v.x ^ JenkinsHash(v.y));
- }
- uint JenkinsHash(uint3 v)
- {
- return JenkinsHash(v.x ^ JenkinsHash(v.yz));
- }
- uint JenkinsHash(uint4 v)
- {
- return JenkinsHash(v.x ^ JenkinsHash(v.yzw));
- }
- // Construct a float with half-open range [0, 1) using low 23 bits.
- // All zeros yields 0, all ones yields the next smallest representable value below 1.
- float ConstructFloat(int m) {
- const int ieeeMantissa = 0x007FFFFF; // Binary FP32 mantissa bitmask
- const int ieeeOne = 0x3F800000; // 1.0 in FP32 IEEE
- m &= ieeeMantissa; // Keep only mantissa bits (fractional part)
- m |= ieeeOne; // Add fractional part to 1.0
- float f = asfloat(m); // Range [1, 2)
- return f - 1; // Range [0, 1)
- }
- float ConstructFloat(uint m)
- {
- return ConstructFloat(asint(m));
- }
- // Pseudo-random value in half-open range [0, 1). The distribution is reasonably uniform.
- // Ref: https://stackoverflow.com/a/17479300
- float GenerateHashedRandomFloat(uint x)
- {
- return ConstructFloat(JenkinsHash(x));
- }
- float GenerateHashedRandomFloat(uint2 v)
- {
- return ConstructFloat(JenkinsHash(v));
- }
- float GenerateHashedRandomFloat(uint3 v)
- {
- return ConstructFloat(JenkinsHash(v));
- }
- float GenerateHashedRandomFloat(uint4 v)
- {
- return ConstructFloat(JenkinsHash(v));
- }
- float2 InitRandom(float2 input)
- {
- float2 r;
- r.x = Hash(uint(input.x * UINT_MAX));
- r.y = Hash(uint(input.y * UINT_MAX));
- return r;
- }
- #endif // SHADER_API_GLES
- //From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
- // http://advances.realtimerendering.com/s2014/index.html
- float InterleavedGradientNoise(float2 pixCoord, int frameCount)
- {
- const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
- float2 frameMagicScale = float2(2.083f, 4.867f);
- pixCoord += frameCount * frameMagicScale;
- return frac(magic.z * frac(dot(pixCoord, magic.xy)));
- }
- // 32-bit Xorshift random number generator
- uint XorShift(inout uint rngState)
- {
- rngState ^= rngState << 13;
- rngState ^= rngState >> 17;
- rngState ^= rngState << 5;
- return rngState;
- }
- #endif // UNITY_RANDOM_INCLUDED
|