WLED pattern porting?

I took a shot at porting Distortion Waves last night. First I did a more-or-less straight transliteration of the FastLED code (though I got rid of the gamma LUT and replaced the cosine LUT with a PB wave function) and that was OK, though there were lots of artefacts in the middle which I think were due to numeric overflows.

Then I started hacking away to make it more PB-like. I’ve now got it very simple and PB-friendly, but in the process of scaling from FastLED’s 0…255 intensities and Soulmate’s 1-20 coordinates to PB’s 0…1 world I lost track of what the scaling coefficients should be at each stage, so it’s now 95% correct but 100% wrong (i.e. the code looks good but the results don’t resemble the original).

I’m tired of looking at it, and feeling distinctly inadequate after seeing @zranger1’s Great Metaballs of Fire, so I’ll post it here as a starting point if someone with fresh eyes wants to carry it forward…

//  Cobbled together from the original at: https://editor.soulmatelights.com/gallery/1089-distorsion-waves

//  simple replacement for LUT
function cos_wave(proportion) { return 1-wave(proportion+0.25); }
function beatsin(bpm) { return wave(time(0.91552734375/bpm)); }

// adjustments
timeBase = 0.1;
speed = 5;
w = 2;

export function beforeRender(delta) {
  a1=time(timeBase); a2=time(2*timeBase); a3=time(3*timeBase);
  cx1 = beatsin(10-speed); cy1 = beatsin(12-speed); 
  cx2 = beatsin(13-speed); cy2 = beatsin(15-speed);
  cx3 = beatsin(17-speed); cy3 = beatsin(14-speed);
}

export function render2D(index, x, y) {
/*
  byte rdistort = cos_wave[   (cos_wave[((x << 3) + a1) & 255]    + cos_wave[   ((y << 3) - a2) & 255]    + a3     ) & 255   ] >> 1;
  byte gdistort = cos_wave[   (cos_wave[((x << 3) - a2) & 255]    + cos_wave[   ((y << 3) + a3) & 255]    + a1 + 32) & 255   ] >> 1;
  byte bdistort = cos_wave[   (cos_wave[((x << 3) + a3) & 255]    + cos_wave[   ((y << 3) - a1) & 255]    + a2 + 64) & 255   ] >> 1;
*/
  coeff1 = 0.06; 
  r1 = coeff1*cos_wave(x+a1); 
  g1 = coeff1*cos_wave(x-a2); 
  b1 = coeff1*cos_wave(x+a3);
  
  coeff2 = 1; 
  r2 = coeff2*cos_wave(y-a2); 
  g2 = coeff2*cos_wave(y+a1); 
  b2 = coeff2*cos_wave(y-a2);
  
  coeff3 = 1; 
  rdistort = coeff3*cos_wave(r1+r2+a3); 
  gdistort = coeff3*cos_wave(g1+g2+a1+1/8);  
  bdistort = coeff3*cos_wave(b1+b2+a2+1/4); 

/*
  byte valueR = rdistort + w * (a1 - (((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1)) >> 7));
  byte valueG = gdistort + w * (a2 - (((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2)) >> 7));
  byte valueB = bdistort + w * (a3 - (((xoffs - cx3) * (xoffs - cx3) + (yoffs - cy3) * (yoffs - cy3)) >> 7));
*/
  dx1 = x-cx1; dy1 = y-cy1; dx2 = x-cx2; dy2 = y-cy2; dx3 = x-cx3; dy3 = y-cy3;
  r = cos_wave(rdistort + w*(a1-(dx1*dx1 + dy1*dy1)));
  g = cos_wave(gdistort + w*(a2-(dx2*dx2 + dy2*dy2)));
  b = cos_wave(bdistort + w*(a3-(dx3*dx3 + dy3*dy3)));

  rgb(r*r, g*g, b*b); 
}
2 Likes