A game about forced loneliness, made by TACStudios
1#ifndef UNITY_RANDOM_INCLUDED
2#define UNITY_RANDOM_INCLUDED
3
4float Hash(uint s)
5{
6 s = s ^ 2747636419u;
7 s = s * 2654435769u;
8 s = s ^ (s >> 16);
9 s = s * 2654435769u;
10 s = s ^ (s >> 16);
11 s = s * 2654435769u;
12 return float(s) * rcp(4294967296.0); // 2^-32
13}
14
15// A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm.
16uint JenkinsHash(uint x)
17{
18 x += (x << 10u);
19 x ^= (x >> 6u);
20 x += (x << 3u);
21 x ^= (x >> 11u);
22 x += (x << 15u);
23 return x;
24}
25
26// Compound versions of the hashing algorithm.
27uint JenkinsHash(uint2 v)
28{
29 return JenkinsHash(v.x ^ JenkinsHash(v.y));
30}
31
32uint JenkinsHash(uint3 v)
33{
34 return JenkinsHash(v.x ^ JenkinsHash(v.yz));
35}
36
37uint JenkinsHash(uint4 v)
38{
39 return JenkinsHash(v.x ^ JenkinsHash(v.yzw));
40}
41
42// Construct a float with half-open range [0, 1) using low 23 bits.
43// All zeros yields 0, all ones yields the next smallest representable value below 1.
44float ConstructFloat(int m) {
45 const int ieeeMantissa = 0x007FFFFF; // Binary FP32 mantissa bitmask
46 const int ieeeOne = 0x3F800000; // 1.0 in FP32 IEEE
47
48 m &= ieeeMantissa; // Keep only mantissa bits (fractional part)
49 m |= ieeeOne; // Add fractional part to 1.0
50
51 float f = asfloat(m); // Range [1, 2)
52 return f - 1; // Range [0, 1)
53}
54
55float ConstructFloat(uint m)
56{
57 return ConstructFloat(asint(m));
58}
59
60// Pseudo-random value in half-open range [0, 1). The distribution is reasonably uniform.
61// Ref: https://stackoverflow.com/a/17479300
62float GenerateHashedRandomFloat(uint x)
63{
64 return ConstructFloat(JenkinsHash(x));
65}
66
67float GenerateHashedRandomFloat(uint2 v)
68{
69 return ConstructFloat(JenkinsHash(v));
70}
71
72float GenerateHashedRandomFloat(uint3 v)
73{
74 return ConstructFloat(JenkinsHash(v));
75}
76
77float GenerateHashedRandomFloat(uint4 v)
78{
79 return ConstructFloat(JenkinsHash(v));
80}
81
82float2 InitRandom(float2 input)
83{
84 float2 r;
85 r.x = Hash(uint(input.x * UINT_MAX));
86 r.y = Hash(uint(input.y * UINT_MAX));
87
88 return r;
89}
90
91//From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
92// http://advances.realtimerendering.com/s2014/index.html
93float InterleavedGradientNoise(float2 pixCoord, int frameCount)
94{
95 const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
96 float2 frameMagicScale = float2(2.083f, 4.867f);
97 pixCoord += frameCount * frameMagicScale;
98 return frac(magic.z * frac(dot(pixCoord, magic.xy)));
99}
100
101// 32-bit Xorshift random number generator
102uint XorShift(inout uint rngState)
103{
104 rngState ^= rngState << 13;
105 rngState ^= rngState >> 17;
106 rngState ^= rngState << 5;
107 return rngState;
108}
109
110#endif // UNITY_RANDOM_INCLUDED