Random.hlsl 2.8 KB

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