PerlinNoise3D.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace KairoEngine.NoiseUtilities
  5. {
  6. public class PerlinNoise3D
  7. {
  8. private static int[] permutation = {
  9. 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
  10. 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
  11. 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
  12. 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
  13. 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
  14. 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
  15. 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
  16. 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
  17. 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
  18. 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
  19. 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
  20. 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
  21. 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
  22. 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
  23. 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
  24. 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180,
  25. 151,160,137, 91, 90, 15,131, 13,201, 95, 96, 53,194,233, 7,225,
  26. 140, 36,103, 30, 69,142, 8, 99, 37,240, 21, 10, 23,190, 6,148,
  27. 247,120,234, 75, 0, 26,197, 62, 94,252,219,203,117, 35, 11, 32,
  28. 57,177, 33, 88,237,149, 56, 87,174, 20,125,136,171,168, 68,175,
  29. 74,165, 71,134,139, 48, 27,166, 77,146,158,231, 83,111,229,122,
  30. 60,211,133,230,220,105, 92, 41, 55, 46,245, 40,244,102,143, 54,
  31. 65, 25, 63,161, 1,216, 80, 73,209, 76,132,187,208, 89, 18,169,
  32. 200,196,135,130,116,188,159, 86,164,100,109,198,173,186, 3, 64,
  33. 52,217,226,250,124,123, 5,202, 38,147,118,126,255, 82, 85,212,
  34. 207,206, 59,227, 47, 16, 58, 17,182,189, 28, 42,223,183,170,213,
  35. 119,248,152, 2, 44,154,163, 70,221,153,101,155,167, 43,172, 9,
  36. 129, 22, 39,253, 19, 98,108,110, 79,113,224,232,178,185,112,104,
  37. 218,246, 97,228,251, 34,242,193,238,210,144, 12,191,179,162,241,
  38. 81, 51,145,235,249, 14,239,107, 49,192,214, 31,181,199,106,157,
  39. 184, 84,204,176,115,121, 50, 45,127, 4,150,254,138,236,205, 93,
  40. 222,114, 67, 29, 24, 72,243,141,128,195, 78, 66,215, 61,156,180
  41. };
  42. const int permutationCount = 255;
  43. private static Vector3[] directions = {
  44. new Vector3( 1f, 1f, 0f),
  45. new Vector3(-1f, 1f, 0f),
  46. new Vector3( 1f,-1f, 0f),
  47. new Vector3(-1f,-1f, 0f),
  48. new Vector3( 1f, 0f, 1f),
  49. new Vector3(-1f, 0f, 1f),
  50. new Vector3( 1f, 0f,-1f),
  51. new Vector3(-1f, 0f,-1f),
  52. new Vector3( 0f, 1f, 1f),
  53. new Vector3( 0f,-1f, 1f),
  54. new Vector3( 0f, 1f,-1f),
  55. new Vector3( 0f,-1f,-1f),
  56. new Vector3( 1f, 1f, 0f),
  57. new Vector3(-1f, 1f, 0f),
  58. new Vector3( 0f,-1f, 1f),
  59. new Vector3( 0f,-1f,-1f)
  60. };
  61. private const int directionCount = 15;
  62. private static float scalar(Vector3 a, Vector3 b)
  63. {
  64. return a.x * b.x + a.y * b.y + a.z * b.z;
  65. }
  66. private static float smoothDistance(float d)
  67. {
  68. return d * d * d * (d * (d * 6f - 15f) + 10f);
  69. }
  70. public static float get3DPerlinNoise(Vector3 point, float frequency)
  71. {
  72. point *= frequency;
  73. int flooredPointX0 = Mathf.FloorToInt(point.x);
  74. int flooredPointY0 = Mathf.FloorToInt(point.y);
  75. int flooredPointZ0 = Mathf.FloorToInt(point.z);
  76. float distanceX0 = point.x - flooredPointX0;
  77. float distanceY0 = point.y - flooredPointY0;
  78. float distanceZ0 = point.z - flooredPointZ0;
  79. float distanceX1 = distanceX0 - 1f;
  80. float distanceY1 = distanceY0 - 1f;
  81. float distanceZ1 = distanceZ0 - 1f;
  82. flooredPointX0 &= permutationCount;
  83. flooredPointY0 &= permutationCount;
  84. flooredPointZ0 &= permutationCount;
  85. int flooredPointX1 = flooredPointX0 + 1;
  86. int flooredPointY1 = flooredPointY0 + 1;
  87. int flooredPointZ1 = flooredPointZ0 + 1;
  88. int permutationX0 = permutation[flooredPointX0];
  89. int permutationX1 = permutation[flooredPointX1];
  90. int permutationY00 = permutation[permutationX0 + flooredPointY0];
  91. int permutationY10 = permutation[permutationX1 + flooredPointY0];
  92. int permutationY01 = permutation[permutationX0 + flooredPointY1];
  93. int permutationY11 = permutation[permutationX1 + flooredPointY1];
  94. /*
  95. int permutationZ000 = permutation[permutationY00 + flooredPointZ0];
  96. int permutationZ100 = permutation[permutationY10 + flooredPointZ0];
  97. int permutationZ010 = permutation[permutationY01 + flooredPointZ0];
  98. int permutationZ110 = permutation[permutationY11 + flooredPointZ0];
  99. int permutationZ001 = permutation[permutationY00 + flooredPointZ1];
  100. int permutationZ101 = permutation[permutationY01 + flooredPointZ1];
  101. int permutationZ011 = permutation[permutationY10 + flooredPointZ1];
  102. int permutationZ111 = permutation[permutationY11 + flooredPointZ1];
  103. */
  104. Vector3 direction000 = directions[permutation[permutationY00 + flooredPointZ0] & directionCount];
  105. Vector3 direction100 = directions[permutation[permutationY10 + flooredPointZ0] & directionCount];
  106. Vector3 direction010 = directions[permutation[permutationY01 + flooredPointZ0] & directionCount];
  107. Vector3 direction110 = directions[permutation[permutationY11 + flooredPointZ0] & directionCount];
  108. Vector3 direction001 = directions[permutation[permutationY00 + flooredPointZ1] & directionCount];
  109. Vector3 direction101 = directions[permutation[permutationY10 + flooredPointZ1] & directionCount];
  110. Vector3 direction011 = directions[permutation[permutationY01 + flooredPointZ1] & directionCount];
  111. Vector3 direction111 = directions[permutation[permutationY11 + flooredPointZ1] & directionCount];
  112. /*
  113. Vector3 direction000 = directions[permutationZ000 & directionCount];
  114. Vector3 direction100 = directions[permutationZ100 & directionCount];
  115. Vector3 direction010 = directions[permutationZ010 & directionCount];
  116. Vector3 direction110 = directions[permutationZ110 & directionCount];
  117. Vector3 direction001 = directions[permutationZ001 & directionCount];
  118. Vector3 direction101 = directions[permutationZ101 & directionCount];
  119. Vector3 direction011 = directions[permutationZ011 & directionCount];
  120. Vector3 direction111 = directions[permutationZ111 & directionCount];
  121. */
  122. float value000 = scalar(direction000, new Vector3(distanceX0, distanceY0, distanceZ0));
  123. float value100 = scalar(direction100, new Vector3(distanceX1, distanceY0, distanceZ0));
  124. float value010 = scalar(direction010, new Vector3(distanceX0, distanceY1, distanceZ0));
  125. float value110 = scalar(direction110, new Vector3(distanceX1, distanceY1, distanceZ0));
  126. float value001 = scalar(direction001, new Vector3(distanceX0, distanceY0, distanceZ1));
  127. float value101 = scalar(direction101, new Vector3(distanceX1, distanceY0, distanceZ1));
  128. float value011 = scalar(direction011, new Vector3(distanceX0, distanceY1, distanceZ1));
  129. float value111 = scalar(direction111, new Vector3(distanceX1, distanceY1, distanceZ1));
  130. float smoothDistanceX = smoothDistance(distanceX0);
  131. float smoothDistanceY = smoothDistance(distanceY0);
  132. float smoothDistanceZ = smoothDistance(distanceZ0);
  133. return Mathf.Lerp(
  134. Mathf.Lerp(Mathf.Lerp(value000, value100, smoothDistanceX), Mathf.Lerp(value010, value110, smoothDistanceX), smoothDistanceY),
  135. Mathf.Lerp(Mathf.Lerp(value001, value101, smoothDistanceX), Mathf.Lerp(value011, value111, smoothDistanceX), smoothDistanceY),
  136. smoothDistanceZ);
  137. }
  138. }
  139. }