Random.hlsl 2.6 KB

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