#ifndef UNITY_RANDOM_INCLUDED #define UNITY_RANDOM_INCLUDED 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 } // 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; } //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