| Here is a version I ported from C code (only 1D and 2D). I added the NoiseSize variables to set where the pattern repeats. 
 
 
Strict
Import brl.random
' Perlin Noise
Type TPerlin
	Field NoiseSizeX: Int
	Field NoiseSizeY: Int
	Field NoiseSizeZ: Int
	Const BN = $100
	Const BM = $FF
	Const N = $1000
	Const NP = 12 ' 2^N
	Const NM = $FFF
	Field p: Int[BN + BN + 2]
	Field g1: Double[BN + BN + 2]
	Field g2: Double[BN + BN + 2, 2]
    Const DEFAULT_NOISE_SIZE = $10000
	Method Init (XS: Int = 0, YS: Int = 0, ZS: Int = 0)	
	  Local i: Int, j: Int, k: Int
	  Local s: Double
      If XS <= 0 Then XS = DEFAULT_NOISE_SIZE
      If YS <= 0 Then YS = DEFAULT_NOISE_SIZE
      If ZS <= 0 Then ZS = DEFAULT_NOISE_SIZE
	  NoiseSizeX = XS
	  NoiseSizeY = YS
	  NoiseSizeZ = ZS
	  For i = 0 To BN - 1 
	    p[i] = i
	    g1[i] = Double (Rand (0, BN + BN - 1) - BN) / BN
	    For j = 0 To 1
	      g2[i, j] = Double (Rand (0, BN + BN - 1) - BN) / BN
	    Next
	    s = Sqr (g2[i, 0] * g2[i, 0] + g2[i, 1] * g2[i, 1])
	    g2[i, 0] = g2[i, 0] / s
	    g2[i, 1] = g2[i, 1] / s
	  Next
	  For i = BN - 1 To 0 Step -1
	    k = p[i]
	    j = Rand (0, BN - 1)
	    p[i] = p[j]
	    p[j] = k
	  Next
	  For i = 0 To BN + 1
	    p[BN + i] = p[i]
	    g1[BN + i] = g1[i]
	    For j = 0 To 1 
	      g2[BN + i, j] = g2[i, j]
	    Next
	  Next
	End Method
	Method S_Curve: Double (t: Double)
	  Return t * t * (3.0 - 2.0 * t)
	End Method
	Method Lerp: Double (t: Double, a: Double, b: Double)
	  Return a + t * (b - a)
	End Method
	Method Noise1: Double (x: Double)
	  Local t: Double = x + N
	  Local bx0: Int = Int (Floor (t) Mod NoiseSizeX) & BM
	  Local bx1: Int = Int ((bx0 + 1) Mod NoiseSizeX) & BM
	  Local rx0: Double = t - (Floor (t))
	  Local rx1: Double = rx0 - 1.0
	  Local sx: Double = s_curve (rx0)
	  Local u: Double = rx0 * g1[p[bx0]]
	  Local v: Double = rx1 * g1[p[bx1]]
	  Local c: Double = 0.5 + Lerp (sx, u, v)
	  If c < 0.0 Then c = 0.0 Else If c > 0.99999999 Then c = 0.99999999
	  Return c
	End Method
	Method Noise2: Double (x: Double, y: Double)
	  Local t: Double = Double (x + N)
	  Local bx0: Int = Int (Floor (t) Mod NoiseSizeX) & BM
	  Local bx1: Int = Int ((bx0 + 1) Mod NoiseSizeX) & BM
	  Local rx0: Double = t - (Floor (t))
	  Local rx1: Double = rx0 - 1.0
	  t = y + N
	  Local by0: Int = Int (Floor (t) Mod NoiseSizeY) & BM
	  Local by1: Int = Int ((by0 + 1) Mod NoiseSizeY) & BM
	  Local ry0: Double = t - (Floor (t))
	  Local ry1: Double = ry0 - 1.0
	  Local i: Int = p[bx0]
	  Local j: Int = p[bx1]
	  Local b00: Int = p[i + by0]
	  Local b10: Int = p[j + by0]
	  Local b01: Int = p[i + by1]
	  Local b11: Int = p[j + by1]
	  Local sx: Double = s_curve (rx0)
	  Local sy: Double = s_curve (ry0)
	  Local u: Double = rx0 * g2[b00, 0] + ry0 * g2[b00, 1]
	  Local v: Double = rx1 * g2[b10, 0] + ry0 * g2[b10, 1]
	  Local a: Double = lerp (sx, u, v)
	  u = rx0 * g2[b01, 0] + ry1 * g2[b01, 1]
	  v = rx1 * g2[b11, 0] + ry1 * g2[b11, 1]
	  Local b: Double = Lerp (sx, u, v)
	  Local c: Double = 0.5 + Lerp (sy, a, b)
	  If c < 0.0 Then c = 0.0 Else If c > 0.99999999 Then c = 0.99999999
	  Return c
	End Method
End Type
 And here is a small example:
 
 
 
Strict
Import brl.random
Import "Perlin.bmx"
Const SCREEN_WIDTH = 320
Const SCREEN_HEIGHT = 240
Local i: Int, j: Int
Local r: Int, g: Int, b: Int
Local f: Double
Local x: Double, y: Double
Local u: Double, v: Double
Local Perlin: TPerlin = New TPerlin
Perlin.Init (10, 10, 10)
x = 0.0
y = 0.0
Graphics SCREEN_WIDTH, SCREEN_HEIGHT
Repeat
  For j = 0 To SCREEN_HEIGHT - 1
    For i = 0 To SCREEN_WIDTH - 1
      u = Float (i) / 100.0
      v = Float (j) / 100.0
      f = Perlin.Noise2 (x + u, y + v)
      r = f * 128.0
      g = 128 - f * 128.0
      b = f * 255.0
      SetColor r, g, b
      DrawRect (i, j, 1, 1)
    Next
  Next
  Flip ()
  x :+ 0.1
  y :+ 0.1
Until AppTerminate () Or KeyHit (KEY_ESCAPE)
EndGraphics
 
 |