#include <FastLED.h>
#define FNL_IMPL
#include "FastNoise.h"

// Create noise state
fnl_state noise;

#define WIDTH 16
#define HEIGHT 16
#define NUM_LEDS ((WIDTH) * (HEIGHT))

CRGB leds[NUM_LEDS + 1];

uint16_t XY(uint8_t x, uint8_t y) {
  if (x >= WIDTH) return NUM_LEDS;
  if (y >= HEIGHT) return NUM_LEDS;
  if (y & 1)
    return (y + 1) * WIDTH - 1 - x;
  else
    return y * WIDTH + x;
}

void setup() {
  // Configure noise state
  noise = fnlCreateState();
  noise.noise_type = FNL_NOISE_OPENSIMPLEX2;

  Serial.begin(115200);
  FastLED.addLeds<NEOPIXEL, 3>(leds, NUM_LEDS);
  FastLED.setCorrection(UncorrectedColor);
  FastLED.setTemperature(UncorrectedTemperature);
  FastLED.setDither(DISABLE_DITHER);
}


void loop() {
  static int z = 0;
  z += 1;
  for (int y = 0; y < HEIGHT; y++) {
    for (int x = 0; x < WIDTH; x++) {
      float n = fnlGetNoise3D(&noise, x, y, z);
      uint8_t c = 127.5f + n * 127.5f;
      leds[XY(x, y)] = CRGB(c, c, c);
    }
  }

  FastLED.show();
  static uint8_t fps_frame = 0;
  if (!++fps_frame)
    Serial.println(FastLED.getFPS());
}