Grayscale dithering + lower FPS = higher resolution!


In a previous topic I talked about using a monochrome display to display colors; and that it’s best to have this color assignment done on the OS level.
Kind of creating a ‘library’ as were, so that on the programming level, one of 3 modes can be chosen:
- fully monochrome,
- 3 colors (B, W, Grey), or
- 4 colors (B, W, Light Grey, Dark Grey)
Can be programmed for each artifact (background/sprite/object) on the screen.
And have the OS take care of correctly dithering the screen.

These 3-4 colors on a monochrome display essentially half to 1/3rd the screen frequency.

On the other hand you can use the same principle to create a higher perceivable resolution.

EG: Imagine in a pixel row on a 4 color setting:
0 = dark ,
1= dark grey,
2= light grey,
3= white.

And for a 3 color setting, I’ll write:
0 = dark
X = grey
3 = white.

Using these colors, to increase perceivable resolution in the following way:

Monochrome setting:
Our current system, moving a monochrome pixel is:
Frame 1: 0300
Frame 2: 0030
The pixel has moved 1 column to the right in 1 frame.
This is great for sharp, fast moving objects, that require little precision.

One can half the framerate, and make the transition from one pixel to another more smooth as such:
F1: 0300
F2: 0330
F3: 0030
This improves the perceived resolution by 2x, however, it halfs the framerate, and stretches the pixel in the transition!
This is good for medium fast movement, of up to 30 pixels per second movement, I would think.


3 Color:
More precision can be gotten in a 3 color setting:
F1: 0300 (60FPS)
F2: 0XX0 (30FPS)
F4: 0030 (60FPS)
However, doing it this way, Frame 2 will take 2 frames to draw, one frame longer than in the above setting; and the FPS in this setting drops from 30FPS to 20FPS.
Color accuracy is increased, as the pixel now looks different stretched over 2 pixels in grey format, rather than doubling the black pixel, like in example above.

Doing the same for a grey pixel in 3 color mode, will essentially stretch the pixel, as dithering is no longer possible (anything between black and grey or white and grey is not available in 3 color mode), and drop the FPS to 10FPS, as each color frame takes 2FPS to draw, and essentially they’re each rendered at 30FPS).
So the entire move of 1 grey pixel takes 6 frames, or 10FPS:

F1: 0X00 (30FPS)
F3: 0XX0
F5: 00X0

Generally good for backgrounds, and slow moving images, moving no faster than what I’d say 10 pixels per second.
Still, stretching and tearing occurs due to F3 doubling the pixels.

You can use this example to move a pixel down, up, left or right from it’s previous spot, doubling the perceivable screen resolution.


4 color settting:
With 4 colors it gets more difficult, as each additional color slows down FPS even more.
For one black or white pixel to move 1 pixel to any direction, it’ll take 8 frames on a 4 color setting, however, it essentially tripling the perceived resolution:

F1: 0300 (60FPS)
F2: 0210 (20FPS)
F5: 0120 (20FPS)
F8: 0030 (60FPS)

This is great for backgrounds that aren’t moving very fast, like less than 8 pixels per second.
A 4 color pixel move using 2 grayscales increases color and position accuracy over 3 color, but drops the pixel framerate considerably, to 8FPS; which would make it quite hard to apply this in fast or medium speed screen objects.
Perhaps rounding off the real life FPS at which the Arduboy refreshes the screen, it’ll be at 9FPS, but still perceivable fps drop to the eye…
It’s probably good for where accuracy and visual aesthetics is required over fluid framerates, and perhaps very slow moving images, like backgrounds moving slower than 8 pixels per second.


This transition pixelation works most fluid on BLACK and WHITE pixels, or MONOCHROME settings, however grey scales increase perceivable resolution accuracy.

In case of a light or dark grey pixel, you’re running 4 colors (black, dark, light, white); which means you’d be running at ~9-20FPS or 1/8th to 1/3rd of the original system FPS.
(I say 20FPS, using 60FPS as a frame of reference. I know the system actually does 67-69 or so FPS, so the real world FPS numbers are somewhat higher).

Possible to do on an arduino, you think?

There’s been extensive discussion about this, actually. :smiley:

1 Like

Yes, more shades of grey, yes.
But increasing perceivable resolution using these same forms of dithering?

I guess I would need to see a proof of concept to understand how that would work.

While i can explain it, unfortunately, I can’t program it :smirk:

However, as proof of concept, if you can program a pixel on the screen, and can program a grayscale pixel, you should be able to program the pixel moving over the screen with increased smoothness, using the principle of dithering…

Then build on that. Perhaps by using sprites, or… I don’t know…
The car game showing the grayscale colors might give some clues how to do it.

I know what you mean :smiley: I guess we’re talking about subpixel positioning. Let me try to make a gif (you don’t need to program it BTW, GIMP is all you need).



1 Like