Close

Shaders

A project log for reactive led gems : make the music pop

show control from an led instrument. bring the audience into the performance experience. play highly reactive and mode setting patterns

mpinnermpinner 06/26/2015 at 22:230 Comments

Q : how do you control 1000s of leds with minimal delay?


A : no delay.

from the beginning i knew this was going to be the central issues. to ease development i choose to parse all the osc messages on the microcontroller.

this is a fairly novel approach. osc doesn't specifically rely on having a network, but everyone uses it over udp. my teensy looks like an osc device sorta. i have to parse all the osc traffic on my teeny. this has to be the highest priority task and cannot be delayed. these usb / serial buffers will overrun quickly and i need the hits to be perfectly sync'd (<5ms) .

doing all this osc parsing in c is kind of maddening, but afforded me only having to manage the message formats in one place. (DRY: don't repeat yourself)


ok, SHADERS


their use wasn't strictly required. i have GPU. I probably wasn't even implemented correctly. I use the term "Shader" in this case to explain the design pattern and division of responsibility. i knew i'd need to add patterns fairly quickly and have lots of data driven configurability.

basically you can get a ton of different behavior by implementing this virtual method:

  virtual uint32_t shade (float height, uint32_t color, uint32_t currentColor, float remaining, uint32_t secondaryColor);

that is all. here is one of the more complex ones.

inline uint32_t shade (float height, uint32_t color, uint32_t currentColor, float remaining, uint32_t secondaryColor) {

    if(remaining > 0.85) {
      if(2 > random(100)) {
        return color;
      }
    } 

    if(remaining > 0.7) {
      if(2 > random(100)) {
        return secondaryColor;
      }
    } 

     if(5 > random(100)) {
      return colorByBrightness(0.9, currentColor);
    }

    return currentColor;
  }  
};

right. not all that complex. check em all out here : https://github.com/mpinner/PurityRingGems/tree/master/Arduino/Gems_HitSync

the trick is in how you think about the context and task.

each led is essentially complete responsible for only itself and i know how to write simple code to control one led.

i provide myself a rich context for each led to live within. things like timing, colors, and position are all normalized from 0.0 - 1.0. this makes writing code extremely predictable, easy, and inefficient.


I am doing so much floating point math. it is almost irresponsible and completely insane for what could be ALL integers


ALMOST INSANE:

the only things that makes it ok:

- having plenty of spare cycles on my Teensy's Freescale

- being able to accept a new OSC Message ANYTIME , even between calculations for neighboring pixels

- Measuring my effective frame rate to ensure it always looked GOOOOOOD . initially i was pushing 200fps. once i started adding more and more and more features and cross gem patterns, my frame rate dipped to just over 60fps.. sweet!

one might argue it looks even better this way because you are constantly calculating the most accurate colors. im not sure that's quite true, but you'll have to see it live.

a fun side effect was being able to bring in and compare previous pixel values to have feedback like effects. i didn't play with this nearly as much as i should have, but it is very apparent when you start using the touchosc interface to simulate hits very very fast.

well, i hope this helps

please review the code and comment as needed. learn what you can. no elitism please. i did this all under no sleep and serious duress.

Discussions