#ifndef NOISE_HXX #define NOISE_HXX /* PerlinNoise2D */ // cosine interpolation float cosrp(float a, float b, float x) { float ft = x * 3.1415927; float f = (1 - cos(ft)) * 0.5; return a*(1-f) + b*f; } // random number generator float Noise2D(int x, int y) { int n = x + y * 57; n = (n<<13) ^ n; float r = ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);; return r; } // interpolating noise float SmoothNoise2D(float x, float y) { double n1 = Noise2D((int)x, (int)y); double n2 = Noise2D((int)x + 1, (int)y); double n3 = Noise2D((int)x, (int)y + 1); double n4 = Noise2D((int)x + 1, (int)y + 1); double i1 = cosrp(n1, n2, x - (int)x); double i2 = cosrp(n3, n4, x - (int)x); return cosrp(i1, i2, y - (int)y); } float PerlinNoise2D(float x, float y, float persistence, float frequency, float octaves) { double total = 0.0; double amplitude = 1; for(int lcv = 0; lcv < octaves; lcv++) { total = total + SmoothNoise2D(x * frequency, y * frequency) * amplitude; frequency = frequency * 2; amplitude = amplitude * persistence; } total = MIN(MAX(total,0), 1); return total; } /* PerlinNoise3D */ // random number generator float Noise3D(int x, int y, int z) { int n = x + y * 57 + z; n = (n<<13) ^ n; float r = ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);; return r; } // interpolating noise float SmoothNoise3D(float x, float y, float z) { double n1 = Noise3D((int)x, (int)y, (int)z); double n2 = Noise3D((int)x + 1, (int)y, (int)z); double n3 = Noise3D((int)x, (int)y + 1, (int)z); double n4 = Noise3D((int)x + 1, (int)y + 1, (int)z); double n5 = Noise3D((int)x, (int)y, (int)z + 1); double n6 = Noise3D((int)x + 1, (int)y, (int)z + 1); double n7 = Noise3D((int)x, (int)y + 1, (int)z + 1); double n8 = Noise3D((int)x + 1, (int)y + 1, (int)z + 1); double i1 = cosrp(n1, n2, x - (int)x); double i2 = cosrp(n3, n4, x - (int)x); double i3 = cosrp(n5, n6, x - (int)x); double i4 = cosrp(n7, n8, x - (int)x); double i5 = cosrp(i1, i2, y - (int)y); double i6 = cosrp(i3, i4, y - (int)y); return cosrp(i5, i6, z - (int)z); } float PerlinNoise3D(float x, float y, float z, float persistence, float frequency, float octaves) { double total = 0.0; double amplitude = 1; for(int lcv = 0; lcv < octaves; lcv++) { total = total + SmoothNoise3D(x * frequency, y * frequency, z * frequency) * amplitude; frequency = frequency * 2; amplitude = amplitude * persistence; } total = MIN(MAX(total,0), 1); return total; } /* improved PerlinNoise3D */ void initializeMatrix(std::vector<int>& p) { int permutations[512] = { 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(int i=0; i < 256 ; i++) { p[i] = permutations[i]; p[256+i] = permutations[i]; } } float fade(float t) { return (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f)); } float grad(int hash, float x, float y, float z) { int h = hash & 15; float u = (h < 8) ? x : y; float v = (h < 4) ? y : (h == 12 || h == 14) ? x : z; return ( ( ((h&1) == 0) ? u : -u ) + ( ((h&2) == 0) ? v : -v )); } float PerlinNoise3D_new(float x, float y, float z) { std::vector<int> p(512); initializeMatrix(p); int X = (int)floor(x) & 255; int Y = (int)floor(y) & 255; int Z = (int)floor(z) & 255; x -= floor(x); y -= floor(y); z -= floor(z); float u = fade(x); float v = fade(y); float w = fade(z); int A = p[X] + Y; int AA = p[A] + Z; int AB = p[A+1] + Z; int B = p[X+1] + Y; int BA = p[B] + Z; int BB = p[B+1] + Z; return lerp(lerp(lerp(grad(p[AA ], x , y , z ), grad(p[BA ], x-1, y , z ), u), lerp(grad(p[AB ], x , y-1, z ), grad(p[BB ], x-1, y-1, z ), u), v), lerp(lerp(grad(p[AA+1], x , y , z-1 ), grad(p[BA+1], x-1, y , z-1 ), u), lerp(grad(p[AB+1], x , y-1, z-1 ), grad(p[BB+1], x-1, y-1, z-1 ), u), v), w); } #endif