Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • I wanted to love this so much but my eyeballs were screaming trying to read the text over the crawling dither pattern.
  • I made it about 7 seconds
  • We had another dithering post a few days ago and nobody answered my question... I'm reposting in case someone who comes here knows the answer:

    "Does anyone know of any application/tool that can perform palette dithering? The idea is "here is a n-color palette specified in their RGB values, here is the full-color RGB image, give me the best possible dithered image using the provided palette". The tools that I've used were underwhelming and produced results full of banding and artifacts.

    Basically, great dithering in color instead of B/W."

    EDIT: Thank you for the answers! I'll check all links.

  • This is common functionality in graphics software, but there isn't such a thing as "the best possible dithered image using the provided palette"; there are unavoidable tradeoffs between sharpness and color precision, so different ways of dithering may be better for different purposes.
  • The gimp can do this.

    Define your palette, then via the dialog spawned through image->format menu, pick your palette from the list.

  • I don't know if it's exactly what you're looking for but I made a free tool https://app.dithermark.com . It only allows 18 colors max, but it has a lot of options, including the ability to determine what color palette to use.
  • Use Google's Squoosh.app: https://squoosh.app

    When editing an image you can choose the 'Reduce palette' option to bring up a way to reduce the number of images used, and the palette reduction panel will let you optionally apply dithering or not.

    The dithering algorithm is not selectable but it's worth trying to see if you like it.

  • I’m using this for making some quake inspired textures - it’s a bit clunky but works for me https://captain4lk.itch.io/slk-img2pixel
  • I responded in that post (though not to you, and probably not what you're after) with a link to my JS canvas library's "reduce palette" filter. It includes both supplying an array of colors to act as the palette, and setting the required number of colors for which the filter can calculate a "commonest colors" palette, calculating color distances in the OKLAB color space - https://scrawl-v8.rikweb.org.uk/demo/filters-027.html

    If anyone wants to see the filter code, it in the GitHub repo here: https://github.com/KaliedaRik/Scrawl-canvas/blob/064469928a3...

  • That’s going to be a tricky problem full of compromises, and entirely up to how you formalize your definition for “the best possible dithered image”.

    Do you care about preserving relative brightness, contrast, edges,… etc.

    Human color perception is tricky, and in the outline you give it’s entirely possible that the provided n-color palette (also, what order of magnitude n are we talking about here?) would be inadequate for a satisfactory rendering of the provided full color image.

  • I left a comment [0] on the other thread, and this is irrelevant if you aren't using Photoshop, but there's a plugin called DITHERTONE Pro that gives you a lot of control over the dither algorithm used + color grade. For actual design, I tend to use this since I'm already in PS cobbling together an image, and you can tweak the results in realtime to dial it in how you want.

    I also have used didder [1] a couple times for dithering via CLI / script. Its results can be pretty good too, just more for repeatable batch operations and you need to make sure your palettes and chosen algorithms will produce what you're actually looking for.

    [0] https://news.ycombinator.com/item?id=45726845

    [1] https://github.com/makew0rld/didder

  • Obligatory link to the in-progress forum post about the development of The Return of the Obra Dinn's dithering effect: https://forums.tigsource.com/index.php?topic=40832.msg136374...

    The difficulty for dithering on an interactive 3d scene is in making the dithering stable on camera rotation, otherwise you get a twinkling stars effect, not dissimilar to the "fireflies" in reflections in ray-traced games.

  • And here's a couple videos about a technique that was inspired by the Obra Dinn's dither, but making it surface stable:

    https://www.youtube.com/watch?v=HPqGaIMVuLs (explanation)

    https://www.youtube.com/watch?v=EzjWBmhO_1E (demo)

    by m12k
  • Great presentation, loved the format! Looking forward to the other two parts.

    I did a bit of ordered dithering on the ZX Spectrum Raytracer (https://gabrielgambetta.com/zx-raytracer.html#fourth-iterati...), it was surprisingly easy to implement and the results were great.

    I wonder why it wasn't done more in the 80s (other than manual pixel art), probably just performance. I do remember seeing ordered dithering patterns in the 90s, in Windows 3.1 and in The Secret of Monkey Island VGA (I guess the backgrounds were hand-painted and scanned?).

  • Surely dithering is good enough to display 10-bit colour on a non-10-bit monitor with good colour.

    The banding disappears and the noise introduced by dithering should hide the lack of depth completely to human eyes.

    So a modern use for graphical dithering. And I'm sure there's more. It's not all for retro art.

  • LCDs have actually used temporal dithering for ages to fake higher bit depth-- it let TN panels with 6 bits if precision per channel appear to have 8 bits of precision, and now it's being used for HDR-10 too!

    Temporal dithering is much simpler algorithmically since you don't have to diffuse error over an area, just flicker a specific pixel between similar shades at the refresh rate.

    https://en.wikipedia.org/wiki/Frame_rate_control

  • Modern printing uses dithering. When you’re going from a high bit rate down to 10 bits or 8 bits, it’s completely fine to use random dithering. Random might not be as fun to write about as Bayer dither patterns, or error diffusion, but for higher dynamic ranges, random is as effective.

    Black and white digital dithering of course has it’s roots in halftoning, which printing has used for more than a century, and it continues to be used for newspapers, for example.

    Photoshop dithers by default when converting from 16 bits per channel to 8 bits. Lots of other image software doesn’t do this, but you start paying attention quickly, I learned from experience, when you order a poster-sized print for $100 and it comes out with visible banding you couldn’t see on your monitor.

  • > Surely dithering is good enough to display 10-bit colour on a non-10-bit monitor with good colour.

    Indeed, but most software does not do this. It's not on people's minds.

    When people hear dithering they think of palette dithering.

    People think 8bit/channel is enough; but it is not.

    Because it is only 256 levels of any gradient. And because of gamma correction it's practically quite a bit fewer; about 14% (i.e. 220) on a full 256 step gradient that went through an sRGB OETF.

    I maintain a Rust crate that solely concerns itself with dithering for such cases as the one you mention.

    The readme has a gradient on top that should make it obvious why this matters.

    https://crates.io/crates/dithereens

  • Interesting topic. I appreciate the effort that went into this, there are some good animations.

    But I find this kind of presentation much harder to read than a classic blog post. It's difficult to skim through the text to see how far it goes (and the article structure is not apparent); instead, I was kind of forced to read the text sentence by sentence (since I was familiar with the topic, I wanted to skip over the basics).

  • It may be more appropriate to compare this to a video than a blog post. This is an interactive video where you control the pacing, such that you don't have to pause if you need more time to read, and can advance as soon as you're done reading the current slide. I generally prefer text content over video content myself, but this seems fine as a variation of the latter.
  • Good lord this is a beautiful web experience
  • Beautiful demo, but I’m not sure it’s accurate to call dithering an “illusion” of more shades than is available?

    If you apply a low pass filter to a dithered image, and compare it to a low passed filtered thresholded, you’ll see that the “illusory” shades are really there in the dithered version, they’re just represented differently in the full resolution image.

    Similarly, a class D amplifier emits purely off/on pulses before a low pass filter is applied, but no one would call the output an auditory “illusion”. In the case of image dithering, isn’t the low pass filter your own vision + the distance to the screen?

  • I would call it an illusion because if you pay attention you can clearly see that the color you perceive isn't actually present. You can see white on an RBG computer screen since your eyes simply don't have the resolution to discern the subpixel colors. However, in a dithered image with only black and white, you perceive gray, but you can also tell what the reality is without much effort. Personally, I think that fits the definition of an illusion.
  • I used different types of dithering (ordered, error diffusion) in many of my design projects as a visual language, static or animated, mostly for projects related to tech/computers/blockchain, sometimes combined with ASCII art.

    There is a certain warmth (or maybe it’s just nostalgia) of these older techniques that can be harvested and combined with new ideas or new takes.

    (Apologies for the Instagram links).

    D.Y.O.R.:

    https://www.instagram.com/p/DH1AjFzi3c6

    D.Y.O.R. (printed):

    https://www.instagram.com/p/Cjfzy23sCOg

    Titles:

    https://www.instagram.com/p/DHITpNYiWtF

    Experiment on controlling the amount of dithering:

    https://www.instagram.com/p/CYO_h9Yh18e/

    by agys
  • Great links. I just did my portfolio in a retro-ish style and started getting into making retro shaders. Check it out: https://olsz.me.
  • Very cool way to visualize it but I will be honest the threshold map doesn’t make sense. This didn’t seem to explain how to form the map, how to choose the threshold values, and so on. It showed grey pixels passing through white, black, and grey pixels and moved onto generalizing this pattern.

    Is this just me being dumb or the curse of knowledge where something is so obvious to the author that they don’t even bother explaining it?

  • On the next episode of dragon ball Z...
  • An incredibly beautiful visualisation but I felt the same. As well as being confused by the threshold map, at first the text seems to suggest that the 'binary' image is the input to the dithering algorithm in order to 'flip' some of the whites to black and vice versa but then it uses a gray area as input to the threshold map.
  • They say that part 2 will discuss how that’s formed, and 3 will discuss error diffusion dithering.
  • How to build the ordered threshold map isn’t obvious, there are some very clever ideas & techniques.

    That said, it might help to keep the ‘threshold’ part in mind. The grey pixels turn into black & white via thresholding, i.e., dithered_color = (raw_color > threshold_color) ? white : black; It might have helped if at the start the point was made that using a threshold map made of solid middle grey results in the un-dithered image.

    You can use a random number for the threshold, i.e., dithered_color = (raw_color > random()) ? white: black; For either random threshold or a threshold map to approximate the original gray tone, the average threshold value needs to be 0.5. That’s a big clue in how you might start making your own ordered threshold map!

    The next step is thinking a little about which pixels turn white as the gray value moves slowly from black to white. It’s best if each time a dithered pixel turns white, it’s not right next to the last one that turned white; you want there to be separate between white pixels when only some of them are white. 50% gray should be a checker board, for example, maybe as opposed to an 8x8 region where the left half is black and right half is white. 25% grey should perhaps be 1 white pixel in the top left corner of every 2x2 region.

    There are a few different ways to achieve those goals, with slightly different tradeoffs, but those are the main things to consider. You might have a lot of fun designing your own threshold map before reading about how others do it. This is insanely easy to experiment with on ShaderToy…