Skip to content

Instantly share code, notes, and snippets.

@StefanPetrick
Last active December 18, 2023 18:22
Show Gist options
  • Save StefanPetrick/c856b6d681ec3122e5551403aabfcc68 to your computer and use it in GitHub Desktop.
Save StefanPetrick/c856b6d681ec3122e5551403aabfcc68 to your computer and use it in GitHub Desktop.
The complete code for the noise controlled noise.
/*
A FastLED matrix example:
A simplex noise field fully modulated and controlled by itself
written by
Stefan Petrick 2017
Do with it whatever you like and show your results to the FastLED community
https://plus.google.com/communities/109127054924227823508
*/
#include "FastLED.h"
// matrix size
uint8_t Width = 16;
uint8_t Height = 16;
uint8_t CentreX = (Width / 2) - 1;
uint8_t CentreY = (Height / 2) - 1;
// NUM_LEDS = Width * Height
#define NUM_LEDS 256
#define BRIGHTNESS 128
CRGB leds[NUM_LEDS];
DEFINE_GRADIENT_PALETTE( pit ) {
0, 3, 3, 3,
64, 13, 13, 255, //blue
128, 3, 3, 3,
192, 255, 130, 3 , //orange
255, 3, 3, 3
};
void setup() {
Serial.begin(115200);
// Adjust this for you own setup. Use the hardware SPI pins if possible.
// On Teensy 3.1/3.2 the pins are 11 & 13
// Details here: https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging
// In case you see flickering / glitching leds, reduce the data rate to 12 MHZ or less
LEDS.addLeds<APA102, 11, 13, BGR, DATA_RATE_MHZ(24)>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
FastLED.setBrightness(BRIGHTNESS);
}
// parameters and buffer for the noise array
#define NUM_LAYERS 1
uint32_t x[NUM_LAYERS];
uint32_t y[NUM_LAYERS];
uint32_t z[NUM_LAYERS];
uint32_t scale_x[NUM_LAYERS];
uint32_t scale_y[NUM_LAYERS];
uint8_t noise[1][16][16];
void loop() {
noise_noise1();
// check the Serial Monitor to see how many fps you get
EVERY_N_MILLIS(1000) {
Serial.println(LEDS.getFPS());
}
}
// this finds the right index within a serpentine matrix
uint16_t XY( uint8_t x, uint8_t y) {
uint16_t i;
if ( y & 0x01) {
uint8_t reverseX = (Width - 1) - x;
i = (y * Width) + reverseX;
} else {
i = (y * Width) + x;
}
return i;
}
/*
// for a line by line matrix it should be
uint16_t XY( uint8_t x, uint8_t y)
{
uint16_t i;
i = (y * Width) + x;
return i;
}
*/
// cheap correction with gamma 2.0
void adjust_gamma()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i].r = dim8_video(leds[i].r);
leds[i].g = dim8_video(leds[i].g);
leds[i].b = dim8_video(leds[i].b);
}
}
//as shown on youtube
//a noise controlled & modulated by itself
void noise_noise1() {
CRGBPalette16 Pal( pit );
//modulate the position so that it increases/decreases x
//(here based on the top left pixel - it could be any position else)
//the factor "2" defines the max speed of the x movement
//the "-255" defines the median moving direction
x[0] = x[0] + (2 * noise[0][0][0]) - 255;
//modulate the position so that it increases/decreases y
//(here based on the top right pixel - it could be any position else)
y[0] = y[0] + (2 * noise[0][Width-1][0]) - 255;
//z just in one direction but with the additional "1" to make sure to never get stuck
//in case the movement is stopped by a crazy parameter (noise data) combination
//(here based on the down left pixel - it could be any position else)
z[0] += 1 + ((noise[0][0][Height-1]) / 4);
//set the scaling based on left and right pixel of the middle line
//here you can set the range of the zoom in both dimensions
scale_x[0] = 8000 + (noise[0][0][CentreY] * 16);
scale_y[0] = 8000 + (noise[0][Width-1][CentreY] * 16);
//calculate the noise data
uint8_t layer = 0;
for (uint8_t i = 0; i < Width; i++) {
uint32_t ioffset = scale_x[layer] * (i - CentreX);
for (uint8_t j = 0; j < Height; j++) {
uint32_t joffset = scale_y[layer] * (j - CentreY);
uint16_t data = inoise16(x[layer] + ioffset, y[layer] + joffset, z[layer]);
// limit the 16 bit results to the interesting range
if (data < 11000) data = 11000;
if (data > 51000) data = 51000;
// normalize
data = data - 11000;
// scale down that the result fits into a byte
data = data / 161;
// store the result in the array
noise[layer][i][j] = data;
}
}
//map the colors
for (uint8_t y = 0; y < Height; y++) {
for (uint8_t x = 0; x < Width; x++) {
//I will add this overlay CRGB later for more colors
//it´s basically a rainbow mapping with an inverted brightness mask
CRGB overlay = CHSV(noise[0][y][x], 255, noise[0][x][y]);
//here the actual colormapping happens - note the additional colorshift caused by the down right pixel noise[0][15][15]
leds[XY(x, y)] = ColorFromPalette( Pal, noise[0][Width-1][Height-1] + noise[0][x][y]) + overlay;
}
}
//make it looking nice
adjust_gamma();
//and show it!
FastLED.show();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment