Skip to content

Commit 95dcb03

Browse files
committed
updated scaling
1 parent 4ecc531 commit 95dcb03

File tree

3 files changed

+23
-236
lines changed

3 files changed

+23
-236
lines changed

wled00/fcn_declare.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,12 @@ uint32_t hashInt(uint32_t s);
519519
int32_t perlin1D_raw(uint32_t x, bool is16bit = false);
520520
int32_t perlin2D_raw(uint32_t x, uint32_t y, bool is16bit = false);
521521
int32_t perlin3D_raw(uint32_t x, uint32_t y, uint32_t z, bool is16bit = false);
522-
uint8_t perlin8(uint16_t x);
523-
uint8_t perlin8(uint16_t x, uint16_t y);
524-
uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z);
525522
uint16_t perlin16(uint32_t x);
526523
uint16_t perlin16(uint32_t x, uint32_t y);
527524
uint16_t perlin16(uint32_t x, uint32_t y, uint32_t z);
525+
uint8_t perlin8(uint16_t x);
526+
uint8_t perlin8(uint16_t x, uint16_t y);
527+
uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z);
528528

529529
// fast (true) random numbers using hardware RNG, all functions return values in the range lowerlimit to upperlimit-1
530530
// note: for true random numbers with high entropy, do not call faster than every 200ns (5MHz)

wled00/util.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ static inline __attribute__((always_inline)) int32_t hashToGradient(uint32_t h)
631631
//return (h & 0xFF) - 128; // use PERLIN_SHIFT 7
632632
//return (h & 0x0F) - 8; // use PERLIN_SHIFT 3
633633
//return (h & 0x07) - 4; // use PERLIN_SHIFT 2
634-
return (h & 0x03) - 2; // use PERLIN_SHIFT 1
634+
return (h & 0x03) - 2; // use PERLIN_SHIFT 1 -> closest to original fastled version
635635
}
636636

637637
// Gradient functions for 1D, 2D and 3D Perlin noise note: forcing inline produces smaller code and makes it 3x faster!
@@ -658,14 +658,25 @@ static inline __attribute__((always_inline)) int32_t gradient3D(uint32_t x0, int
658658
h ^= h >> 15;
659659
h *= 0x92C3412B;
660660
h ^= h >> 13;
661+
662+
/*
663+
// fastled version: 25% slower but gives original "look"
664+
h = h&15;
665+
int32_t u = h<8?dx:dy;
666+
int32_t v = h<4?dy:h==12||h==14?dx:dz;
667+
if(h&1) { u = -u; }
668+
if(h&2) { v = -v; }
669+
return (u >> 1) + (v >> 1) + (u & 0x1);
670+
*/
671+
// closer to actual perlin version
661672
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
662673
}
663674

664675
// fast cubic smoothstep: t*(3 - 2t²), optimized for fixed point, scaled to avoid overflows
665676
static uint32_t smoothstep(const uint32_t t) {
666677
uint32_t t_squared = (t * t) >> 16;
667678
uint32_t factor = (3 << 16) - ((t << 1));
668-
return (t_squared * factor) >> 18; // scale to avoid overflows
679+
return (t_squared * factor) >> 18; // scale to avoid overflows and give best resolution
669680
}
670681

671682
// 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) {
771782

772783
uint16_t perlin16(uint32_t x) {
773784
//return ((perlin1D_raw(x) * 1168) >> 10) + 0x7FFF; //scale to 16bit and offset (full range)
774-
return ((perlin1D_raw(x) * 895) >> 10) + 34616; //scale to 16bit and offset (fastled range)
785+
//return ((perlin1D_raw(x) * 895) >> 10) + 34616; //scale to 16bit and offset (fastled range) -> 8 steps
786+
return ((perlin1D_raw(x) * 1159) >> 10) + 32803; //scale to 16bit and offset (fastled range) -> 8 steps
775787
}
776788

777789
uint16_t perlin16(uint32_t x, uint32_t y) {
778-
return ((perlin2D_raw(x, y) * 1359) >> 10) + 31508; //scale to 16bit and offset (empirical values with some overflow safety margin)
790+
return ((perlin2D_raw(x, y) * 1537) >> 10) + 32725; //scale to 16bit and offset (empirical values with some overflow safety margin)
779791
}
780792

