-
-
Save kasperkamperman/091c3aeadab3ce92ea496a4f4fe60005 to your computer and use it in GitHub Desktop.
Some messy sketch code to compare noise functions
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
/* Messy sketch code | |
* Just to compare different noise implementation. | |
* Not well documented. | |
* https://mrl.nyu.edu/%7Eperlin/noise/INoise.java | |
* https://plus.google.com/communities/109127054924227823508/s/fixed%20noise | |
*/ | |
const uint8_t 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, | |
}; | |
const uint16_t fadeArray[] = { | |
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 6, 7, | |
9, 10, 12, 14, 17, 19, 22, 25, 29, 32, 36, 40, 45, 49, 54, 60, | |
65, 71, 77, 84, 91, 98, 105, 113, 121, 130, 139, 148, 158, 167, 178, 188, | |
199, 211, 222, 234, 247, 259, 273, 286, 300, 314, 329, 344, 359, 374, 390, 407, | |
424, 441, 458, 476, 494, 512, 531, 550, 570, 589, 609, 630, 651, 672, 693, 715, | |
737, 759, 782, 805, 828, 851, 875, 899, 923, 948, 973, 998, 1023, 1049, 1074, 1100, | |
1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, 1543, | |
1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, 1988, 2018, | |
2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, 2435, 2464, 2493, | |
2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, 2861, 2888, 2915, 2942, | |
2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, 3244, 3267, 3290, 3313, 3336, | |
3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, 3564, 3583, 3601, 3619, 3637, 3654, | |
3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, 3809, 3822, 3836, 3848, 3861, 3873, 3884, | |
3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024, | |
4030, 4035, 4041, 4046, 4050, 4055, 4059, 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085, | |
4086, 4088, 4089, 4091, 4092, 4092, 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095, | |
}; | |
//const PROGMEM uint16_t fadeLUT[] = { | |
const uint16_t fadeLUT[] = { | |
0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x000C, 0x0013, 0x001A, 0x0024, 0x0030, 0x003E, 0x004F, 0x0062, 0x0078, | |
0x0091, 0x00AD, 0x00CC, 0x00EE, 0x0115, 0x013E, 0x016C, 0x019D, 0x01D2, 0x020C, 0x024A, 0x028C, 0x02D2, 0x031E, 0x036D, 0x03C2, | |
0x041C, 0x047A, 0x04DD, 0x0546, 0x05B3, 0x0626, 0x069E, 0x071B, 0x079E, 0x0826, 0x08B4, 0x0947, 0x09E0, 0x0A7F, 0x0B23, 0x0BCC, | |
0x0C7C, 0x0D31, 0x0DEC, 0x0EAC, 0x0F72, 0x103F, 0x1110, 0x11E8, 0x12C6, 0x13A9, 0x1492, 0x1580, 0x1675, 0x176F, 0x186F, 0x1974, | |
0x1A80, 0x1B90, 0x1CA7, 0x1DC3, 0x1EE4, 0x200B, 0x2138, 0x2269, 0x23A1, 0x24DD, 0x261F, 0x2766, 0x28B2, 0x2A03, 0x2B59, 0x2CB4, | |
0x2E14, 0x2F79, 0x30E3, 0x3251, 0x33C4, 0x353C, 0x36B8, 0x3838, 0x39BD, 0x3B46, 0x3CD3, 0x3E64, 0x3FF9, 0x4192, 0x432F, 0x44CF, | |
0x4674, 0x481B, 0x49C6, 0x4B75, 0x4D26, 0x4EDB, 0x5093, 0x524D, 0x540B, 0x55CB, 0x578E, 0x5953, 0x5B1B, 0x5CE5, 0x5EB1, 0x607F, | |
0x624F, 0x6421, 0x65F5, 0x67CA, 0x69A1, 0x6B79, 0x6D53, 0x6F2E, 0x7109, 0x72E6, 0x74C4, 0x76A2, 0x7881, 0x7A60, 0x7C40, 0x7E20, | |
0x8000, 0x81DF, 0x83BF, 0x859F, 0x877E, 0x895D, 0x8B3B, 0x8D19, 0x8EF6, 0x90D1, 0x92AC, 0x9486, 0x965E, 0x9835, 0x9A0A, 0x9BDE, | |
0x9DB0, 0x9F80, 0xA14E, 0xA31A, 0xA4E4, 0xA6AC, 0xA871, 0xAA34, 0xABF4, 0xADB2, 0xAF6C, 0xB124, 0xB2D9, 0xB48A, 0xB639, 0xB7E4, | |
0xB98C, 0xBB30, 0xBCD0, 0xBE6D, 0xC006, 0xC19B, 0xC32C, 0xC4B9, 0xC642, 0xC7C7, 0xC947, 0xCAC3, 0xCC3B, 0xCDAE, 0xCF1C, 0xD086, | |
0xD1EB, 0xD34B, 0xD4A6, 0xD5FC, 0xD74D, 0xD899, 0xD9E0, 0xDB22, 0xDC5E, 0xDD96, 0xDEC7, 0xDFF4, 0xE11B, 0xE23C, 0xE358, 0xE46F, | |
0xE580, 0xE68B, 0xE790, 0xE890, 0xE98A, 0xEA7F, 0xEB6D, 0xEC56, 0xED39, 0xEE17, 0xEEEF, 0xEFC0, 0xF08D, 0xF153, 0xF213, 0xF2CE, | |
0xF383, 0xF433, 0xF4DC, 0xF580, 0xF61F, 0xF6B8, 0xF74B, 0xF7D9, 0xF861, 0xF8E4, 0xF961, 0xF9D9, 0xFA4C, 0xFAB9, 0xFB22, 0xFB85, | |
0xFBE4, 0xFC3D, 0xFC92, 0xFCE1, 0xFD2D, 0xFD73, 0xFDB5, 0xFDF3, 0xFE2D, 0xFE62, 0xFE93, 0xFEC1, 0xFEEA, 0xFF11, 0xFF33, 0xFF52, | |
0xFF6E, 0xFF87, 0xFF9D, 0xFFB0, 0xFFC1, 0xFFCF, 0xFFDB, 0xFFE5, 0xFFEC, 0xFFF3, 0xFFF7, 0xFFFB, 0xFFFD, 0xFFFE, 0xFFFF, 0xFFFF, | |
0xFFFF | |
}; | |
#include "FastLED.h"; | |
int amountOfLights = 100; | |
// debug duration | |
unsigned long t1; // for measuring purposes | |
unsigned long t2; // for measuring purposes | |
unsigned long t3 = 0; // for measuring purposes | |
int32_t perlinTimeInc = 1000L; | |
int32_t perlinXInc = 1000L; | |
int32_t perlinTimePosition = 0; | |
int32_t maxVal = 0; | |
int32_t minVal = 1000; | |
int32_t lastMaxVal = -1; | |
int32_t lastMinVal = 0; | |
void setup() | |
{ Serial.begin(57600); | |
} | |
void loop() | |
{ | |
int i = 0; | |
//for(int i=0;i<amountOfLights;i++) | |
//{ | |
Serial.print(F("perlin ")); | |
setTime(); | |
uint16_t val = renderNoise(i*perlinXInc, 0, perlinTimePosition); | |
printTime(); | |
// Serial.print("fastled "); | |
// setTime(); | |
uint16_t val2 = inoise16(i*perlinXInc, 0, perlinTimePosition); | |
// printTime(); | |
// Serial.print("fastled mod "); | |
// setTime(); | |
uint16_t val3 = inoise16_mod(i*perlinXInc, 0, perlinTimePosition); | |
// printTime(); | |
// Serial.print("input value:"); | |
// Serial.println(perlinTimePosition); | |
//int32_t val = renderNoise(1, 2, 3); | |
// Serial.print(val); | |
// Serial.print(" - "); | |
// Serial.println(val3); | |
for(int i=0;i<(val>>9);i++) | |
{ Serial.print("+"); | |
} | |
Serial.println(" (perlin)"); | |
// for(int i=0;i<(val2>>9);i++) | |
// { Serial.print("-"); | |
// } | |
// Serial.println(" (fastled)"); | |
for(int i=0;i<(val3>>9);i++) | |
{ Serial.print("*"); | |
} | |
Serial.println(" (fastled mod)"); | |
if(val>maxVal) { | |
maxVal = val; | |
} | |
if(val<minVal) { | |
minVal = val; | |
} | |
//if(val>127) Serial.print("*"); | |
//else Serial.print("-"); | |
//} | |
// go a step further in time (input for y function in perlin noise) | |
perlinTimePosition = perlinTimePosition + perlinTimeInc; | |
//Serial.print("time: "); | |
//Serial.print(passedTime); | |
//Serial.print(" max: "); | |
//Serial.println(int32_testTime); | |
//Serial.print("array: "); | |
// if(minVal != lastMinVal) { | |
// Serial.print("- min: "); | |
// Serial.println(minVal); | |
// lastMinVal = minVal; | |
// } | |
// | |
// if(maxVal != lastMaxVal) { | |
// Serial.print("- max: "); | |
// Serial.println(maxVal); | |
// lastMaxVal = maxVal; | |
// } | |
// if(minVal < 32.767) { | |
// Serial.print("- min: "); | |
// Serial.println(minVal); | |
// | |
// } | |
// | |
// if(maxVal > 32.767) { | |
// Serial.print("- max: "); | |
// Serial.println(maxVal); | |
// } | |
//Serial.println(); | |
delay(10); | |
} | |
uint16_t renderNoise(int32_t x, int32_t y, int32_t z) | |
{ //return 137 + (inoise(x, y, z)/512); | |
//int32_t temp = inoise(x, y, z) + 36739; | |
int32_t temp = inoise(x, y, z) + 32767; | |
//36739 | |
return constrain(temp, 0, 65535); | |
} | |
int32_t inoise(int32_t x, int32_t y, int32_t z) | |
{ | |
int32_t X = x>>16 & 255, Y = y>>16 & 255, Z = z>>16 & 255, N = 1L<<16; | |
x &= N-1; | |
y &= N-1; | |
z &= N-1; | |
int32_t u=fade(x),v=fade(y),w=fade(z), A=p[X ]+Y, AA=p[A]+Z, AB=p[A+1]+Z, | |
B=p[X+1]+Y, BA=p[B]+Z, BB=p[B+1]+Z; | |
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), | |
grad(p[BA ], x-N , y , z )), | |
lerp(u, grad(p[AB ], x , y-N , z ), | |
grad(p[BB ], x-N , y-N , z ))), | |
lerp(v, lerp(u, grad(p[AA+1], x , y , z-N ), | |
grad(p[BA+1], x-N , y , z-N )), | |
lerp(u, grad(p[AB+1], x , y-N , z-N ), | |
grad(p[BB+1], x-N , y-N , z-N )))); | |
} | |
int32_t lerp(int32_t t, int32_t a, int32_t b) { return a + (t * (b - a) >> 12); } | |
int16_t lerp15by12( int16_t a, int16_t b, uint16_t frac) | |
{ | |
//if(1) return (lerp(frac,a,b)); | |
int16_t result; | |
if( b > a) { | |
uint16_t delta = b - a; | |
uint16_t scaled = scale16(delta,frac<<4); | |
result = a + scaled; | |
} else { | |
uint16_t delta = a - b; | |
uint16_t scaled = scale16(delta,frac<<4); | |
result = a - scaled; | |
} | |
return result; | |
} | |
//uint16_t scale16( uint16_t i, uint16_t scale ) | |
//{ | |
// uint16_t result; | |
// //result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536; // old way | |
// | |
// result = ((uint32_t)(i) * (uint32_t)(scale+1)) / 65536; // new way | |
// | |
// return result; | |
//} | |
//int32_t grad(int32_t hash, int32_t x, int32_t y, int32_t z) | |
//{ int32_t h = hash&15, u = h<8?x:y, v = h<4?y:h==12||h==14?x:z; | |
// return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); | |
//} | |
// Source: http://riven8192.blogspot.com/2010/08/calculate-perlinnoise-twice-as-fast.html | |
// 1ms faster on Arduino UNO with 100 calculations, also faster on Teensy | |
int32_t grad(int32_t hash, int32_t x, int32_t y, int32_t z) | |
{ | |
switch(hash & 0xF) | |
{ | |
case 0x0: return x + y; | |
case 0x1: return -x + y; | |
case 0x2: return x - y; | |
case 0x3: return -x - y; | |
case 0x4: return x + z; | |
case 0x5: return -x + z; | |
case 0x6: return x - z; | |
case 0x7: return -x - z; | |
case 0x8: return y + z; | |
case 0x9: return -y + z; | |
case 0xA: return y - z; | |
case 0xB: return -y - z; | |
case 0xC: return y + x; | |
case 0xD: return -y + z; | |
case 0xE: return y - x; | |
case 0xF: return -y - z; | |
default: return 0; // never happens | |
} | |
} | |
//fastled | |
int16_t grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) { | |
hash = hash&15; | |
int16_t u = hash<8?x:y; | |
int16_t v = hash<4?y:hash==12||hash==14?x:z; | |
if(hash&1) { u = -u; } | |
if(hash&2) { v = -v; } | |
return (u+v)>>1; | |
} | |
int32_t fade(int32_t t) { | |
int32_t t0 = fadeArray[t >> 8], t1 = fadeArray[min(255, (t >> 8) + 1)]; | |
return t0 + ( (t & 255) * (t1 - t0) >> 8 ); | |
} | |
// modified test for 16 bit fade curve | |
int32_t fade16(int32_t t) { | |
//int32_t t0 = fadeArray[t >> 8], t1 = fadeArray[min(255, (t >> 8) + 1)]; | |
//return (t0 + ( (t & 255) * (t1 - t0) >> 8 )) << 4; | |
// new array | |
int32_t index = t >> 8; | |
return lerp16by8(fadeLUT[index], fadeLUT[index + 1], t&255); | |
//int32_t t0 = fadeLUT[index]; | |
//int32_t t1 = fadeLUT[min(255, index + 1)]; | |
//int32_t t1 = fadeLUT[index + 1]; | |
//return (t0 + ( (t & 255) * (t1 - t0) >> 8 )); | |
// return lerp16by8(t0, t1, t&255); | |
//int32_t index = t >> 8; | |
//int32_t interpolation = t & 255; | |
//return lerp16by8(pgm_read_word_near(fadeLUT + index), pgm_read_word_near(fadeLUT + (index + 1)), interpolation); | |
} | |
// ------------ FASTLED --------------- | |
int16_t inoise16_raw_mod(uint32_t x, uint32_t y, uint32_t z) | |
{ | |
// Find the unit cube containing the point | |
uint8_t X = (x>>16)&0xFF; | |
uint8_t Y = (y>>16)&0xFF; | |
uint8_t Z = (z>>16)&0xFF; | |
// Hash cube corner coordinates | |
uint8_t A = p[X]+Y; | |
uint8_t AA = p[A]+Z; | |
uint8_t AB = p[A+1]+Z; | |
uint8_t B = p[X+1]+Y; | |
uint8_t BA = p[B] + Z; | |
uint8_t BB = p[B+1]+Z; | |
// Get the relative position of the point in the cube | |
uint16_t u = x & 0xFFFF; | |
uint16_t v = y & 0xFFFF; | |
uint16_t w = z & 0xFFFF; | |
// Get a signed version of the above for the grad function | |
int16_t xx = (u >> 1) & 0x7FFF; | |
int16_t yy = (v >> 1) & 0x7FFF; | |
int16_t zz = (w >> 1) & 0x7FFF; | |
uint16_t N = 0x8000L; | |
u = fade16(u); v = fade16(v); w = fade16(w); | |
// skip the log fade adjustment for the moment, otherwise here we would | |
// adjust fade values for u,v,w | |
int16_t X1 = lerp15by16(grad(p[AA], xx, yy, zz), grad(p[BA], xx - N, yy, zz), u); | |
int16_t X2 = lerp15by16(grad(p[AB], xx, yy-N, zz), grad(p[BB], xx - N, yy - N, zz), u); | |
int16_t X3 = lerp15by16(grad(p[AA+1], xx, yy, zz-N), grad(p[BA+1], xx - N, yy, zz-N), u); | |
int16_t X4 = lerp15by16(grad(p[AB+1], xx, yy-N, zz-N), grad(p[BB+1], xx - N, yy - N, zz - N), u); | |
int16_t Y1 = lerp15by16(X1,X2,v); | |
int16_t Y2 = lerp15by16(X3,X4,v); | |
int16_t ans = lerp15by16(Y1,Y2,w); | |
return ans; | |
} | |
uint16_t inoise16_mod(uint32_t x, uint32_t y, uint32_t z) { | |
int32_t ans = inoise16_raw_mod(x,y,z); | |
ans = ans + 19052L; | |
uint32_t pan = ans; | |
return (pan*220L)>>7; | |
// // return scale16by8(pan,220)<<1; | |
// return ((inoise16_raw(x,y,z)+19052)*220)>>7; | |
// return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; | |
} | |
void setTime() | |
{ t1 = micros(); | |
} | |
void printTime() | |
{ | |
t2 = micros()-t1; | |
if(t2>t3) t3 = t2; | |
Serial.print(F("time: ")); | |
//Serial.print(t3); | |
//Serial.print(" "); | |
Serial.print(t2); | |
Serial.println(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment