Noise.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "Noise.h"
  2. using namespace CurlNoise;
  3. static const unsigned int s_kHashIndexMask = 255;
  4. static const unsigned int s_kGradientIndexMask = 15;
  5. // Repeat perlin's permutation of [0, 255] twice so we don't need to use the mod operator while indexing
  6. static const int s_Hash[] =
  7. {
  8. 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
  9. 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
  10. 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
  11. 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
  12. 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
  13. 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
  14. 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
  15. 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
  16. 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
  17. 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
  18. 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
  19. 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
  20. 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
  21. 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
  22. 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
  23. 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180,
  24. 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
  25. 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
  26. 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
  27. 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
  28. 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
  29. 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
  30. 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
  31. 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
  32. 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
  33. 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
  34. 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
  35. 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
  36. 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
  37. 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
  38. 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
  39. 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180
  40. };
  41. static const Vector3 s_Gradients3D[] =
  42. {
  43. // center of cube to center of each of the 12 edges of a cube
  44. Vector3(1.0f, 1.0f, 0.0f),
  45. Vector3(-1.0f, 1.0f, 0.0f),
  46. Vector3(1.0f,-1.0f, 0.0f),
  47. Vector3(-1.0f,-1.0f, 0.0f),
  48. Vector3(1.0f, 0.0f, 1.0f),
  49. Vector3(-1.0f, 0.0f, 1.0f),
  50. Vector3(1.0f, 0.0f,-1.0f),
  51. Vector3(-1.0f, 0.0f,-1.0f),
  52. Vector3(0.0f, 1.0f, 1.0f),
  53. Vector3(0.0f,-1.0f, 1.0f),
  54. Vector3(0.0f, 1.0f,-1.0f),
  55. Vector3(0.0f,-1.0f,-1.0f),
  56. // Repeat some to skew distribution
  57. Vector3(1.0f, 1.0f, 0.0f),
  58. Vector3(-1.0f, 1.0f, 0.0f),
  59. Vector3(0.0f,-1.0f, 1.0f),
  60. Vector3(0.0f,-1.0f,-1.0f)
  61. };
  62. //-----------------------------------------------------------------------------------------------
  63. // The PerlinNoise3 implementation calculates a noise value in the range [-1f, 1f] given a 3D position & frequency.
  64. // It also calculates the analytical derivative (change wrt x, y & z) which can be used to quickly calculate the curl,
  65. // when the potential field doesn't need to be modified.
  66. NoiseSample
  67. PerlinNoise3::EvaluateNoise(const Vector3& point, float frequency)
  68. {
  69. Vector3 p = point * frequency;
  70. int ix0 = static_cast<int> ( floorf(p.getX()) );
  71. int iy0 = static_cast<int> ( floorf(p.getY()) );
  72. int iz0 = static_cast<int> ( floorf(p.getZ()) );
  73. float tx0 = p.getX() - ix0;
  74. float ty0 = p.getY() - iy0;
  75. float tz0 = p.getZ() - iz0;
  76. float tx1 = tx0 - 1.0f;
  77. float ty1 = ty0 - 1.0f;
  78. float tz1 = tz0 - 1.0f;
  79. ix0 &= s_kHashIndexMask;
  80. iy0 &= s_kHashIndexMask;
  81. iz0 &= s_kHashIndexMask;
  82. int ix1 = ix0 + 1;
  83. int iy1 = iy0 + 1;
  84. int iz1 = iz0 + 1;
  85. int h0 = s_Hash[ix0];
  86. int h1 = s_Hash[ix1];
  87. int h00 = s_Hash[h0 + iy0];
  88. int h10 = s_Hash[h1 + iy0];
  89. int h01 = s_Hash[h0 + iy1];
  90. int h11 = s_Hash[h1 + iy1];
  91. // gradients at each of the 8 lattice points
  92. Vector3 g000 = s_Gradients3D[s_Hash[h00 + iz0] & s_kGradientIndexMask];
  93. Vector3 g100 = s_Gradients3D[s_Hash[h10 + iz0] & s_kGradientIndexMask];
  94. Vector3 g010 = s_Gradients3D[s_Hash[h01 + iz0] & s_kGradientIndexMask];
  95. Vector3 g110 = s_Gradients3D[s_Hash[h11 + iz0] & s_kGradientIndexMask];
  96. Vector3 g001 = s_Gradients3D[s_Hash[h00 + iz1] & s_kGradientIndexMask];
  97. Vector3 g101 = s_Gradients3D[s_Hash[h10 + iz1] & s_kGradientIndexMask];
  98. Vector3 g011 = s_Gradients3D[s_Hash[h01 + iz1] & s_kGradientIndexMask];
  99. Vector3 g111 = s_Gradients3D[s_Hash[h11 + iz1] & s_kGradientIndexMask];
  100. float v000 = Dot(g000, tx0, ty0, tz0);
  101. float v100 = Dot(g100, tx1, ty0, tz0);
  102. float v010 = Dot(g010, tx0, ty1, tz0);
  103. float v110 = Dot(g110, tx1, ty1, tz0);
  104. float v001 = Dot(g001, tx0, ty0, tz1);
  105. float v101 = Dot(g101, tx1, ty0, tz1);
  106. float v011 = Dot(g011, tx0, ty1, tz1);
  107. float v111 = Dot(g111, tx1, ty1, tz1);
  108. float dtx = SmoothDerivative(tx0);
  109. float dty = SmoothDerivative(ty0);
  110. float dtz = SmoothDerivative(tz0);
  111. float tx = Smooth(tx0);
  112. float ty = Smooth(ty0);
  113. float tz = Smooth(tz0);
  114. float a = v000;
  115. float b = v100 - v000;
  116. float c = v010 - v000;
  117. float d = v001 - v000;
  118. float e = v110 - v010 - v100 + v000;
  119. float f = v101 - v001 - v100 + v000;
  120. float g = v011 - v001 - v010 + v000;
  121. float h = v111 - v011 - v101 + v001 - v110 + v010 + v100 - v000;
  122. Vector3 da = g000;
  123. Vector3 db = g100 - g000;
  124. Vector3 dc = g010 - g000;
  125. Vector3 dd = g001 - g000;
  126. Vector3 de = g110 - g010 - g100 + g000;
  127. Vector3 df = g101 - g001 - g100 + g000;
  128. Vector3 dg = g011 - g001 - g010 + g000;
  129. Vector3 dh = g111 - g011 - g101 + g001 - g110 + g010 + g100 - g000;
  130. NoiseSample sample;
  131. sample.value = a + b * tx + (c + e * tx) * ty + (d + f * tx + (g + h * tx) * ty) * tz;
  132. // calculate derivative analytically
  133. sample.derivative = da + db * tx + (dc + de * tx) * ty + (dd + df * tx + (dg + dh * tx) * ty) * tz;
  134. Vector3 delta = Vector3((b + e * ty + (f + h * ty) * tz) * dtx,
  135. (c + e * tx + (g + h * tx) * tz) * dty,
  136. (d + f * tx + (g + h * tx) * ty) * dtz);
  137. sample.derivative += delta;
  138. sample.derivative *= frequency;
  139. return sample;
  140. }
  141. //-----------------------------------------------------------------------------------------------
  142. // Wrapper that sums multiple octaves at noise; see decl for defaults
  143. NoiseSample
  144. PerlinNoise3::Noise(Vector3 point, float frequency, int octaves, float lacunarity, float persistence)
  145. {
  146. NoiseSample sum = EvaluateNoise(point, frequency);
  147. float amplitude = 1.0f;
  148. float range = 1.0f;
  149. for (int o = 1; o < octaves; o++) {
  150. frequency *= lacunarity;
  151. amplitude *= persistence;
  152. range += amplitude;
  153. sum += EvaluateNoise(point, frequency) * amplitude;
  154. }
  155. return sum * (1.0f / range);
  156. }