updated scaling
This commit is contained in:
		| @@ -519,12 +519,12 @@ uint32_t hashInt(uint32_t s); | ||||
| int32_t perlin1D_raw(uint32_t x, bool is16bit = false); | ||||
| int32_t perlin2D_raw(uint32_t x, uint32_t y, bool is16bit = false); | ||||
| int32_t perlin3D_raw(uint32_t x, uint32_t y, uint32_t z, bool is16bit = false); | ||||
| uint8_t perlin8(uint16_t x); | ||||
| uint8_t perlin8(uint16_t x, uint16_t y); | ||||
| uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z); | ||||
| uint16_t perlin16(uint32_t x); | ||||
| uint16_t perlin16(uint32_t x, uint32_t y); | ||||
| uint16_t perlin16(uint32_t x, uint32_t y, uint32_t z); | ||||
| uint8_t perlin8(uint16_t x); | ||||
| uint8_t perlin8(uint16_t x, uint16_t y); | ||||
| uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z); | ||||
|  | ||||
| // fast (true) random numbers using hardware RNG, all functions return values in the range lowerlimit to upperlimit-1 | ||||
| // note: for true random numbers with high entropy, do not call faster than every 200ns (5MHz) | ||||
|   | ||||
| @@ -631,7 +631,7 @@ static inline __attribute__((always_inline)) int32_t hashToGradient(uint32_t h) | ||||
|   //return (h & 0xFF) - 128; // use PERLIN_SHIFT 7 | ||||
|   //return (h & 0x0F) - 8; // use PERLIN_SHIFT 3 | ||||
|   //return (h & 0x07) - 4; // use PERLIN_SHIFT 2 | ||||
|   return (h & 0x03) - 2; // use PERLIN_SHIFT 1 | ||||
|   return (h & 0x03) - 2; // use PERLIN_SHIFT 1 -> closest to original fastled version | ||||
| } | ||||
|  | ||||
| // Gradient functions for 1D, 2D and 3D Perlin noise  note: forcing inline produces smaller code and makes it 3x faster! | ||||
| @@ -658,6 +658,17 @@ static inline __attribute__((always_inline)) int32_t gradient3D(uint32_t x0, int | ||||
|   h ^= h >> 15; | ||||
|   h *= 0x92C3412B; | ||||
|   h ^= h >> 13; | ||||
|  | ||||
| /* | ||||
|   // fastled version: 25% slower but gives original "look" | ||||
|   h = h&15; | ||||
|   int32_t u = h<8?dx:dy; | ||||
|   int32_t v = h<4?dy:h==12||h==14?dx:dz; | ||||
|   if(h&1) { u = -u; } | ||||
|   if(h&2) { v = -v; } | ||||
|   return (u >> 1) + (v >> 1) + (u & 0x1); | ||||
| */ | ||||
|   // closer to actual perlin version | ||||
|   return ((hashToGradient(h) * dx + hashToGradient(h>>(1+PERLIN_SHIFT)) * dy + hashToGradient(h>>(1 + 2*PERLIN_SHIFT)) * dz) * 85) >> (8 + PERLIN_SHIFT); // scale to 16bit, x*85 >> 8 = x/3 | ||||
| } | ||||
|  | ||||
| @@ -665,7 +676,7 @@ static inline __attribute__((always_inline)) int32_t gradient3D(uint32_t x0, int | ||||
| static uint32_t smoothstep(const uint32_t t) { | ||||
|   uint32_t t_squared = (t * t) >> 16; | ||||
|   uint32_t factor = (3 << 16) - ((t << 1)); | ||||
|   return (t_squared * factor) >> 18; // scale to avoid overflows | ||||
|   return (t_squared * factor) >> 18; // scale to avoid overflows and give best resolution | ||||
| } | ||||
|  | ||||
| // simple linear interpolation for fixed-point values, scaled for perlin noise use | ||||
| @@ -771,25 +782,26 @@ int32_t perlin3D_raw(uint32_t x, uint32_t y, uint32_t z, bool is16bit) { | ||||
|  | ||||
| uint16_t perlin16(uint32_t x) { | ||||
|   //return ((perlin1D_raw(x) * 1168) >> 10) + 0x7FFF; //scale to 16bit and offset (full range) | ||||
|   return ((perlin1D_raw(x) * 895) >> 10) + 34616; //scale to 16bit and offset (fastled range) | ||||
|   //return ((perlin1D_raw(x) * 895) >> 10) + 34616; //scale to 16bit and offset (fastled range) -> 8 steps | ||||
|   return ((perlin1D_raw(x) * 1159) >> 10) + 32803; //scale to 16bit and offset (fastled range) -> 8 steps | ||||
| } | ||||
|  | ||||
| uint16_t perlin16(uint32_t x, uint32_t y) { | ||||
|  return ((perlin2D_raw(x, y) * 1359) >> 10) + 31508; //scale to 16bit and offset (empirical values with some overflow safety margin) | ||||
|  return ((perlin2D_raw(x, y) * 1537) >> 10) + 32725; //scale to 16bit and offset (empirical values with some overflow safety margin) | ||||
| } | ||||
|  | ||||
| uint16_t perlin16(uint32_t x, uint32_t y, uint32_t z) { | ||||
|   return ((perlin3D_raw(x, y, z) * 1923) >> 10) + 31290; //scale to 16bit and offset (empirical values with some overflow safety margin) | ||||
|   return ((perlin3D_raw(x, y, z) * 1731) >> 10) + 33147; //scale to 16bit and offset (empirical values with some overflow safety margin) | ||||
| } | ||||
|  | ||||
| uint8_t perlin8(uint16_t x) { | ||||
|   return (((perlin1D_raw((uint32_t)x << 8, true) * 1168) >> 10) + 0x7FFF) >> 8; | ||||
|   return (((perlin1D_raw((uint32_t)x << 8, true) * 1353) >> 10) + 32769) >> 8; | ||||
| } | ||||
|  | ||||
| uint8_t perlin8(uint16_t x, uint16_t y) { | ||||
|   return (((perlin2D_raw((uint32_t)x << 8, (uint32_t)y << 8, true) * 1359) >> 10) + 31508) >> 8; | ||||
|   return (((perlin2D_raw((uint32_t)x << 8, (uint32_t)y << 8, true) * 1620) >> 10) + 32771) >> 8; | ||||
| } | ||||
|  | ||||
| uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z) { | ||||
|   return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 1923) >> 10) + 31290) >> 8; //scale to 8bit | ||||
|   return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 2015) >> 10) + 33168) >> 8; //scale to 8bit | ||||
| } | ||||
							
								
								
									
										225
									
								
								wled00/wled.cpp
									
									
									
									
									
								
							
							
						
						
									
										225
									
								
								wled00/wled.cpp
									
									
									
									
									
								
							| @@ -339,231 +339,6 @@ void WLED::setup() | ||||