781793
uint16_t perlin16(uint32_t x, uint32_t y, uint32_t z) {
782-
return ((perlin3D_raw(x, y, z) * 1923) >> 10) + 31290; //scale to 16bit and offset (empirical values with some overflow safety margin)
794+
return ((perlin3D_raw(x, y, z) * 1731) >> 10) + 33147; //scale to 16bit and offset (empirical values with some overflow safety margin)
783795
}
784796

785797
uint8_t perlin8(uint16_t x) {
786-
return (((perlin1D_raw((uint32_t)x << 8, true) * 1168) >> 10) + 0x7FFF) >> 8;
798+
return (((perlin1D_raw((uint32_t)x << 8, true) * 1353) >> 10) + 32769) >> 8;
787799
}
788800

789801
uint8_t perlin8(uint16_t x, uint16_t y) {
790-
return (((perlin2D_raw((uint32_t)x << 8, (uint32_t)y << 8, true) * 1359) >> 10) + 31508) >> 8;
802+
return (((perlin2D_raw((uint32_t)x << 8, (uint32_t)y << 8, true) * 1620) >> 10) + 32771) >> 8;
791803
}
792804

793805
uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z) {
794-
return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 1923) >> 10) + 31290) >> 8; //scale to 8bit
806+
return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 2015) >> 10) + 33168) >> 8; //scale to 8bit
795807
}

wled00/wled.cpp

