Perlin Noise

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Another function)
 
(11 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
== Description ==
 
== Description ==
  
The following snippet shows how to smoothly randomly move a transform around.
+
The following snippet shows how to use noise for smoothly randomly moving objects, rotating them or animated light intensity.
  
 
== Usage ==
 
== Usage ==
 +
Download the package. Open Unity with your own project folder. Double click on the unityPackage in the finder.
 +
[[http://unity3d.com/support/resources/example-projects/procedural-examples PerlinNoise]]
  
Add this script anywhere in your project folder.
+
This installs the perlin noise class and 3 scripts implementing:
Attach the javascript to any transform to make that transform smoothly and randomly move around.
+
# Animated light intensity noise
 +
# Animated noise position
 +
# Animated noise rotation
  
<javascript>
+
To use one of the scripts, just drag them on a game object, to make them move, rotate, animate light based on noise.
// 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();
+
== Another function ==
private var position : Vector3;
+
previous information above is out of date links
 +
here are 4 new functions including voronoi on a pretty free license
 +
[http://forum.unity3d.com/threads/68764-LibNoise-Ported-to-Unity?p=439185#post439185 UnityScript noises on forum]
  
function Start()
+
Also here is a nearly complete implementation of Perlin noise in UnityScript,although I didn't finish completing it because I didn't understand JavaScript this.noise function.
{
+
I am sure I will finish it or else you can help if you want the original is here-
position = transform.position;
+
[http://asserttrue.blogspot.co.uk/2011/12/perlin-noise-in-javascript_31.html JavaScript Perlin noise implementation]
}
+
  
function Update () {
+
<syntaxhighlight lang="javascript">
transform.position = position + Vector3.Scale(SmoothRandom.GetVector3(speed), range);
+
#pragma strict
}
+
</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.
+
// This is a port of Ken Perlin's Java code. The
 +
// original Java code is at http://cs.nyu.edu/%7Eperlin/noise/.
 +
// Note that in this version, a number from 0 to 1 is returned.
 +
function PerlinNoise() {
 +
var x :int;
 +
var y :int;
 +
var z :int;
 +
var t :int;
 +
var a :int;
 +
var b :int;
 +
var n :int;
 +
var hash :int;
 +
thisnoise (x, y, z);
 +
fade(t);
 +
lerp( t, a, b);
 +
grad(hash, x, y, z);
 +
    scale(n);}
  
<csharp>
+
function thisnoise (x:int, y:int, z:int) {
using System.Collections;
+
using System;
+
using UnityEngine;
+
  
public class Perlin
+
  var p : int[]; //array
{
+
  p = new int[512];
const int B = 0x100;
+
  var permutation : int[] = [ 151,160,137,91,90,15,
const int BM = 0xff;
+
  131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
const int N = 0x1000;
+
  190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
 +
  88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
 +
  77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
 +
  102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
 +
  135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
 +
  5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
 +
  223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
 +
  129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
 +
  251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
 +
  49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
 +
  138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
 +
  ];
 +
  for (var i=0; i < 256 ; i++)
 +
p[256+i] = p[i] = permutation[i];  
  
int[] p = new int[B + B + 2];
+
    var X = parseInt(Mathf.Floor(x)) & 255;                 // FIND UNIT CUBE THAT
float[,] g3 = new float [B + B + 2 , 3];
+
var Y = parseInt(Mathf.Floor(y)) & 255;                // CONTAINS POINT.
float[,] g2 = new float[B + B + 2,2];
+
var Z = parseInt(Mathf.Floor(z)) & 255;
float[] g1 = new float[B + B + 2];
+
      x -= Mathf.Floor(x);                                // FIND RELATIVE X,Y,Z
 +
      y -= Mathf.Floor(y);                                // OF POINT IN CUBE.
 +
      z -= Mathf.Floor(z);
 +
      var    u = fade(x);                              // COMPUTE FADE CURVES
 +
      var      v = fade(y);                              // FOR EACH OF X,Y,Z.
 +
      var      w = fade(z);
 +
      var A = p[]+Y;var AA = p[A]+Z;var AB = p[A+1]+Z;     // HASH COORDINATES OF
 +
        var B = p[X+1]+Y;var BA = p[B]+Z;var BB = p[B+1]+Z;     // THE 8 CUBE CORNERS,
  
float s_curve(float t)
+
      return scale(lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z  ),  // AND ADD
{
+
                                    grad(p[BA  ], x-1, y  , z  )), // BLENDED
return t * t * (3.0F - 2.0F * t);
+
                            lerp(u, grad(p[AB  ], x  , y-1, z  ),  // RESULTS
}
+
                                    grad(p[BB  ], x-1, y-1, z  ))),// FROM  8
+
                    lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
float lerp (float t, float a, float b)
+
                                    grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
{  
+
                            lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
return a + t * (b - a);
+
                                    grad(p[BB+1], x-1, y-1, z-1 )))));
}
+
  }
 +
  function fade(t:int) { return t * t * t * (t * (t * 6 - 15) + 10); }
 +
  function lerp( t:int, a:int, b:int) { return a + t * (b - a); }
 +
  function grad(hash:int, x:int, y:int, z:int) {
 +
      var h = hash & 15;                      // CONVERT LO 4 BITS OF HASH CODE
 +
      var u = h<8 ? x : y;                // INTO 12 GRADIENT DIRECTIONS.
 +
          var  v = h<4 ? y : h==12||h==14 ? x : z;
 +
      return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
 +
  }
 +
  function scale(n:int) { return (1 + n)/2; }
  
