Perlin Noise

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Usage)
Line 7: Line 7:
 
Add this script anywhere in your project folder.
 
Add this script anywhere in your project folder.
 
Attach the javascript to any transform to make that transform smoothly and randomly move around.
 
Attach the javascript to any transform to make that transform smoothly and randomly move around.
 +
 +
[[Media:Noise_174.unitypackage.zip|Noise_174.unitypackage.zip]]
  
 
<javascript>
 
<javascript>

Revision as of 13:35, 1 August 2006

Description

The following snippet shows how to smoothly randomly move a transform around.

Usage

Add this script anywhere in your project folder. Attach the javascript to any transform to make that transform smoothly and randomly move around.

Noise_174.unitypackage.zip

<javascript> // Moves the object along as far as range units randomly but in a smooth way. // This script requires the Noise.cs script. var speed = 1.0; var range = Vector3 (1.0, 1.0, 1.0);

private var noise = new Noise(); private var position : Vector3;

function Start() { position = transform.position; }

function Update () { transform.position = position + Vector3.Scale(SmoothRandom.GetVector3(speed), range); } </javascript>


Place this script in a folder called Plugins as a sub folder of the Assets folder. This will allow you to access the PerlinNoise class which is written in C# from Javascript.

<csharp> using System.Collections; using System; using UnityEngine;

public class Perlin { 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; }

public float Noise1D(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 Noise2D(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); } /* double noise3(double vec[3]) { int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; int i, j;

if (start) { start = 0; init(); }

setup(0, bx0,bx1, rx0,rx1); setup(1, by0,by1, ry0,ry1); setup(2, bz0,bz1, rz0,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);

q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0); q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0); a = lerp(t, u, v);

q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0); q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0); b = lerp(t, u, v);

c = lerp(sy, a, b);

q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1); q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1); a = lerp(t, u, v);

q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1); q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1); 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 SmoothRandom { public static Vector3 GetVector3 (float speed) { float time = Time.time * 0.01F * speed; return new Vector3(Get().HybridMultifractal(time, 15.73F, 0.65F), Get().HybridMultifractal(time, 63.94F, 0.65F), Get().HybridMultifractal(time, 0.2F, 0.65F)); }

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.06F, 8.36F); return s_Noise; }

private static FractalNoise s_Noise; }


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.Noise2D (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.Noise2D (x, y) + offset) * m_Exponent[i]; result += weight * signal; weight *= signal; x *= m_Lacunarity; y *= m_Lacunarity; } remainder = m_Octaves - m_IntOctaves; if (remainder != 0.0F) result += remainder * m_Noise.Noise2D (x,y) * m_Exponent[i];

return result; }

Perlin m_Noise; float[] m_Exponent; int m_IntOctaves; float m_Octaves; float m_Lacunarity; }


public class Noise { public float Noise1D(float x) { return Noise2D(x, 0.5F); }

public float Noise2D(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 }

protected 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; }

public 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<m_nNoiseWidth; x++) { for (int y = 0; y<m_nNoiseHeight; y++) { m_aNoise[x,y] = rnd.Next(255); } } }

private int[,] m_aNoise; protected int m_nNoiseWidth, m_nNoiseHeight; private float m_fScaleX, m_fScaleY; }


/* float noise1[]; float noise2[]; float noise3[]; int indices[];

float PerlinSmoothStep (float t) { return t * t * (3.0f - 2.0f * t); }

float PerlinLerp(float t, float a, float b) { return a + t * (b - a); }

float PerlinRand() { return Random.rand () / float(RAND_MAX) * 2.0f - 1.0f; }


PerlinNoise::PerlinNoise () { long i, j, k; float x, y, z, denom;

Random rnd = new Random();


noise1 = new float[1 * (PERLIN_B + PERLIN_B + 2)]; noise2 = new float[2 * (PERLIN_B + PERLIN_B + 2)]; noise3 = new float[3 * (PERLIN_B + PERLIN_B + 2)]; indices = new long[PERLIN_B + PERLIN_B + 2];

for (i = 0; i < PERLIN_B; i++) { indices[i] = i;

x = PerlinRand(); y = PerlinRand(); z = PerlinRand();

noise1[i] = x;

denom = sqrt(x * x + y * y); if (denom > 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); }

  • /

</csharp>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox