You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.8 KiB
114 lines
2.8 KiB
#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
|
|
|