|   #else | ||||
|     DEBUG_PRINTLN(F("arduino-esp32 v1.0.x\n"));  // we can't say in more detail. | ||||
|   #endif | ||||
|  | ||||
|  | ||||
|   uint32_t start; | ||||
|   uint32_t end; | ||||
|   uint32_t time; | ||||
|   uint8_t offset = hw_random()+hw_random(); | ||||
|   delay(2000); | ||||
|   /* | ||||
| //online serial plotter: https://sekigon-gonnoc.github.io/web-serial-plotter/  format is "valueA:213423, ValueB:123123, \n" | ||||
|   for(int i = 0; i < 0xFFFFFFF; i+=10) { | ||||
|     //Serial.print(inoise16(i, offset, (offset >> 3)));  Serial.print(" "); //x | ||||
|     //Serial.print(inoise16(offset, i, (offset >> 3)));  Serial.print(" "); //y | ||||
|     //Serial.print(inoise16(offset, (offset >> 3), i));  Serial.print(" "); //z | ||||
|     //Serial.print(perlin16(i, offset, (offset >> 3)));  Serial.print(" "); //x | ||||
|     //Serial.print(perlin16(offset, i, (offset >> 3)));  Serial.print(" "); //y | ||||
|     //Serial.print(perlin16(offset, (offset >> 3), i));  Serial.print(" "); //z | ||||
|      | ||||
|     //Serial.print("Fastled:");Serial.print(inoise16(i, offset+i/2, i + (offset >> 3))); Serial.print(", "); //mixed mode | ||||
|     //Serial.print("New:");Serial.println(perlin16(i, offset+i/2, i + (offset >> 3)));// Serial.println(", "); | ||||
|      | ||||
|     //Serial.print("Fastled:");Serial.print(inoise16(i, offset+i/2)); Serial.print(", "); //mixed mode | ||||
|     //Serial.print("New:");Serial.println(perlin16(i, offset+i/2));// Serial.println(", "); | ||||
|  | ||||
|     //Serial.print("Fastled:");Serial.print(inoise16(i)); Serial.print(", "); //mixed mode | ||||
|     //Serial.print("New:");Serial.println(perlin16(i));// Serial.println(", "); | ||||
|      | ||||
|     Serial.print("Fastled3D:");Serial.print(inoise8(i, offset+i/2, i + (offset >> 3))); Serial.print(", "); //mixed mode | ||||
|     Serial.print("New3D:");Serial.print(perlin8(i, offset+i/2, i + (offset >> 3)));// Serial.println(", "); | ||||
|     Serial.print(", "); | ||||
|     Serial.print("Fastled2D:");Serial.print(inoise8(i, offset+i/2)); Serial.print(", "); //mixed mode | ||||
|     Serial.print("New2D:");Serial.print(perlin8(i, offset+i/2));// Serial.println(", "); | ||||
|     Serial.print(", "); | ||||
|     Serial.print("Fastled1D:");Serial.print(inoise8(i)); Serial.print(", "); //mixed mode | ||||
|     Serial.print("New1D:");Serial.println(perlin8(i));// Serial.println(", "); | ||||
|      | ||||
|     //Serial.print(inoise16(i, offset+i/2, i + (offset >> 3))); Serial.print(","); //mixed mode | ||||
|     //Serial.println(perlin16(i, offset+i/2, i + (offset >> 3)));// Serial.println(", "); | ||||
|     //delay(10); | ||||
|    // Serial.println(perlin3D_raw(i, offset+i/4, i*2 + (offset >> 3))); //raw | ||||
|   }*/ | ||||
|  | ||||
| /* | ||||
|   for(int i = 0; i <  0x2FFFF; i+=100) { | ||||
|     uint32_t pos = i + offset; | ||||
|     Serial.print(inoise8_raw((pos)>>3, (pos)>>3));  Serial.print(",");  | ||||
|     Serial.print(inoise8((pos)>>3, (pos)>>3, (pos)>>3));  Serial.print(",");  | ||||
|     Serial.print(inoise16(pos*20, pos*30));  Serial.print(",");  | ||||
|     //Serial.print(inoise16_raw(pos*20, pos*30, pos*40));  Serial.print(",");  | ||||
|     Serial.print(inoise16(pos*20, pos*20, pos*20));  Serial.print(",");  | ||||
|     //Serial.print(((perlin1D_raw(pos*20)* 85)>>7) + 0x7FFF);  Serial.print(",");  | ||||
|     Serial.print(perlin1D_raw(pos*20));  Serial.print(",");  | ||||
|     Serial.print(perlin2D_raw(pos*20, pos*20));  Serial.print(",");  | ||||
|     //Serial.print(perlin2D_raw(pos*20, pos*30) + 0x7FFF);  Serial.print(",");  | ||||
|     Serial.println(perlin3D_raw(pos*20, pos*20, pos*20)); | ||||
|     //Serial.println(((perlin3D_raw(pos*20, pos*30, pos*40) * 85)>>7) + 0x7FFF); | ||||
|   }*/ | ||||
|  | ||||
| /* | ||||
|   for(int i = 0; i <  0xF0000; i+=55) { | ||||
|     Serial.print(inoise8_raw(i,i+5648) / 2);  Serial.print(","); // +/-32 ? | ||||
|     Serial.print(((int16_t)perlin8(i,i+5648) - 0x7F) >> 2);  Serial.print(","); | ||||
|     Serial.print(inoise8(i,i/3,i/5));  Serial.print(","); | ||||
|     Serial.print(perlin8(i,i/3,i/5));  Serial.print(",");  | ||||
|     Serial.print(inoise8(i,i/3));  Serial.print(",");  | ||||
|     Serial.print(perlin8(i,i/3));  Serial.print(",");  | ||||
|     Serial.print(inoise8(i));  Serial.print(",");  | ||||
|     Serial.println(perlin8(i));   | ||||
|   } | ||||
| */ | ||||
|   int32_t minval=0xFFFFF; | ||||
|   int32_t maxval=0; | ||||
|    start = micros(); | ||||
|   for(int i = 0; i <  0xFFFFF; i+=50) { | ||||
|     uint16_t pos = i + offset; | ||||
|     int32_t noiseval = inoise8_raw(pos); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|      end = micros(); | ||||
|     time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
|   Serial.print(" inoise8_raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|  | ||||
|   minval=0xFFFFF; | ||||
|   maxval=0; | ||||
|    | ||||
|   start = micros(); | ||||
|   for(int i = 0; i <  0xFFFFFF; i+=50) { | ||||
|     uint32_t pos = i + offset; | ||||
|     //int32_t noiseval = inoise16(pos, pos+4684165, pos+985685); | ||||
|     int32_t noiseval = inoise16(hw_random(), hw_random(), hw_random()); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|    end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
|   Serial.print(" inoise16_3D min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|  | ||||
|   minval=0xFFFFF; | ||||
|   maxval=0; | ||||
|     start = micros(); | ||||
|   for(int i = 0; i <  0xFFFFFF; i+=50) { | ||||
|     uint32_t pos = i + offset; | ||||
|     //int32_t noiseval = perlin16(hw_random()); | ||||
|     int32_t noiseval = perlin1D_raw(hw_random(),false); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|      end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
| Serial.print(" perlin1D raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|   minval=0xFFFFF; | ||||
|   maxval=0; | ||||
|     start = micros(); | ||||
|   for(int i = 0; i <  0xFFFFFF; i+=50) { | ||||
|     uint32_t pos = i + offset; | ||||
|     //int32_t noiseval = perlin16( hw_random(),  hw_random()); | ||||
|     int32_t noiseval = perlin2D_raw( hw_random(),  hw_random()); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|      end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
|   Serial.print(" perlin2D raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|  | ||||
|  | ||||
|   minval=0xFFFFF; | ||||
|   maxval=0; | ||||
|   for(int i = 0; i <  0xFFFFFF; i+=50) { | ||||
|     uint32_t pos = i + offset; | ||||
|     //int32_t noiseval = perlin3D_raw(pos, pos+46845, pos+654684); | ||||
|     //int32_t noiseval = perlin3D_raw(hw_random(), hw_random(), hw_random()); | ||||
|     int32_t noiseval = perlin16(hw_random(), hw_random(), hw_random()); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|      end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
|   Serial.print(" perlin16 min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|  | ||||
|   minval=0xFFFFF; | ||||
|   maxval=0; | ||||
|   for(int i = 0; i <  0xFFFFFF; i+=50) { | ||||
|     uint32_t pos = i + offset; | ||||
|     //int32_t noiseval = perlin3D_raw(pos, pos+46845, pos+654684); | ||||
|     int32_t noiseval = perlin3D_raw(hw_random(), hw_random(), hw_random(),false); | ||||
|     //int32_t noiseval = perlin16(hw_random(), hw_random(), hw_random()); | ||||
|     if(noiseval < minval) minval = noiseval; | ||||
|     if(noiseval > maxval) maxval = noiseval; | ||||
|   } | ||||
|      end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("time: "); Serial.print(time); | ||||
|   Serial.print(" perlin3D_raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval); | ||||
|  | ||||
|  | ||||
|  | ||||
|   volatile uint32_t temp; | ||||
|   start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += inoise8(i); | ||||
|   } | ||||
|   end = micros(); | ||||
|   time = end - start; | ||||
|   Serial.print("inoise8: "); | ||||
|   Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|    start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += inoise16(i,i<<1,i<<2); | ||||
|   } | ||||
|    end = micros(); | ||||
|    time = end - start; | ||||
|     Serial.print("inoise16:"); | ||||
|     Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|        start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += perlin1D_raw(i); | ||||
|   } | ||||
|    end = micros(); | ||||
|    time = end - start; | ||||
|     Serial.print("perlin1Draw:"); | ||||
|     Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|        start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += perlin2D_raw(i,i*33); | ||||
|   } | ||||
|    end = micros(); | ||||
|    time = end - start; | ||||
|     Serial.print("perlin2Draw:"); | ||||
|     Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|      start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += perlin16(i,i*33,i*17); | ||||
|   } | ||||
|    end = micros(); | ||||
|    time = end - start; | ||||
|   Serial.print("perlin163D:"); | ||||
|   Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|       | ||||
|      start = micros(); | ||||
|   for(int i = 0; i < 100000; i++){ | ||||
|     temp += perlin3D_raw(i,i*33,i*17); | ||||
|   } | ||||
|    end = micros(); | ||||
|    time = end - start; | ||||
|   Serial.print("perlin3D raw:"); | ||||
|   Serial.print(temp); | ||||
|   Serial.print("time: "); | ||||
|   Serial.println(time); | ||||
|  | ||||
|  | ||||
|   DEBUG_PRINTF_P(PSTR("CPU:   %s rev.%d, %d core(s), %d MHz.\n"), ESP.getChipModel(), (int)ESP.getChipRevision(), ESP.getChipCores(), ESP.getCpuFreqMHz()); | ||||
|   DEBUG_PRINTF_P(PSTR("FLASH: %d MB, Mode %d "), (ESP.getFlashChipSize()/1024)/1024, (int)ESP.getFlashChipMode()); | ||||
|   #ifdef WLED_DEBUG | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Damian Schneider
					Damian Schneider