Created
June 8, 2012 17:12
-
-
Save Fintan/2896935 to your computer and use it in GitHub Desktop.
Perlin Noise Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import flash.events.Event; | |
import flash.display.Shape; | |
import flash.display.Sprite; | |
class Test { | |
static var W = 540; | |
static var H = 300; | |
static var colours = [0x419164, 0x21A4A6, 0x52BAAB, 0x85CCBE]; | |
var perlin:OptimizedPerlin; | |
var noiseScale:Float; | |
var n:Float; | |
var d:Float; | |
var a:Array<Shape>; | |
public function new(){ | |
var s = new Sprite(); | |
s.graphics.beginFill(0xE57705); | |
s.graphics.drawRect(0, 0, W, H); | |
s.graphics.endFill(); | |
flash.Lib.current.addChild(s); | |
perlin = new OptimizedPerlin(null, 1, 0.2); | |
noiseScale = 0.11; | |
n = 0.3; | |
d = 0.14; | |
a = []; | |
for (j in 0...4) { | |
var s = new Shape(); | |
a[j] = s; | |
flash.Lib.current.addChild(s); | |
} | |
flash.Lib.current.addEventListener(Event.ENTER_FRAME, enterFrame); | |
} | |
function enterFrame(e) { | |
n += d; | |
for (j in 0...4) { | |
var y:Int = j * 10; | |
var s:Shape = a[j]; | |
s.graphics.clear(); | |
s.graphics.beginFill(colours[j]); | |
s.graphics.moveTo(0, H); | |
for (x in 0...54) { | |
var noiseVal:Float = perlin.noise((n+x)*noiseScale, (-n+y)*noiseScale, y*noiseScale); | |
s.graphics.lineTo(x*10, 100+noiseVal*100); | |
} | |
s.graphics.lineTo(W, H); | |
s.graphics.endFill(); | |
} | |
} | |
static function main(){ | |
new Test(); | |
} | |
} | |
/** | |
Title: Perlin noise | |
Version: 1.3 | |
Author: Ron Valstar | |
Author URI: http://www.sjeiti.com/ | |
Original code port from http://mrl.nyu.edu/~perlin/noise/ | |
and some help from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm | |
AS3 optimizations by Mario Klingemann http://www.quasimondo.com | |
haXe port and optimization by Nicolas Cannasse http://haxe.org | |
*/ | |
import flash.display.BitmapData; | |
class OptimizedPerlin { | |
private static var P = [ | |
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,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 | |
]; | |
var octaves : Int; | |
var aOctFreq:Array<Float>; // frequency per octave | |
var aOctPers:Array<Float>; // persistence per octave | |
var fPersMax:Float;// 1 / max persistence | |
var iXoffset:Float; | |
var iYoffset:Float; | |
var iZoffset:Float; | |
var baseFactor:Float; | |
public function new( ?seed, ?octaves, ?falloff ) { | |
if( seed == null ) seed = 123; | |
if( falloff == null ) falloff = .5; | |
this.octaves = if( octaves == null ) 4 else octaves; | |
baseFactor = 1 / 64; | |
seedOffset(seed); | |
octFreqPers(falloff); | |
} | |
inline public function noise( _x:Float, _y:Float=1, _z:Float=1 ):Float { | |
_x += iXoffset; | |
_y += iYoffset; | |
_z += iZoffset; | |
var p = P; | |
var s = 0.; | |
for ( i in 0...octaves ){ | |
var fFreq = aOctFreq[i]; | |
var fPers = aOctPers[i]; | |
var x = _x * fFreq; | |
var y = _y * fFreq; | |
var z = _z * fFreq; | |
var xf = x - (x % 1); | |
var yf = y - (y % 1); | |
var zf = z - (z % 1); | |
var X = Std.int(xf) & 255; | |
var Y = Std.int(yf) & 255; | |
var Z = Std.int(zf) & 255; | |
x -= xf; | |
y -= yf; | |
z -= zf; | |
var u = x * x * x * (x * (x*6 - 15) + 10); | |
var v = y * y * y * (y * (y*6 - 15) + 10); | |
var w = z * z * z * (z * (z*6 - 15) + 10); | |
var A = (p[X]) + Y; | |
var AA = (p[A]) + Z; | |
var AB = (p[A+1]) + Z; | |
var B = (p[X+1]) + Y; | |
var BA = (p[B]) + Z; | |
var BB = (p[B+1]) + Z; | |
var x1 = x-1; | |
var y1 = y-1; | |
var z1 = z-1; | |
var hash = (p[BB+1]) & 15; | |
var g1 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z1 )); | |
hash = (p[AB+1]) & 15; | |
var g2 = ((hash&1) == 0 ? (hash<8 ? x : y1) : (hash<8 ? -x : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x : -z1 )); | |
hash = (p[BA+1]) & 15; | |
var g3 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x1 : z1 ) : hash<4 ? -y : ( hash==14 ? -x1 : -z1 )); | |
hash = (p[AA+1]) & 15; | |
var g4 = ((hash&1) == 0 ? (hash<8 ? x : y ) : (hash<8 ? -x : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x : z1 ) : hash<4 ? -y : ( hash==14 ? -x : -z1 )); | |
hash = (p[BB]) & 15; | |
var g5 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z )); | |
hash = (p[AB]) & 15; | |
var g6 = ((hash&1) == 0 ? (hash<8 ? x : y1) : (hash<8 ? -x : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x : z ) : hash<4 ? -y1 : ( hash==14 ? -x : -z )); | |
hash = (p[BA]) & 15; | |
var g7 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x1 : z ) : hash<4 ? -y : ( hash==14 ? -x1 : -z )); | |
hash = (p[AA]) & 15; | |
var g8 = ((hash&1) == 0 ? (hash<8 ? x : y ) : (hash<8 ? -x : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x : z ) : hash<4 ? -y : ( hash==14 ? -x : -z )); | |
g2 += u * (g1 - g2); | |
g4 += u * (g3 - g4); | |
g6 += u * (g5 - g6); | |
g8 += u * (g7 - g8); | |
g4 += v * (g2 - g4); | |
g8 += v * (g6 - g8); | |
s += ( g8 + w * (g4 - g8)) * fPers; | |
} | |
return ( s * fPersMax + 1 ) * .5; | |
} | |
public function fill( bitmap:BitmapData, _x:Float, _y:Float, _z:Float, ?_ ):Void { | |
var baseX:Float; | |
baseX = _x * baseFactor + iXoffset; | |
_y = _y * baseFactor + iYoffset; | |
_z = _z * baseFactor + iZoffset; | |
var width:Int = bitmap.width; | |
var height:Int = bitmap.height; | |
var p = P; | |
var octaves = octaves; | |
var aOctFreq = aOctFreq; | |
var aOctPers = aOctPers; | |
for ( py in 0...height ) | |
{ | |
_x = baseX; | |
for ( px in 0...width ) | |
{ | |
var s = 0.; | |
for ( i in 0...octaves ) | |
{ | |
var fFreq = aOctFreq[i]; | |
var fPers = aOctPers[i]; | |
var x = _x * fFreq; | |
var y = _y * fFreq; | |
var z = _z * fFreq; | |
var xf = x - (x % 1); | |
var yf = y - (y % 1); | |
var zf = z - (z % 1); | |
var X = Std.int(xf) & 255; | |
var Y = Std.int(yf) & 255; | |
var Z = Std.int(zf) & 255; | |
x -= xf; | |
y -= yf; | |
z -= zf; | |
var u = x * x * x * (x * (x*6 - 15) + 10); | |
var v = y * y * y * (y * (y*6 - 15) + 10); | |
var w = z * z * z * (z * (z*6 - 15) + 10); | |
var A = (p[X]) + Y; | |
var AA = (p[A]) + Z; | |
var AB = (p[A+1]) + Z; | |
var B = (p[X+1]) + Y; | |
var BA = (p[B]) + Z; | |
var BB = (p[B+1]) + Z; | |
var x1 = x-1; | |
var y1 = y-1; | |
var z1 = z-1; | |
var hash = (p[BB+1]) & 15; | |
var g1 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z1 )); | |
hash = (p[AB+1]) & 15; | |
var g2 = ((hash&1) == 0 ? (hash<8 ? x : y1) : (hash<8 ? -x : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x : -z1 )); | |
hash = (p[BA+1]) & 15; | |
var g3 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x1 : z1 ) : hash<4 ? -y : ( hash==14 ? -x1 : -z1 )); | |
hash = (p[AA+1]) & 15; | |
var g4 = ((hash&1) == 0 ? (hash<8 ? x : y ) : (hash<8 ? -x : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x : z1 ) : hash<4 ? -y : ( hash==14 ? -x : -z1 )); | |
hash = (p[BB]) & 15; | |
var g5 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z )); | |
hash = (p[AB]) & 15; | |
var g6 = ((hash&1) == 0 ? (hash<8 ? x : y1) : (hash<8 ? -x : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x : z ) : hash<4 ? -y1 : ( hash==14 ? -x : -z )); | |
hash = (p[BA]) & 15; | |
var g7 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x1 : z ) : hash<4 ? -y : ( hash==14 ? -x1 : -z )); | |
hash = (p[AA]) & 15; | |
var g8 = ((hash&1) == 0 ? (hash<8 ? x : y ) : (hash<8 ? -x : -y )) + ((hash&2) == 0 ? hash<4 ? y : ( hash==12 ? x : z ) : hash<4 ? -y : ( hash==14 ? -x : -z )); | |
g2 += u * (g1 - g2); | |
g4 += u * (g3 - g4); | |
g6 += u * (g5 - g6); | |
g8 += u * (g7 - g8); | |
g4 += v * (g2 - g4); | |
g8 += v * (g6 - g8); | |
s += ( g8 + w * (g4 - g8)) * fPers; | |
} | |
var color = Std.int( ( s * fPersMax + 1 ) * 128 ); | |
bitmap.setPixel32( px, py, 0xff000000 | color << 16 | color << 8 | color ); | |
_x += baseFactor; | |
} | |
_y += baseFactor; | |
} | |
} | |
function octFreqPers( fPersistence ) { | |
var fFreq:Float, fPers:Float; | |
aOctFreq = []; | |
aOctPers = []; | |
fPersMax = 0; | |
for ( i in 0...octaves ) { | |
fFreq = Math.pow(2,i); | |
fPers = Math.pow(fPersistence,i); | |
fPersMax += fPers; | |
aOctFreq.push( fFreq ); | |
aOctPers.push( fPers ); | |
} | |
fPersMax = 1 / fPersMax; | |
} | |
function seedOffset( iSeed : Int ) { | |
iXoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647); | |
iYoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647); | |
iZoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment