Anti-aliasing example This example shows two bars of light moving at the same speed

Anti-aliasing example
This example shows two bars of light moving at the same speed down the strip: one using plain integer steps and one using anti-aliased fractional steps.
Code for this example is here: http://pastebin.com/yAgKs0Ay
Notice how even though the two bars are moving at the same speed, one (the ‘fractional’ antialiased one) moves much more smoothly.

… dreaded ‘video processing’ message. No video.
There it is!

Can you see the difference it makes? And after you’ve looked at the code for a bit, does it make sense?
There’s an ASCII art drawing in there that I should really re-do as something with circles and arrows and a paragraph on the back explaining what it is.

So I’m noticing you are only affecting the first and last pixel of each bar, by going from 0% to 100% (or reverse) in 10% step increments. What about making that longer? As in, say the first and last 5 pixels? Yes I realize that makes the ‘bar’ longer, but I think it looks more natural that way. As one pixel gets brighter, the one next to it starts glowing brighter as well …

Like the way BlinkenLight does it:

This example shows the bare-bones idea of how to do this kind of anti-aliasing. The particular implementation that I did here is just spatial anti-aliasing. There are other (very pleasing!) effects which build on this idea, including the one you mentioned, and I definitely encourage you to play around with it.
The code isn’t doing 10% increments even though my hand-written decimalized example is. The code is doing 6.25% increments (1/16ths). In previous implementations I’ve used a full eight bits for the fractional part of the pixel position, but that forces me to choose between projects with < 256 pixels or using data types larger than 16 bits for my ‘position’ variables. The Q12.4 split here (12 bits of integer, 4 bits of fraction) lets me address up to 4096 pixels. I’ve played around with Q10.6: up to 1024 pixels, with 6 bits (64 levels) of anti-aliased dimming, but it turns out that ATmegas have special instructions for cleaving a byte into two four-bit ‘nybbles’, so the code size and execution speed are much better if everything is 4-bit aligned, as in Q12.4.
If I weren’t such a bit-twiddler I suppose I could use 24-bit (or 32-bit) data types for position values, and get 8-bits of anti-aliasing. On ARM I’d probably go with Q24.8; ARM not only deals with the 32-bit words in a single cycle, but it can also shift an arbitrary number of bits in a single cycle as well.

Anyway, there are lots of fancier effects, as always. This is to get people started with the idea and thinking about what they could do with it – so I think it’s working!

If you really want it to look slick, you code it so you have a faster ramp-up on the brightness at the ‘head’ end of the bar, and a slower ramp-down of the brightness at the ‘tail’ end of the bar, depending on which way it’s moving and how fast. The next effect is not only anti-aliasing but also motion blurring, which makes it look even that much better.

As for the Blinkenlight code, they way they’re doing it doesn’t really scale up. When I’ve done that on larger projects, I’ve done one of two things: EITHER break the ‘draw’ code into three parts: the ramp up, the constant-brightness section in the middle, and the ramp down, so that the constant brightness loop in the middle can be as tight as possible, OR use a fast fixed point function (e.g., cosine, or quadratic in/out easing, both provided in the library) to modulate the brightness along the whole bar. The modulated-brightness options look much more ‘organic’ than the up-hold-down ones at larger scale, and only cost a handful of instructions. In fact, I just compared it, and using the FastLED fixed point cosine function to modulate the brightness along the light bar is actually faster than the code in the Blinkenlight example. (The problem there is that they’re assuming that “abs(…)” is cheap, and that the compiler will make a jump table out of the switch; neither are as right as they probably expect.

Happy to be able to provide some working code that demonstrates how to do a particular kind of effect.

Thanks for the share, I can’t wait to experiment with higher pixel density strips. I’m stuck with UCS1903’s till next year :frowning:

FWIW, I ran this code on both 60 and 30 px/m strips, and I liked the look better on the less dense strips, much to my surprise. I posted the video with the 60 px/m strip here because otherwise you’d need a wider monitor to see them all.

@Mark_Kriegsman thank you for the sample code. My programming skills go back to BASIC from the Timex/Sinclair ZX81 more than 30 years ago and a college semester of C more than 15 years ago. Seeing the code in action helps me understand and improve.

I’m just now getting into programming LEDs and I’m diving head first in and trying to learn as much as I can. The amount of information on this G+ site is great, and I intend to read just about every single post! :wink:

One of the things I’m hungry for right now is more information about the algorithms used for color and brightness programming. Sample code like what you posted is very helpful!

The comments are really well written and helpful, and I even understood the ASCII art. :wink: Thanks for posting it!! I’m definitely going to try this out on my 24x24 matrix when I get home tonight.

In looking at the code though, one thing isn’t clear to me. In setting the brightness for first and last pixels in the light bar, you do this:

leds[i] += CHSV( hue, 255, bright);

I’m still learning C/C++ (although I have quite a bit of experience in C#), so this may be a dumb question, but what does the += do in this particular usage? At first glance, it would appear to just add to the existing HSV values for the specified LED, but in looking at the intent, along with what the video shows, it appears to be replacing the existing values. Is there a reason you wouldn’t just use = instead? Like this:

leds[i] = CHSV( hue, 255, bright);

This particular trick changed my text scroller from awfully stuttering to nearly completely smooth. Thanks a bunch! :slight_smile:

Glad it helped!
If you can post it, I’d love to see how it looks now (and ideally, the “before” look too, but this kind of upgrade is often difficult to"turn off"). In any case, please do share a video if you can!

Sorry I never came back on this. I was using a Spark Core to feed an Arduino full screen buffers over serial, not noticing that though most Spark Core IO pins are 5V compatible, the serial RX is not - doh! Until I can get a replacement, I’m unfortunately out of luck. FastLED on Spark Core would eliminate a lot of hassle though :wink:

Mark - This looks amazing when I tested it on my strip. I am a complete noob when it comes to programming but I am trying to learn. How would I go about removing the "none-antialiased " bar from this example? Would you be able to post a copy with just the one bar? Also I would love to know how to make this cycle between the RBG colors randomly. Look forward to hearing from you - If not, keep up the good work! Gives me something to strive for =].

Took only a few minutes to delete the “Integer” code, leaving only the anti-aliased bar. I threw in a color wash, too. Enjoy and have fun playing around with the code! Try changing some of the numbers and see what effect it has…

v1.1: http://pastebin.com/g8Bxi6zW

Wow that is exactly what I was looking to do! Thank you so much for the quick and amazing reply! =] I can’t wait to tinker with this more.

very interesting!

That is exactly what i need for my current project:

https://plus.google.com/b/116363807875890742340/116363807875890742340/posts/F8PQeak7Kn9

Sorry to say this, the current documentation for this library it not of good help for me, as i was expecting some sort of function reference, where every function is described…may this exist somewhere but, at least, i wasn´t able to find it, jet…

Hi! Did you check out the docs here https://github.com/FastLED/FastLED/wiki/Overview or all the comments in the source code?