世界を動かす技術を、日本語で。

ディザリング – パート2: オーダードディザリング

概要

visualrambling.space は、Damarによる視覚的な探究をテーマにしたサイト。 本記事は ordered dithering (順序付きディザリング)の仕組みとパターン形成を視覚的に解説。 グレースケール画像 を白黒2色に変換する方法に焦点。 しきい値マップ の配置や種類によるパターンの違いを紹介。 さらなるディザリング手法やリソースも案内。

Ordered Ditheringの視覚的探究

  • visualrambling.space はDamarによる新しいトピックの視覚的な探究・発信サイト
  • コラボレーションや依頼 も随時受付中、気軽な連絡歓迎
  • 画面右側のタップ/クリック で次に進むインタラクション設計
  • Part 1未読の場合 は先にそちらの読了推奨、ディザリングの基本(色数の拡張)を解説

Ordered Ditheringの基礎

  • ordered ditheringしきい値マップ を使い各ピクセルの最終色を決定
    • 本記事は 白黒2色のグレースケールディザリング のみ対象
  • しきい値マップ の構築方法で独自のビジュアルパターンが生まれる
  • 技術的な詳細ではなく ロジックの視覚的理解 を重視

量子化の復習

  • 量子化 とは画像の色数削減処理
    • グレースケール画像は黒〜白まで多数の階調
    • 表示装置が 白黒のみ の場合、全階調を白か黒に変換する必要
  • 方法例
    • 四捨五入 :暗い階調→黒、明るい階調→白
    • しきい値設定 :しきい値未満→黒、しきい値以上→白
  • しきい値によって出力結果が変化
    • 低いしきい値:暗い階調も白化
    • 高いしきい値:明るい階調も黒化

複数しきい値による変換

  • 複数しきい値 を同時に用いることで黒白の混合パターン生成
    • 明るい入力→白多め、暗い入力→黒多め
  • これが しきい値マップの本質
    • グレー階調を黒白パターンに変換し明るさを模倣

画像全体への適用とパターン

  • しきい値マップのタイル配置 で画像全体を変換
    • 直線的なパターン(例:縦線アーティファクト)が発生する場合あり
    • マップの並びが出力に直結するため

アーティファクト対策

  • しきい値マップの再配置 (例:2x2マトリクス)でクロスハッチパターン生成
    • 黒白ピクセルを分散し、縦線などのアーティファクトを防止
    • 均一な黒白分布で滑らかなグレー表現

階調表現の改善

  • 2x2マトリクス ではパターン数が4つのみ→階調遷移が粗い
  • 4x4 Bayerマトリクス でしきい値を16段階に増加
    • 16種類のパターンで16階調を表現
    • より滑らかなグラデーションを実現
  • 階調間の急な変化を軽減、自然な画像表現

さらなるパターンの拡張

  • 8x8 Bayerマトリクス :64段階のしきい値でより細やかな階調表現
    • パターンはクロスハッチ系を維持しつつ、より滑らかな変化
  • 8x8 Cluster Dotマトリクス :円形のドットクラスターで新聞印刷のような質感
    • Bayerと異なり、より自然なグレー表現や柔らかい質感

まとめと今後

  • しきい値マップ で階調をパターン化し明るさを再現
  • マップの配置や種類で多様なディザリングパターンが生成可能
  • 他にも多くのマップが存在し、さらなる探究余地あり

参考リソース

  • Ditherpunk — モノクロ画像ディザリングに関する包括的記事
  • Robert Ulichney のvoid-and-clusterディザリング論文

次回予告・案内

  • 次回は マップを使わないディザリング (Error Diffusion)を紹介予定
  • visualrambling.space ではThree.js、WebGL、dithering、ビジュアライゼーション、インタラクティブ学習なども扱う
  • フォローやシェア 歓迎、今後も視覚的な記事を多数発信予定
  • コラボや依頼 も随時受付中、気軽な連絡推奨

Hackerたちの意見

関連: ディザリング - パート1 https://news.ycombinator.com/item?id=45750954

ありがとう!