void setup (float value, out int b0, out int b1, out float r0, out float r1)
+
</syntaxhighlight>
{
+
        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>
+

Latest revision as of 04:01, 23 October 2012

[edit] Description

The following snippet shows how to use noise for smoothly randomly moving objects, rotating them or animated light intensity.

[edit] Usage

Download the package. Open Unity with your own project folder. Double click on the unityPackage in the finder. [PerlinNoise]

This installs the perlin noise class and 3 scripts implementing:

  1. Animated light intensity noise
  2. Animated noise position
  3. Animated noise rotation

To use one of the scripts, just drag them on a game object, to make them move, rotate, animate light based on noise.

[edit] Another function

previous information above is out of date links here are 4 new functions including voronoi on a pretty free license UnityScript noises on forum

Also here is a nearly complete implementation of Perlin noise in UnityScript,although I didn't finish completing it because I didn't understand JavaScript this.noise function. I am sure I will finish it or else you can help if you want the original is here- JavaScript Perlin noise implementation

#pragma strict
 
 
// This is a port of Ken Perlin's Java code. The
// original Java code is at http://cs.nyu.edu/%7Eperlin/noise/.
// Note that in this version, a number from 0 to 1 is returned.
function PerlinNoise() {
var x :int;
var y :int; 
var z :int;
var t :int;
var a :int;
var b :int;
var n :int;
var hash :int;
	 thisnoise (x, y, z);
	 fade(t);
	 lerp( t, a, b);
	 grad(hash, x, y, z);
     scale(n);}
 
function thisnoise (x:int, y:int, z:int) {
 
   var p : int[]; //array
   p = new int[512];
   var permutation : int[] = [ 151,160,137,91,90,15,
   131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
   88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
   77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
   102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
   135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
   5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
   223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
   129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
   251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
   49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
   138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
   ];
   for (var i=0; i < 256 ; i++) 
 p[256+i] = p[i] = permutation[i]; 
 
     var X = parseInt(Mathf.Floor(x)) & 255;                  // FIND UNIT CUBE THAT
	 var Y = parseInt(Mathf.Floor(y)) & 255;                // CONTAINS POINT.
	 var Z = parseInt(Mathf.Floor(z)) & 255;
      x -= Mathf.Floor(x);                                // FIND RELATIVE X,Y,Z
      y -= Mathf.Floor(y);                                // OF POINT IN CUBE.
      z -= Mathf.Floor(z);
      var    u = fade(x);                               // COMPUTE FADE CURVES
       var      v = fade(y);                               // FOR EACH OF X,Y,Z.
      var       w = fade(z);
      var A = p[X  ]+Y;var AA = p[A]+Z;var AB = p[A+1]+Z;      // HASH COORDINATES OF
         var B = p[X+1]+Y;var BA = p[B]+Z;var BB = p[B+1]+Z;      // THE 8 CUBE CORNERS,
 
      return scale(lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),  // AND ADD
                                     grad(p[BA  ], x-1, y  , z   )), // BLENDED
                             lerp(u, grad(p[AB  ], x  , y-1, z   ),  // RESULTS
                                     grad(p[BB  ], x-1, y-1, z   ))),// FROM  8
                     lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
                                     grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
                             lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
                                     grad(p[BB+1], x-1, y-1, z-1 )))));
   }
   function fade(t:int) { return t * t * t * (t * (t * 6 - 15) + 10); }
   function lerp( t:int, a:int, b:int) { return a + t * (b - a); }
   function grad(hash:int, x:int, y:int, z:int) {
      var h = hash & 15;                      // CONVERT LO 4 BITS OF HASH CODE
      var u = h<8 ? x : y;                 // INTO 12 GRADIENT DIRECTIONS.
           var  v = h<4 ? y : h==12||h==14 ? x : z;
      return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
   } 
   function scale(n:int) { return (1 + n)/2; }
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox