20 decent Christmas tree patterns

Here are some patterns and a 3D map generator I made last year that look pretty good on a tree.

A few are new; many are existing patterns adapted for this map. All are slowed down. We wanted more subtle fades that don’t distract you when doing other things in the same room.

Code

In order to not clutter the pattern library, here’s a:

Map

ChristmasTree 2022-11-18 10-29-23

The map is mostly a stack of rings. This worked well even though it was more like a spiral cone in practice. I could specify the number of LEDs in each revolution and the starting rotation of each ring, which was easier than trying to string it with an accurate spiral. I include a mapping helper pattern above to make it easier to set the LEDs-per-revolution and angular alignment arrays.

Map generator code
function (pixelCount) {
  var map = []
  
  // Flat ring generator
  function ring(pixels, r, h, start) {
    for (j = 0; j < pixels; j++) {
      c = j / pixels * Math.PI * 2;
      point = [r * Math.cos(c - start), r * Math.sin(c - start), h]
      map.push(point)
    }
  }
  
  // Wizard's spiral cone generator
  function cone(cpixels) {
    loops = 3
    r = 4
    phase = 0
    pixelSpacing = 1.3
    resolution = .00005 //controls the resolution of the integral
    a = Math.PI * 2 * loops
    
    function conicalHelix(t, r, a) {
      z = layerPixels.length +130*t/cpixels
      x = (1-t) * r * Math.cos(t * a - phase * Math.PI * 2)
      y = (1-t) * r * Math.sin(t * a - phase * Math.PI * 2)
      return [x,y,z]
    }
    
    function conicalHelixArcLength(t1, t2, r, a) {
      h1 = conicalHelix(t1, r, a)
      h2 = conicalHelix(t2, r, a)
      dh = [h1[0] - h2[0], h1[1] - h2[1], h1[2] - h2[2]]
      return Math.sqrt(dh[0]*dh[0] + dh[1]*dh[1] + dh[2]*dh[2])
    }
    
    for (t = 0, i = 0; i < cpixels; i++) {
      //integrate arc lengths until we cover the distance to our next pixel
      l = 0;
      while (l < pixelSpacing) {
        l += conicalHelixArcLength(t, t+resolution, r, a)
        t += resolution
      }
      map.push(conicalHelix(t, r, a))
    }
  
  }
  
  // Number of pixels in each ring layer, bottom to top
  var layerPixels = [134, 122, 114, 
                      96, 84, 79, 68, 
                      73, 49, 40, 41, 37,
                      33];

  // Angular starting offset for each layer
  // Unit is revolutions (multiply by 2 PI to get radians)
  var layerAngles = [  -0.02,  0.02,  0.13,
                       -.08, -.07, 0.03, 
                       0.05, -.08, -.05, 0.04, .1, -.66, 
                       0.6];

  // For each layer
  for (i = 0; i < layerPixels.length; i++) {
    ring(layerPixels[i],              // pixels
         layerPixels.length - i + 3,  // radius - gets smaller each layer, but min radius of 3
         i,                           // height
         layerAngles[i] * Math.PI * 2); // angular offset
  }

  cone(30) // top is a simple spiral
  
  return map
}

Even though it’s an approximation, I found it was less work than correcting the 2% wildly-errant LED positions that the nascent auto-mapping tools produce.

LEDs

Two years ago I strung my tree with 1000 WS2811 (12V) bullets (now $280, with green wire). I’ve used strands of 20mm SK9822 modules in other projects, but they don’t have the classic bulb look like the bullets do.

If doing this now I would try out these 12V* 5V GS8206 bullets - the 8206 is supposedly the IC version of the GS8208. The the GS8208 is the 5050 LED+chip with a great 12-bit gamma curve that some of us have really come to like.

I think some people are happy with the fairy-light style LEDs as well.

*Edit: Thanks, @hex337 - you’re right, the GS8206 bullets seem to all be 5V :-1:

6 Likes

Just beautiful, @jeff!

Pixelblazes really do make terrific Christmas trees. Here’s mine, w/800 fairy lights.

And no map. My wife, who does statistics/ML for a living, and knows exactly how all this works, looked at my initial spiral cone arrangement, shook her head, and rearranged the lights “stochastically” so that they’re all but impossible to map algorithmically. One of these years, I’ll fix it with a CV-based mapper, but I have to admit, the irregularity looks nice - a lot like a noise texture.

3 Likes

Oh man… this looks so great! I am tempted to do this… I wonder if there is an optimal height for 1k leds. The 8206’s that I can find are only 5v, which will be a pain for power injection :frowning:

1 Like

I just wanted to add a heads-up for a potential issue for anyone buying GS8206 based LEDs.
I have been unable to find these ICs without built-in patterns, whereas the GS8208 are now commonly available without the built in patterns.
The built-in patterns can trigger in a fraction of a second, and may cause visual glitches when switching patterns or loading the app (both can potentially pause LED output for hundreds of ms).
If anyone tries these and can report on compatibility, please let us know!


Very nice collection of patterns, @jeff ! Thank you for putting that together with an awesome demo video!

1 Like

@jeff I have to thank you again, your mapping method was super easy to adapt, and didn’t take a lot of time to tune with a helper!

Most of the patterns can be found in Jeff’s collection or the shared patterns library, here are a few that I tweaked slightly for the tree:

Perlin fire 3D.epe (8.9 KB)
spiral twirls 2D tree.epe (8.0 KB)
slow color twinkles.epe (7.5 KB)
rainbow fire.epe (9.0 KB)

2 Likes