Chromeだと「アセットを読み込んでいます。しばらくお待ちください...」って表示されて止まっちゃう。でも、Firefoxではちゃんと動くよ。

これ、本当に素晴らしい作品だね。他の投稿もそうだけど。もし作者が見てたら、使ってる技術について聞いてみたいな。

ZX Spectrumのレイトレーサーで順序付きディザリングを使ったよ(https://gabrielgambetta.com/zx-raytracer.html#fourth-iterati...)。今回はカラー画像に適用してるけど、8x8ピクセルのブロックは2色のうちの1色しか使えないから(Spectrumの面白い制限の一つ)、実質的にはモノクロのディザリングになってる。

スペクトラムベーシックが僕の最初のプログラミング言語だったから、すごく懐かしい気持ちになるよ。君の作品は素晴らしいね。

特にバイヤーディザリングは、Flipnote Studioのアニメーションの特徴的な見た目の一部で、kekeflipnoteみたいなアニメーターからも見覚えがあるかも(例: https://youtu.be/Ut-fJCc0zS4)。

バイヤー dithering は、オリジナルのプレイステーションでもかなり使われてたんだよね。PS1のGPUは24ビットの色精度でGouraudシェーディングができたけど、VRAMの容量(1MB)と帯域幅の制限があったから、16ビットのフレームバッファやテクスチャを使う方が良かったんだ。だから、ソニーはフレームバッファに書き込むピクセルをその場で4x4のバイヤー行列を使ってditherする機能を追加したんだよね。古いCRTテレビで安いコンポジットビデオケーブルを使うと、画像がぼやけてditheringのアーティファクトが隠れちゃうんだ。もちろん、エミュレーターや現代のLCDテレビだとすぐにそれが見えちゃって、独特のざらついた見た目になるんだよね。面白いことに、GPUは「真の」24ビットレンダリングが全くできなかったのに、ソニーはPS1を24ビットのビデオDACと24ビットのフレームバッファを表示できるようにして出荷したんだ。これが主にタイトル画面や動画再生に使われて、PS1のハードウェアMJPEGデコーダーは24ビット出力をサポートしてたんだよね。

自分のプロジェクトで電子ペーパーのノートパソコンを作るために、ディザリングについてちょっと深く掘り下げてみたよ。https://peterme.net/building-an-epaper-laptop-dithering.html ここではエラー拡散アルゴリズムやバイヤー、ブルーノイズ、さらに新しいアプローチも比較してる。ディザリングについてもっと読みたい人がいたらどうぞ!

青ノイズや現代のゲームで使われる3行アプローチを含むいくつかのdithering手法を実装した結果、準ランダムなシーケンスが一番良い結果を出すことがわかったよ。試してみた?

良いまとめだね。オンデマンド印刷プロジェクトを考えてたんだけど、物理的なインクのにじみが電子ペーパーと比べて制約をかなり変えることに気づいたよ。僕の経験では、エラー拡散はドットゲインのせいでしばしばぼやけちゃうけど、オーダード ditheringはインクの物理的な膨張をうまく処理できるみたい。

RustとTypeScriptでブルーノイズジェネレーターとディザリングライブラリを作ったよ。ブルーノイズテクスチャを生成して、画像にブルーノイズディザリングを適用するんだ。ちょっとしたウェブデモもあるから試してみてね [1]。コードはオープンソースだよ [2] [3] [1] https://blue-noise.blode.co [2] https://github.com/mblode/blue-noise-rust [3] https://github.com/mblode/blue-noise-typescript

スクリーンの100%解像度でメディアを見るのって、すごく満足感があるよね。すべてのピクセルがシャキッとして役割を果たしてる。動画を見たり拡大した画像を見るだけでは味わえない喜びだよ。

これをブックマークしておく。グラフィックスアルゴリズムの明確な説明って意外と少ないからね。

普通は gimmicky なページフォーマットはあまり好きじゃないけど、このシリーズはプレゼンテーションがよく考えられてて、すごく良い感じだね。次のエラー拡散に関する記事が待ちきれないよ。アトキンソンditheringがすごく良いと思ってるから、画像をditherするためのウェブコンポーネントを作っちゃった。