Lines changed: 0 additions & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -339,231 +339,6 @@ void WLED::setup()
339339
#else
340340
DEBUG_PRINTLN(F("arduino-esp32 v1.0.x\n")); // we can't say in more detail.
341341
#endif
342-
343-
344-
uint32_t start;
345-
uint32_t end;
346-
uint32_t time;
347-
uint8_t offset = hw_random()+hw_random();
348-
delay(2000);
349-
/*
350-
//online serial plotter: https://sekigon-gonnoc.github.io/web-serial-plotter/ format is "valueA:213423, ValueB:123123, \n"
351-
for(int i = 0; i < 0xFFFFFFF; i+=10) {
352-
//Serial.print(inoise16(i, offset, (offset >> 3))); Serial.print(" "); //x
353-
//Serial.print(inoise16(offset, i, (offset >> 3))); Serial.print(" "); //y
354-
//Serial.print(inoise16(offset, (offset >> 3), i)); Serial.print(" "); //z
355-
//Serial.print(perlin16(i, offset, (offset >> 3))); Serial.print(" "); //x
356-
//Serial.print(perlin16(offset, i, (offset >> 3))); Serial.print(" "); //y
357-
//Serial.print(perlin16(offset, (offset >> 3), i)); Serial.print(" "); //z
358-
359-
//Serial.print("Fastled:");Serial.print(inoise16(i, offset+i/2, i + (offset >> 3))); Serial.print(", "); //mixed mode
360-
//Serial.print("New:");Serial.println(perlin16(i, offset+i/2, i + (offset >> 3)));// Serial.println(", ");
361-
362-
//Serial.print("Fastled:");Serial.print(inoise16(i, offset+i/2)); Serial.print(", "); //mixed mode
363-
//Serial.print("New:");Serial.println(perlin16(i, offset+i/2));// Serial.println(", ");
364-
365-
//Serial.print("Fastled:");Serial.print(inoise16(i)); Serial.print(", "); //mixed mode
366-
//Serial.print("New:");Serial.println(perlin16(i));// Serial.println(", ");
367-
368-
Serial.print("Fastled3D:");Serial.print(inoise8(i, offset+i/2, i + (offset >> 3))); Serial.print(", "); //mixed mode
369-
Serial.print("New3D:");Serial.print(perlin8(i, offset+i/2, i + (offset >> 3)));// Serial.println(", ");
370-
Serial.print(", ");
371-
Serial.print("Fastled2D:");Serial.print(inoise8(i, offset+i/2)); Serial.print(", "); //mixed mode
372-
Serial.print("New2D:");Serial.print(perlin8(i, offset+i/2));// Serial.println(", ");
373-
Serial.print(", ");
374-
Serial.print("Fastled1D:");Serial.print(inoise8(i)); Serial.print(", "); //mixed mode
375-
Serial.print("New1D:");Serial.println(perlin8(i));// Serial.println(", ");
376-
377-
//Serial.print(inoise16(i, offset+i/2, i + (offset >> 3))); Serial.print(","); //mixed mode
378-
//Serial.println(perlin16(i, offset+i/2, i + (offset >> 3)));// Serial.println(", ");
379-
//delay(10);
380-
// Serial.println(perlin3D_raw(i, offset+i/4, i*2 + (offset >> 3))); //raw
381-
}*/
382-
383-
/*
384-
for(int i = 0; i < 0x2FFFF; i+=100) {
385-
uint32_t pos = i + offset;
386-
Serial.print(inoise8_raw((pos)>>3, (pos)>>3)); Serial.print(",");
387-
Serial.print(inoise8((pos)>>3, (pos)>>3, (pos)>>3)); Serial.print(",");
388-
Serial.print(inoise16(pos*20, pos*30)); Serial.print(",");
389-
//Serial.print(inoise16_raw(pos*20, pos*30, pos*40)); Serial.print(",");
390-
Serial.print(inoise16(pos*20, pos*20, pos*20)); Serial.print(",");
391-
//Serial.print(((perlin1D_raw(pos*20)* 85)>>7) + 0x7FFF); Serial.print(",");
392-
Serial.print(perlin1D_raw(pos*20)); Serial.print(",");
393-
Serial.print(perlin2D_raw(pos*20, pos*20)); Serial.print(",");
394-
//Serial.print(perlin2D_raw(pos*20, pos*30) + 0x7FFF); Serial.print(",");
395-
Serial.println(perlin3D_raw(pos*20, pos*20, pos*20));
396-
//Serial.println(((perlin3D_raw(pos*20, pos*30, pos*40) * 85)>>7) + 0x7FFF);
397-
}*/
398-
399-
/*
400-
for(int i = 0; i < 0xF0000; i+=55) {
401-
Serial.print(inoise8_raw(i,i+5648) / 2); Serial.print(","); // +/-32 ?
402-
Serial.print(((int16_t)perlin8(i,i+5648) - 0x7F) >> 2); Serial.print(",");
403-
Serial.print(inoise8(i,i/3,i/5)); Serial.print(",");
404-
Serial.print(perlin8(i,i/3,i/5)); Serial.print(",");
405-
Serial.print(inoise8(i,i/3)); Serial.print(",");
406-
Serial.print(perlin8(i,i/3)); Serial.print(",");
407-
Serial.print(inoise8(i)); Serial.print(",");
408-
Serial.println(perlin8(i));
409-
}
410-
*/
411-
int32_t minval=0xFFFFF;
412-
int32_t maxval=0;
413-
start = micros();
414-
for(int i = 0; i < 0xFFFFF; i+=50) {
415-
uint16_t pos = i + offset;
416-
int32_t noiseval = inoise8_raw(pos);
417-
if(noiseval < minval) minval = noiseval;
418-
if(noiseval > maxval) maxval = noiseval;
419-
}
420-
end = micros();
421-
time = end - start;
422-
Serial.print("time: "); Serial.print(time);
423-
Serial.print(" inoise8_raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
424-
425-
minval=0xFFFFF;
426-
maxval=0;
427-
428-
start = micros();
429-
for(int i = 0; i < 0xFFFFFF; i+=50) {
430-
uint32_t pos = i + offset;
431-
//int32_t noiseval = inoise16(pos, pos+4684165, pos+985685);
432-
int32_t noiseval = inoise16(hw_random(), hw_random(), hw_random());
433-
if(noiseval < minval) minval = noiseval;
434-
if(noiseval > maxval) maxval = noiseval;
435-
}
436-
end = micros();
437-
time = end - start;
438-
Serial.print("time: "); Serial.print(time);
439-
Serial.print(" inoise16_3D min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
440-
441-
minval=0xFFFFF;
442-
maxval=0;
443-
start = micros();
444-
for(int i = 0; i < 0xFFFFFF; i+=50) {
445-
uint32_t pos = i + offset;
446-
//int32_t noiseval = perlin16(hw_random());
447-
int32_t noiseval = perlin1D_raw(hw_random(),false);
448-
if(noiseval < minval) minval = noiseval;
449-
if(noiseval > maxval) maxval = noiseval;
450-
}
451-
end = micros();
452-
time = end - start;
453-
Serial.print("time: "); Serial.print(time);
454-
Serial.print(" perlin1D raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
455-
minval=0xFFFFF;
456-
maxval=0;
457-
start = micros();
458-
for(int i = 0; i < 0xFFFFFF; i+=50) {
459-
uint32_t pos = i + offset;
460-
//int32_t noiseval = perlin16( hw_random(), hw_random());
461-
int32_t noiseval = perlin2D_raw( hw_random(), hw_random());
462-
if(noiseval < minval) minval = noiseval;
463-
if(noiseval > maxval) maxval = noiseval;
464-
}
465-
end = micros();
466-
time = end - start;
467-
Serial.print("time: "); Serial.print(time);
468-
Serial.print(" perlin2D raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
469-
470-
471-
minval=0xFFFFF;
472-
maxval=0;
473-
for(int i = 0; i < 0xFFFFFF; i+=50) {
474-
uint32_t pos = i + offset;
475-
//int32_t noiseval = perlin3D_raw(pos, pos+46845, pos+654684);
476-
//int32_t noiseval = perlin3D_raw(hw_random(), hw_random(), hw_random());
477-
int32_t noiseval = perlin16(hw_random(), hw_random(), hw_random());
478-
if(noiseval < minval) minval = noiseval;
479-
if(noiseval > maxval) maxval = noiseval;
480-
}
481-
end = micros();
482-
time = end - start;
483-
Serial.print("time: "); Serial.print(time);
484-
Serial.print(" perlin16 min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
485-
486-
minval=0xFFFFF;
487-
maxval=0;
488-
for(int i = 0; i < 0xFFFFFF; i+=50) {
489-
uint32_t pos = i + offset;
490-
//int32_t noiseval = perlin3D_raw(pos, pos+46845, pos+654684);
491-
int32_t noiseval = perlin3D_raw(hw_random(), hw_random(), hw_random(),false);
492-
//int32_t noiseval = perlin16(hw_random(), hw_random(), hw_random());
493-
if(noiseval < minval) minval = noiseval;
494-
if(noiseval > maxval) maxval = noiseval;
495-
}
496-
end = micros();
497-
time = end - start;
498-
Serial.print("time: "); Serial.print(time);
499-
Serial.print(" perlin3D_raw min: "); Serial.print(minval); Serial.print(" max: "); Serial.println(maxval);
500-
501-
502-
503-
volatile uint32_t temp;
504-
start = micros();
505-
for(int i = 0; i < 100000; i++){
506-
temp += inoise8(i);
507-
}
508-
end = micros();
509-
time = end - start;
510-
Serial.print("inoise8: ");
511-
Serial.print(temp);
512-
Serial.print("time: ");
513-
Serial.println(time);
514-
start = micros();
515-
for(int i = 0; i < 100000; i++){
516-
temp += inoise16(i,i<<1,i<<2);
517-
}
518-
end = micros();
519-
time = end - start;
520-
Serial.print("inoise16:");
521-
Serial.print(temp);
522-
Serial.print("time: ");
523-
Serial.println(time);
524-
start = micros();
525-
for(int i = 0; i < 100000; i++){
526-
temp += perlin1D_raw(i);
527-
}
528-
end = micros();
529-
time = end - start;
530-
Serial.print("perlin1Draw:");
531-
Serial.print(temp);
532-
Serial.print("time: ");
533-
Serial.println(time);
534-
start = micros();
535-
for(int i = 0; i < 100000; i++){
536-
temp += perlin2D_raw(i,i*33);
537-
}
538-
end = micros();
539-
time = end - start;
540-
Serial.print("perlin2Draw:");
541-
Serial.print(temp);
542-
Serial.print("time: ");
543-
Serial.println(time);
544-
start = micros();
545-
for(int i = 0; i < 100000; i++){
546-
temp += perlin16(i,i*33,i*17);
547-
}
548-
end = micros();
549-
time = end - start;
550-
Serial.print("perlin163D:");
551-
Serial.print(temp);
552-
Serial.print("time: ");
553-
Serial.println(time);
554-
555-
start = micros();
556-
for(int i = 0; i < 100000; i++){
557-
temp += perlin3D_raw(i,i*33,i*17);
558-
}
559-
end = micros();
560-
time = end - start;
561-
Serial.print("perlin3D raw:");
562-
Serial.print(temp);
563-
Serial.print("time: ");
564-
Serial.println(time);
565-
566-
567342
DEBUG_PRINTF_P(PSTR("CPU: %s rev.%d, %d core(s), %d MHz.\n"), ESP.getChipModel(), (int)ESP.getChipRevision(), ESP.getChipCores(), ESP.getCpuFreqMHz());
568343
DEBUG_PRINTF_P(PSTR("FLASH: %d MB, Mode %d "), (ESP.getFlashChipSize()/1024)/1024, (int)ESP.getFlashChipMode());
569344
#ifdef WLED_DEBUG

0 commit comments

Comments
 (0)