111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
| #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
 |