using System.Collections; using System; using UnityEngine; // ReSharper disable All /* Perlin noise use example: Perlin perlin = new Perlin(); var value : float = perlin.Noise(2); var value : float = perlin.Noise(2, 3, ); var value : float = perlin.Noise(2, 3, 4); SmoothRandom use example: var p = SmoothRandom.GetVector3(3); */ namespace BeautifulTransitions.Scripts.Helper { public class SmoothRandom { public static Vector3 GetVector3(float speed) { float time = Time.time*0.01F*speed; return new Vector3(Get().HybridMultifractal(time, 15.73F, 0.58F), Get().HybridMultifractal(time, 63.94F, 0.58F), Get().HybridMultifractal(time, 0.2F, 0.58F)); } public static Vector2 GetVector2(float speed) { float time = Time.time * 0.01F * speed; return new Vector2(Get().HybridMultifractal(time, 15.73F, 0.58F), Get().HybridMultifractal(time, 63.94F, 0.58F)); } public static float Get(float speed) { float time = Time.time*0.01F*speed; return Get().HybridMultifractal(time*0.01F, 15.7F, 0.65F); } private static FractalNoise Get() { if (s_Noise == null) s_Noise = new FractalNoise(1.27F, 2.04F, 8.36F); return s_Noise; } private static FractalNoise s_Noise; } public class Perlin { // Original C code derived from // http://astronomy.swin.edu.au/~pbourke/texture/perlin/perlin.c // http://astronomy.swin.edu.au/~pbourke/texture/perlin/perlin.h const int B = 0x100; const int BM = 0xff; const int N = 0x1000; int[] p = new int[B + B + 2]; float[,] g3 = new float[B + B + 2, 3]; float[,] g2 = new float[B + B + 2, 2]; float[] g1 = new float[B + B + 2]; float s_curve(float t) { return t*t*(3.0F - 2.0F*t); } float lerp(float t, float a, float b) { return a + t*(b - a); } void setup(float value, out int b0, out int b1, out float r0, out float r1) { float t = value + N; b0 = ((int) t) & BM; b1 = (b0 + 1) & BM; r0 = t - (int) t; r1 = r0 - 1.0F; } float at2(float rx, float ry, float x, float y) { return rx*x + ry*y; } float at3(float rx, float ry, float rz, float x, float y, float z) { return rx*x + ry*y + rz*z; } public float Noise(float arg) { int bx0, bx1; float rx0, rx1, sx, u, v; setup(arg, out bx0, out bx1, out rx0, out rx1); sx = s_curve(rx0); u = rx0*g1[p[bx0]]; v = rx1*g1[p[bx1]]; return (lerp(sx, u, v)); } public float Noise(float x, float y) { int bx0, bx1, by0, by1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, sx, sy, a, b, u, v; int i, j; setup(x, out bx0, out bx1, out rx0, out rx1); setup(y, out by0, out by1, out ry0, out ry1); i = p[bx0]; j = p[bx1]; b00 = p[i + by0]; b10 = p[j + by0]; b01 = p[i + by1]; b11 = p[j + by1]; sx = s_curve(rx0); sy = s_curve(ry0); u = at2(rx0, ry0, g2[b00, 0], g2[b00, 1]); v = at2(rx1, ry0, g2[b10, 0], g2[b10, 1]); a = lerp(sx, u, v); u = at2(rx0, ry1, g2[b01, 0], g2[b01, 1]); v = at2(rx1, ry1, g2[b11, 0], g2[b11, 1]); b = lerp(sx, u, v); return lerp(sy, a, b); } public float Noise(float x, float y, float z) { int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v; int i, j; setup(x, out bx0, out bx1, out rx0, out rx1); setup(y, out by0, out by1, out ry0, out ry1); setup(z, out bz0, out bz1, out rz0, out rz1); i = p[bx0]; j = p[bx1]; b00 = p[i + by0]; b10 = p[j + by0]; b01 = p[i + by1]; b11 = p[j + by1]; t = s_curve(rx0); sy = s_curve(ry0); sz = s_curve(rz0); u = at3(rx0, ry0, rz0, g3[b00 + bz0, 0], g3[b00 + bz0, 1], g3[b00 + bz0, 2]); v = at3(rx1, ry0, rz0, g3[b10 + bz0, 0], g3[b10 + bz0, 1], g3[b10 + bz0, 2]); a = lerp(t, u, v); u = at3(rx0, ry1, rz0, g3[b01 + bz0, 0], g3[b01 + bz0, 1], g3[b01 + bz0, 2]); v = at3(rx1, ry1, rz0, g3[b11 + bz0, 0], g3[b11 + bz0, 1], g3[b11 + bz0, 2]); b = lerp(t, u, v); c = lerp(sy, a, b); u = at3(rx0, ry0, rz1, g3[b00 + bz1, 0], g3[b00 + bz1, 2], g3[b00 + bz1, 2]); v = at3(rx1, ry0, rz1, g3[b10 + bz1, 0], g3[b10 + bz1, 1], g3[b10 + bz1, 2]); a = lerp(t, u, v); u = at3(rx0, ry1, rz1, g3[b01 + bz1, 0], g3[b01 + bz1, 1], g3[b01 + bz1, 2]); v = at3(rx1, ry1, rz1, g3[b11 + bz1, 0], g3[b11 + bz1, 1], g3[b11 + bz1, 2]); b = lerp(t, u, v); d = lerp(sy, a, b); return lerp(sz, c, d); } void normalize2(ref float x, ref float y) { float s; s = (float) Math.Sqrt(x*x + y*y); x = y/s; y = y/s; } void normalize3(ref float x, ref float y, ref float z) { float s; s = (float) Math.Sqrt(x*x + y*y + z*z); x = y/s; y = y/s; z = z/s; } public Perlin() { int i, j, k; System.Random rnd = new System.Random(); for (i = 0; i < B; i++) { p[i] = i; g1[i] = (float) (rnd.Next(B + B) - B)/B; for (j = 0; j < 2; j++) g2[i, j] = (float) (rnd.Next(B + B) - B)/B; normalize2(ref g2[i, 0], ref g2[i, 1]); for (j = 0; j < 3; j++) g3[i, j] = (float) (rnd.Next(B + B) - B)/B; normalize3(ref g3[i, 0], ref g3[i, 1], ref g3[i, 2]); } while (--i != 0) { k = p[i]; p[i] = p[j = rnd.Next(B)]; p[j] = k; } for (i = 0; i < B + 2; i++) { p[B + i] = p[i]; g1[B + i] = g1[i]; for (j = 0; j < 2; j++) g2[B + i, j] = g2[i, j]; for (j = 0; j < 3; j++) g3[B + i, j] = g3[i, j]; } } } public class FractalNoise { public FractalNoise(float inH, float inLacunarity, float inOctaves) : this(inH, inLacunarity, inOctaves, null) { } public FractalNoise(float inH, float inLacunarity, float inOctaves, Perlin noise) { m_Lacunarity = inLacunarity; m_Octaves = inOctaves; m_IntOctaves = (int) inOctaves; m_Exponent = new float[m_IntOctaves + 1]; float frequency = 1.0F; for (int i = 0; i < m_IntOctaves + 1; i++) { m_Exponent[i] = (float) Math.Pow(m_Lacunarity, -inH); frequency *= m_Lacunarity; } if (noise == null) m_Noise = new Perlin(); else m_Noise = noise; } public float HybridMultifractal(float x, float y, float offset) { float weight, signal, remainder, result; result = (m_Noise.Noise(x, y) + offset)*m_Exponent[0]; weight = result; x *= m_Lacunarity; y *= m_Lacunarity; int i; for (i = 1; i < m_IntOctaves; i++) { if (weight > 1.0F) weight = 1.0F; signal = (m_Noise.Noise(x, y) + offset)*m_Exponent[i]; result += weight*signal; weight *= signal; x *= m_Lacunarity; y *= m_Lacunarity; } remainder = m_Octaves - m_IntOctaves; result += remainder*m_Noise.Noise(x, y)*m_Exponent[i]; return result; } public float RidgedMultifractal(float x, float y, float offset, float gain) { float weight, signal, result; int i; signal = Mathf.Abs(m_Noise.Noise(x, y)); signal = offset - signal; signal *= signal; result = signal; weight = 1.0F; for (i = 1; i < m_IntOctaves; i++) { x *= m_Lacunarity; y *= m_Lacunarity; weight = signal*gain; weight = Mathf.Clamp01(weight); signal = Mathf.Abs(m_Noise.Noise(x, y)); signal = offset - signal; signal *= signal; signal *= weight; result += signal*m_Exponent[i]; } return result; } public float BrownianMotion(float x, float y) { float value, remainder; long i; value = 0.0F; for (i = 0; i < m_IntOctaves; i++) { value = m_Noise.Noise(x, y)*m_Exponent[i]; x *= m_Lacunarity; y *= m_Lacunarity; } remainder = m_Octaves - m_IntOctaves; value += remainder*m_Noise.Noise(x, y)*m_Exponent[i]; return value; } private Perlin m_Noise; private float[] m_Exponent; private int m_IntOctaves; private float m_Octaves; private float m_Lacunarity; } /* /// This is an alternative implementation of perlin noise public class Noise { public float Noise(float x) { return Noise(x, 0.5F); } public float Noise(float x, float y) { int Xint = (int)x; int Yint = (int)y; float Xfrac = x - Xint; float Yfrac = y - Yint; float x0y0 = Smooth_Noise(Xint, Yint); //find the noise values of the four corners float x1y0 = Smooth_Noise(Xint+1, Yint); float x0y1 = Smooth_Noise(Xint, Yint+1); float x1y1 = Smooth_Noise(Xint+1, Yint+1); //interpolate between those values according to the x and y fractions float v1 = Interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y) float v2 = Interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1) float fin = Interpolate(v1, v2, Yfrac); //interpolate in y direction return fin; } private float Interpolate(float x, float y, float a) { float b = 1-a; float fac1 = (float)(3*b*b - 2*b*b*b); float fac2 = (float)(3*a*a - 2*a*a*a); return x*fac1 + y*fac2; //add the weighted factors } private float GetRandomValue(int x, int y) { x = (x+m_nNoiseWidth) % m_nNoiseWidth; y = (y+m_nNoiseHeight) % m_nNoiseHeight; float fVal = (float)m_aNoise[(int)(m_fScaleX*x), (int)(m_fScaleY*y)]; return fVal/255*2-1f; } private float Smooth_Noise(int x, int y) { float corners = ( Noise2d(x-1, y-1) + Noise2d(x+1, y-1) + Noise2d(x-1, y+1) + Noise2d(x+1, y+1) ) / 16.0f; float sides = ( Noise2d(x-1, y) +Noise2d(x+1, y) + Noise2d(x, y-1) + Noise2d(x, y+1) ) / 8.0f; float center = Noise2d(x, y) / 4.0f; return corners + sides + center; } private float Noise2d(int x, int y) { x = (x+m_nNoiseWidth) % m_nNoiseWidth; y = (y+m_nNoiseHeight) % m_nNoiseHeight; float fVal = (float)m_aNoise[(int)(m_fScaleX*x), (int)(m_fScaleY*y)]; return fVal/255*2-1f; } public Noise() { m_nNoiseWidth = 100; m_nNoiseHeight = 100; m_fScaleX = 1.0F; m_fScaleY = 1.0F; System.Random rnd = new System.Random(); m_aNoise = new int[m_nNoiseWidth,m_nNoiseHeight]; for (int x = 0; x 0.0001f) denom = 1.0f / denom; j = i << 1; noise2[j + 0] = x * denom; noise2[j + 1] = y * denom; denom = sqrt(x * x + y * y + z * z); if (denom > 0.0001f) denom = 1.0f / denom; j += i; noise3[j + 0] = x * denom; noise3[j + 1] = y * denom; noise3[j + 2] = z * denom; } while (--i != 0) { j = rand() & PERLIN_BITMASK; std::swap (indices[i], indices[j]); } for (i = 0; i < PERLIN_B + 2; i++) { j = i + PERLIN_B; indices[j] = indices[i]; noise1[j] = noise1[i]; j = j << 1; k = i << 1; noise2[j + 0] = noise2[k + 0]; noise2[j + 1] = noise2[k + 1]; j += i + PERLIN_B; k += i + PERLIN_B; noise3[j + 0] = noise3[k + 0]; noise3[j + 1] = noise3[k + 1]; noise3[j + 2] = noise3[k + 2]; } } PerlinNoise::~PerlinNoise () { delete []noise1; delete []noise2; delete []noise3; delete []indices; } void PerlinSetup (float v, long& b0, long& b1, float& r0, float& r1); void PerlinSetup( float v, long& b0, long& b1, float& r0, float& r1) { v += PERLIN_N; long vInt = (long)v; b0 = vInt & PERLIN_BITMASK; b1 = (b0 + 1) & PERLIN_BITMASK; r0 = v - (float)vInt; r1 = r0 - 1.0f; } float PerlinNoise::Noise1 (float x) { long bx0, bx1; float rx0, rx1, sx, u, v; PerlinSetup(x, bx0, bx1, rx0, rx1); sx = PerlinSmoothStep(rx0); u = rx0 * noise1[indices[bx0]]; v = rx1 * noise1[indices[bx1]]; return PerlinLerp (sx, u, v); } float PerlinNoise::Noise2(float x, float y) { long bx0, bx1, by0, by1, b00, b01, b10, b11; float rx0, rx1, ry0, ry1, sx, sy, u, v, a, b; PerlinSetup (x, bx0, bx1, rx0, rx1); PerlinSetup (y, by0, by1, ry0, ry1); sx = PerlinSmoothStep (rx0); sy = PerlinSmoothStep (ry0); b00 = indices[indices[bx0] + by0] << 1; b10 = indices[indices[bx1] + by0] << 1; b01 = indices[indices[bx0] + by1] << 1; b11 = indices[indices[bx1] + by1] << 1; u = rx0 * noise2[b00 + 0] + ry0 * noise2[b00 + 1]; v = rx1 * noise2[b10 + 0] + ry0 * noise2[b10 + 1]; a = PerlinLerp (sx, u, v); u = rx0 * noise2[b01 + 0] + ry1 * noise2[b01 + 1]; v = rx1 * noise2[b11 + 0] + ry1 * noise2[b11 + 1]; b = PerlinLerp (sx, u, v); u = PerlinLerp (sy, a, b); return u; } float PerlinNoise::Noise3(float x, float y, float z) { long bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; PerlinSetup (x, bx0, bx1, rx0, rx1); PerlinSetup (y, by0, by1, ry0, ry1); PerlinSetup (z, bz0, bz1, rz0, rz1); b00 = indices[indices[bx0] + by0] << 1; b10 = indices[indices[bx1] + by0] << 1; b01 = indices[indices[bx0] + by1] << 1; b11 = indices[indices[bx1] + by1] << 1; t = PerlinSmoothStep (rx0); sy = PerlinSmoothStep (ry0); sz = PerlinSmoothStep (rz0); #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) q = &noise3[b00 + bz0]; u = at3(rx0,ry0,rz0); q = &noise3[b10 + bz0]; v = at3(rx1,ry0,rz0); a = PerlinLerp(t, u, v); q = &noise3[b01 + bz0]; u = at3(rx0,ry1,rz0); q = &noise3[b11 + bz0]; v = at3(rx1,ry1,rz0); b = PerlinLerp(t, u, v); c = PerlinLerp(sy, a, b); q = &noise3[b00 + bz1]; u = at3(rx0,ry0,rz1); q = &noise3[b10 + bz1]; v = at3(rx1,ry0,rz1); a = PerlinLerp(t, u, v); q = &noise3[b01 + bz1]; u = at3(rx0,ry1,rz1); q = &noise3[b11 + bz1]; v = at3(rx1,ry1,rz1); b = PerlinLerp(t, u, v); d = PerlinLerp(sy, a, b); return PerlinLerp (sz, c, d); } */ }