adafruit / RGB-matrix-Panel

Arduino library and example code for the 16x32 RGB matrix panels in the shop
http://www.adafruit.com/products/420
303 stars 145 forks source link

Timing experiment #30

Closed seebs closed 7 years ago

seebs commented 7 years ago

Instead of aiming for 320/640/1280/2560 cycle display timing, aim for perceptual timing. Lowest-order bit gets a couple of instructions, second-lowest-order gets about 180 cycles, and the other two get 800/3200 cycle displays. This looks much smoother.

You probably shouldn't accept this without checking it out and possibly tuning it, and I have no way to test it on 32x32 or 64x32 boards. (I'm not even sure whether the timing logic is at all right for 64x32 boards; it looks like they'd need more time per line than the existing code gives them?)

This code may or may not break the plasma example on an Uno, as I have had issues with a slightly older arduino IDE breaking that anyway because of memory contention. (It would probably be better to use a user-provided buffer instead of malloc space for the buffer, that would save several bytes.)

The main point is to illustrate that you can pretty much eliminate the need for the "gamma.h" header because you can get a pretty smooth 4-bit curve by tweaking timings instead of using gamma to make up for that, and that gets much nicer behavior for things like smooth gradients.

PaintYourDragon commented 7 years ago

While a gamma-corrected curve would be better, you won't get it out of this combination of constants. Consider the case of pixel brightnesses 0xE and 0xF; there will be minimal difference in the duty cycles, yet (if properly gamma corrected) this is where the largest difference in adjacent brightness pairs should occur. The powers-of-two approach isn't perceptually optimal but it's at least linear and deterministic; 0xE has about 14/15 the duty cycle of 0xF. The alternate constants are neither linear nor a true gamma curve...if you graph it out it'll be a weird haphazard thing.

seebs commented 7 years ago

Huh, you have a really good point, and that explains why I was getting relatively homogenous brightness on the top end, which I hadn't quite gotten my head around.

I do note, even if the high end are relatively homogenous, having any color resolution at all on the low end is immensely useful and improves things a lot. With the actual-binary distribution, you still see relatively little brightness variance on the high end, but there is no low end.