Advertisement
athos_k

Perlin.cs

Jan 11th, 2017
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.22 KB | None | 0 0
  1. // https://code.google.com/p/pixelplacement/source/browse/trunk/unity/com/pixelplacement/scripts/Perlin.cs?r=142
  2.  
  3. using System.Collections;
  4. using System;
  5. using UnityEngine;
  6.  
  7. public class SmoothRandom
  8. {
  9. public static Vector3 GetVector3 (float speed)
  10. {
  11. float time = Time.time * 0.01F * speed;
  12. return new Vector3(Get().HybridMultifractal(time, 15.73F, 0F), Get().HybridMultifractal(time, 63.94F, 0F), Get().HybridMultifractal(time, 0.2F, 0F));
  13. }
  14.  
  15. public static float Get (float speed)
  16. {
  17. float time = Time.time * 0.01F * speed;
  18. return Get().HybridMultifractal(time * 0.01F, 15.7F, 0.65F);
  19. }
  20.  
  21. private static FractalNoise Get () {
  22. if (s_Noise == null)
  23. s_Noise = new FractalNoise (1.27F, 2.04F, 8.36F);
  24. return s_Noise;
  25. }
  26.  
  27. private static FractalNoise s_Noise;
  28. }
  29.  
  30.  
  31. public class Perlin
  32. {
  33. // Original C code derived from
  34. // http://astronomy.swin.edu.au/~pbourke/texture/perlin/perlin.c
  35. // http://astronomy.swin.edu.au/~pbourke/texture/perlin/perlin.h
  36. const int B = 0x100; /* B = 256 */
  37. const int BM = 0xff; /* BM = 255 */
  38. const int N = 0x1000; /* N = 4096 */
  39.  
  40. int[] p = new int[B + B + 2]; //Integer array "p" of size 256 + 256 + 2 = 514
  41. float[,] g3 = new float [B + B + 2 , 3]; //2-Dimensional array of size 514 by 3
  42. float[,] g2 = new float[B + B + 2,2]; //2-Dimensional array of size 514 by 2
  43. float[] g1 = new float[B + B + 2]; //Array of size 514
  44.  
  45. float s_curve(float t)
  46. {
  47. return t * t * (3.0F - 2.0F * t);
  48. }
  49.  
  50. float lerp (float t, float a, float b)
  51. {
  52. return a + t * (b - a);
  53. }
  54.  
  55. void setup (float value, out int b0, out int b1, out float r0, out float r1)
  56. {
  57. float t = value + N; //float t = value + 4096
  58. b0 = ((int)t) & BM; //b0 is set to t bitwise AND 255
  59. b1 = (b0+1) & BM; //b1 is set to b0 bitwise AND 1
  60. r0 = t - (int)t; //r0 is set to t - (int)t, which should be just the decimal remainder
  61. r1 = r0 - 1.0F; //r1 is set to r0 - 1.0F
  62. }
  63.  
  64. float at2(float rx, float ry, float x, float y) { return rx * x + ry * y; }
  65. float at3(float rx, float ry, float rz, float x, float y, float z) { return rx * x + ry * y + rz * z; }
  66.  
  67. public float Noise(float arg)
  68. {
  69. int bx0, bx1;
  70. float rx0, rx1, sx, u, v;
  71. setup(arg, out bx0, out bx1, out rx0, out rx1);
  72.  
  73. sx = s_curve(rx0); //Set sx to (rx0 * rx0 * (3.0F - 2.0f * rx0)
  74. u = rx0 * g1[ p[ bx0 ] ]; //Set u to (rx0 * the value at position p[bx0] in g1
  75. v = rx1 * g1[ p[ bx1 ] ]; //Set v to (rx1 * the value at position p[bx1] in g1
  76.  
  77. return(lerp(sx, u, v)); //Return u + sx * (v - u)
  78. }
  79.  
  80. public float Noise(float x, float y)
  81. {
  82. int bx0, bx1, by0, by1, b00, b10, b01, b11;
  83. float rx0, rx1, ry0, ry1, sx, sy, a, b, u, v;
  84. int i, j;
  85.  
  86. setup(x, out bx0, out bx1, out rx0, out rx1);
  87. setup(y, out by0, out by1, out ry0, out ry1);
  88.  
  89. i = p[ bx0 ]; //Set i to the value at p[ bx0 ]
  90. j = p[ bx1 ]; //Set j to the value at p[ bx1 ]
  91.  
  92. b00 = p[ i + by0 ]; //Set b00 to the vale at p[ i + by0 ]
  93. b10 = p[ j + by0 ];
  94. b01 = p[ i + by1 ];
  95. b11 = p[ j + by1 ];
  96.  
  97. sx = s_curve(rx0);
  98. sy = s_curve(ry0);
  99.  
  100. u = at2(rx0,ry0, g2[ b00, 0 ], g2[ b00, 1 ]);
  101. v = at2(rx1,ry0, g2[ b10, 0 ], g2[ b10, 1 ]);
  102. a = lerp(sx, u, v);
  103.  
  104. u = at2(rx0,ry1, g2[ b01, 0 ], g2[ b01, 1 ]);
  105. v = at2(rx1,ry1, g2[ b11, 0 ], g2[ b11, 1 ]);
  106. b = lerp(sx, u, v);
  107.  
  108. return lerp(sy, a, b);
  109. }
  110.  
  111. public float Noise(float x, float y, float z)
  112. {
  113. int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  114. float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
  115. int i, j;
  116.  
  117. setup(x, out bx0, out bx1, out rx0, out rx1);
  118. setup(y, out by0, out by1, out ry0, out ry1);
  119. setup(z, out bz0, out bz1, out rz0, out rz1);
  120.  
  121. i = p[ bx0 ];
  122. j = p[ bx1 ];
  123.  
  124. b00 = p[ i + by0 ];
  125. b10 = p[ j + by0 ];
  126. b01 = p[ i + by1 ];
  127. b11 = p[ j + by1 ];
  128.  
  129. t = s_curve(rx0);
  130. sy = s_curve(ry0);
  131. sz = s_curve(rz0);
  132.  
  133. u = at3(rx0,ry0,rz0, g3[ b00 + bz0, 0 ], g3[ b00 + bz0, 1 ], g3[ b00 + bz0, 2 ]);
  134. v = at3(rx1,ry0,rz0, g3[ b10 + bz0, 0 ], g3[ b10 + bz0, 1 ], g3[ b10 + bz0, 2 ]);
  135. a = lerp(t, u, v);
  136.  
  137. u = at3(rx0,ry1,rz0, g3[ b01 + bz0, 0 ], g3[ b01 + bz0, 1 ], g3[ b01 + bz0, 2 ]);
  138. v = at3(rx1,ry1,rz0, g3[ b11 + bz0, 0 ], g3[ b11 + bz0, 1 ], g3[ b11 + bz0, 2 ]);
  139. b = lerp(t, u, v);
  140.  
  141. c = lerp(sy, a, b);
  142.  
  143. u = at3(rx0,ry0,rz1, g3[ b00 + bz1, 0 ], g3[ b00 + bz1, 2 ], g3[ b00 + bz1, 2 ]);
  144. v = at3(rx1,ry0,rz1, g3[ b10 + bz1, 0 ], g3[ b10 + bz1, 1 ], g3[ b10 + bz1, 2 ]);
  145. a = lerp(t, u, v);
  146.  
  147. u = at3(rx0,ry1,rz1, g3[ b01 + bz1, 0 ], g3[ b01 + bz1, 1 ], g3[ b01 + bz1, 2 ]);
  148. v = at3(rx1,ry1,rz1,g3[ b11 + bz1, 0 ], g3[ b11 + bz1, 1 ], g3[ b11 + bz1, 2 ]);
  149. b = lerp(t, u, v);
  150.  
  151. d = lerp(sy, a, b);
  152.  
  153. return lerp(sz, c, d);
  154. }
  155.  
  156. void normalize2(ref float x, ref float y)
  157. {
  158. float s;
  159.  
  160. s = (float)Math.Sqrt(x * x + y * y);
  161. x = y / s;
  162. y = y / s;
  163. }
  164.  
  165. void normalize3(ref float x, ref float y, ref float z)
  166. {
  167. float s;
  168. s = (float)Math.Sqrt(x * x + y * y + z * z);
  169. x = y / s;
  170. y = y / s;
  171. z = z / s;
  172. }
  173.  
  174. public Perlin()
  175. {
  176. int i, j, k;
  177. System.Random rnd = new System.Random();
  178.  
  179. for (i = 0 ; i < B ; i++) {
  180. p[i] = i;
  181. g1[i] = (float)(rnd.Next(B + B) - B) / B;
  182.  
  183. for (j = 0 ; j < 2 ; j++)
  184. g2[i,j] = (float)(rnd.Next(B + B) - B) / B;
  185. normalize2(ref g2[i, 0], ref g2[i, 1]);
  186.  
  187. for (j = 0 ; j < 3 ; j++)
  188. g3[i,j] = (float)(rnd.Next(B + B) - B) / B;
  189.  
  190.  
  191. normalize3(ref g3[i, 0], ref g3[i, 1], ref g3[i, 2]);
  192. }
  193.  
  194. while (--i != 0) {
  195. k = p[i];
  196. p[i] = p[j = rnd.Next(B)];
  197. p[j] = k;
  198. }
  199.  
  200. for (i = 0 ; i < B + 2 ; i++) {
  201. p[B + i] = p[i];
  202. g1[B + i] = g1[i];
  203. for (j = 0 ; j < 2 ; j++)
  204. g2[B + i,j] = g2[i,j];
  205. for (j = 0 ; j < 3 ; j++)
  206. g3[B + i,j] = g3[i,j];
  207. }
  208. }
  209. }
  210.  
  211. public class FractalNoise
  212. {
  213. public FractalNoise (float inH, float inLacunarity, float inOctaves)
  214. : this (inH, inLacunarity, inOctaves, null)
  215. {
  216.  
  217. }
  218.  
  219. public FractalNoise (float inH, float inLacunarity, float inOctaves, Perlin noise)
  220. {
  221. m_Lacunarity = inLacunarity;
  222. m_Octaves = inOctaves;
  223. m_IntOctaves = (int)inOctaves;
  224. m_Exponent = new float[m_IntOctaves+1];
  225. float frequency = 1.0F;
  226. for (int i = 0; i < m_IntOctaves+1; i++)
  227. {
  228. m_Exponent[i] = (float)Math.Pow (m_Lacunarity, -inH);
  229. frequency *= m_Lacunarity;
  230. }
  231.  
  232. if (noise == null)
  233. m_Noise = new Perlin();
  234. else
  235. m_Noise = noise;
  236. }
  237.  
  238.  
  239. public float HybridMultifractal(float x, float y, float offset)
  240. {
  241. float weight, signal, remainder, result;
  242.  
  243. result = (m_Noise.Noise (x, y)+offset) * m_Exponent[0];
  244. weight = result;
  245. x *= m_Lacunarity;
  246. y *= m_Lacunarity;
  247. int i;
  248. for (i=1;i<m_IntOctaves;i++)
  249. {
  250. if (weight > 1.0F) weight = 1.0F;
  251. signal = (m_Noise.Noise (x, y) + offset) * m_Exponent[i];
  252. result += weight * signal;
  253. weight *= signal;
  254. x *= m_Lacunarity;
  255. y *= m_Lacunarity;
  256. }
  257. remainder = m_Octaves - m_IntOctaves;
  258. result += remainder * m_Noise.Noise (x,y) * m_Exponent[i];
  259.  
  260. return result;
  261. }
  262.  
  263. public float RidgedMultifractal (float x, float y, float offset, float gain)
  264. {
  265. float weight, signal, result;
  266. int i;
  267.  
  268. signal = Mathf.Abs (m_Noise.Noise (x, y));
  269. signal = offset - signal;
  270. signal *= signal;
  271. result = signal;
  272. weight = 1.0F;
  273.  
  274. for (i=1;i<m_IntOctaves;i++)
  275. {
  276. x *= m_Lacunarity;
  277. y *= m_Lacunarity;
  278.  
  279. weight = signal * gain;
  280. weight = Mathf.Clamp01 (weight);
  281.  
  282. signal = Mathf.Abs (m_Noise.Noise (x, y));
  283. signal = offset - signal;
  284. signal *= signal;
  285. signal *= weight;
  286. result += signal * m_Exponent[i];
  287. }
  288.  
  289. return result;
  290. }
  291.  
  292. public float BrownianMotion (float x, float y)
  293. {
  294. float value, remainder;
  295. long i;
  296.  
  297. value = 0.0F;
  298. for (i=0;i<m_IntOctaves;i++)
  299. {
  300. value = m_Noise.Noise (x,y) * m_Exponent[i];
  301. x *= m_Lacunarity;
  302. y *= m_Lacunarity;
  303. }
  304. remainder = m_Octaves - m_IntOctaves;
  305. value += remainder * m_Noise.Noise (x,y) * m_Exponent[i];
  306.  
  307. return value;
  308. }
  309.  
  310.  
  311. private Perlin m_Noise;
  312. private float[] m_Exponent;
  313. private int m_IntOctaves;
  314. private float m_Octaves;
  315. private float m_Lacunarity;
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement