Skip to content

Instantly share code, notes, and snippets.

@kasperkamperman
Created April 25, 2017 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kasperkamperman/091c3aeadab3ce92ea496a4f4fe60005 to your computer and use it in GitHub Desktop.
Save kasperkamperman/091c3aeadab3ce92ea496a4f4fe60005 to your computer and use it in GitHub Desktop.
Some messy sketch code to compare noise functions
/* 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