Perlin.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. using System;
  2. namespace Xft
  3. {
  4. public class Perlin
  5. {
  6. public Perlin()
  7. {
  8. Random random = new Random();
  9. int i;
  10. for (i = 0; i < 256; i++)
  11. {
  12. this.p[i] = i;
  13. this.g1[i] = (float)(random.Next(512) - 256) / 256f;
  14. for (int j = 0; j < 2; j++)
  15. {
  16. this.g2[i, j] = (float)(random.Next(512) - 256) / 256f;
  17. }
  18. this.normalize2(ref this.g2[i, 0], ref this.g2[i, 1]);
  19. for (int j = 0; j < 3; j++)
  20. {
  21. this.g3[i, j] = (float)(random.Next(512) - 256) / 256f;
  22. }
  23. this.normalize3(ref this.g3[i, 0], ref this.g3[i, 1], ref this.g3[i, 2]);
  24. }
  25. while (--i != 0)
  26. {
  27. int num = this.p[i];
  28. int j;
  29. this.p[i] = this.p[j = random.Next(256)];
  30. this.p[j] = num;
  31. }
  32. for (i = 0; i < 258; i++)
  33. {
  34. this.p[256 + i] = this.p[i];
  35. this.g1[256 + i] = this.g1[i];
  36. for (int j = 0; j < 2; j++)
  37. {
  38. this.g2[256 + i, j] = this.g2[i, j];
  39. }
  40. for (int j = 0; j < 3; j++)
  41. {
  42. this.g3[256 + i, j] = this.g3[i, j];
  43. }
  44. }
  45. }
  46. private float s_curve(float t)
  47. {
  48. return t * t * (3f - 2f * t);
  49. }
  50. private float lerp(float t, float a, float b)
  51. {
  52. return a + t * (b - a);
  53. }
  54. private void setup(float value, out int b0, out int b1, out float r0, out float r1)
  55. {
  56. float num = value + 4096f;
  57. b0 = ((int)num & 255);
  58. b1 = (b0 + 1 & 255);
  59. r0 = num - (float)((int)num);
  60. r1 = r0 - 1f;
  61. }
  62. private float at2(float rx, float ry, float x, float y)
  63. {
  64. return rx * x + ry * y;
  65. }
  66. private float at3(float rx, float ry, float rz, float x, float y, float z)
  67. {
  68. return rx * x + ry * y + rz * z;
  69. }
  70. public float Noise(float arg)
  71. {
  72. int num;
  73. int num2;
  74. float num3;
  75. float num4;
  76. this.setup(arg, out num, out num2, out num3, out num4);
  77. float t = this.s_curve(num3);
  78. float a = num3 * this.g1[this.p[num]];
  79. float b = num4 * this.g1[this.p[num2]];
  80. return this.lerp(t, a, b);
  81. }
  82. public float Noise(float x, float y)
  83. {
  84. int num;
  85. int num2;
  86. float num3;
  87. float rx;
  88. this.setup(x, out num, out num2, out num3, out rx);
  89. int num4;
  90. int num5;
  91. float num6;
  92. float ry;
  93. this.setup(y, out num4, out num5, out num6, out ry);
  94. int num7 = this.p[num];
  95. int num8 = this.p[num2];
  96. int num9 = this.p[num7 + num4];
  97. int num10 = this.p[num8 + num4];
  98. int num11 = this.p[num7 + num5];
  99. int num12 = this.p[num8 + num5];
  100. float t = this.s_curve(num3);
  101. float t2 = this.s_curve(num6);
  102. float a = this.at2(num3, num6, this.g2[num9, 0], this.g2[num9, 1]);
  103. float b = this.at2(rx, num6, this.g2[num10, 0], this.g2[num10, 1]);
  104. float a2 = this.lerp(t, a, b);
  105. a = this.at2(num3, ry, this.g2[num11, 0], this.g2[num11, 1]);
  106. b = this.at2(rx, ry, this.g2[num12, 0], this.g2[num12, 1]);
  107. float b2 = this.lerp(t, a, b);
  108. return this.lerp(t2, a2, b2);
  109. }
  110. public float Noise(float x, float y, float z)
  111. {
  112. int num;
  113. int num2;
  114. float num3;
  115. float rx;
  116. this.setup(x, out num, out num2, out num3, out rx);
  117. int num4;
  118. int num5;
  119. float num6;
  120. float ry;
  121. this.setup(y, out num4, out num5, out num6, out ry);
  122. int num7;
  123. int num8;
  124. float num9;
  125. float rz;
  126. this.setup(z, out num7, out num8, out num9, out rz);
  127. int num10 = this.p[num];
  128. int num11 = this.p[num2];
  129. int num12 = this.p[num10 + num4];
  130. int num13 = this.p[num11 + num4];
  131. int num14 = this.p[num10 + num5];
  132. int num15 = this.p[num11 + num5];
  133. float t = this.s_curve(num3);
  134. float t2 = this.s_curve(num6);
  135. float t3 = this.s_curve(num9);
  136. float a = this.at3(num3, num6, num9, this.g3[num12 + num7, 0], this.g3[num12 + num7, 1], this.g3[num12 + num7, 2]);
  137. float b = this.at3(rx, num6, num9, this.g3[num13 + num7, 0], this.g3[num13 + num7, 1], this.g3[num13 + num7, 2]);
  138. float a2 = this.lerp(t, a, b);
  139. a = this.at3(num3, ry, num9, this.g3[num14 + num7, 0], this.g3[num14 + num7, 1], this.g3[num14 + num7, 2]);
  140. b = this.at3(rx, ry, num9, this.g3[num15 + num7, 0], this.g3[num15 + num7, 1], this.g3[num15 + num7, 2]);
  141. float b2 = this.lerp(t, a, b);
  142. float a3 = this.lerp(t2, a2, b2);
  143. a = this.at3(num3, num6, rz, this.g3[num12 + num8, 0], this.g3[num12 + num8, 2], this.g3[num12 + num8, 2]);
  144. b = this.at3(rx, num6, rz, this.g3[num13 + num8, 0], this.g3[num13 + num8, 1], this.g3[num13 + num8, 2]);
  145. a2 = this.lerp(t, a, b);
  146. a = this.at3(num3, ry, rz, this.g3[num14 + num8, 0], this.g3[num14 + num8, 1], this.g3[num14 + num8, 2]);
  147. b = this.at3(rx, ry, rz, this.g3[num15 + num8, 0], this.g3[num15 + num8, 1], this.g3[num15 + num8, 2]);
  148. b2 = this.lerp(t, a, b);
  149. float b3 = this.lerp(t2, a2, b2);
  150. return this.lerp(t3, a3, b3);
  151. }
  152. private void normalize2(ref float x, ref float y)
  153. {
  154. float num = (float)Math.Sqrt((double)(x * x + y * y));
  155. x = y / num;
  156. y /= num;
  157. }
  158. private void normalize3(ref float x, ref float y, ref float z)
  159. {
  160. float num = (float)Math.Sqrt((double)(x * x + y * y + z * z));
  161. x = y / num;
  162. y /= num;
  163. z /= num;
  164. }
  165. private const int B = 256;
  166. private const int BM = 255;
  167. private const int N = 4096;
  168. private int[] p = new int[514];
  169. private float[,] g3 = new float[514, 3];
  170. private float[,] g2 = new float[514, 2];
  171. private float[] g1 = new float[514];
  172. }
  173. }