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

ディザリング – 第1部

概要

  • ディザリング は、限られた色数で多彩な色調を表現する技術
  • 白黒ピクセル の配置パターンでグレースケールを錯覚させる仕組み
  • しきい値マップ を使った基本的なディザリング手法の解説
  • 今回は ディザリングの基礎 に焦点、詳細は次回以降に続く
  • Three.js/WebGL などの視覚的学習・インタラクティブな内容も紹介

ディザリングの魅力と基本原理

  • ディザリング効果 には独特の魅力、限られた色で豊かな表現が可能
  • アニメーションや画像では 黒と白のピクセル が交互に並ぶことで多階調を錯覚
  • ディザリング は実際に使っている色数以上の色を「見せる」技術
  • ここでは 黒と白 のみで複数のグレー階調を表現
  • あるもので最大限表現する」という発想に感銘、学びのきっかけ

グレースケール画像でのディザリング入門

  • グレースケール画像は 黒から白までの複数のグレー階調 で構成
  • 白黒しか表示できないディスプレイ の場合、各ピクセルを黒か白に割り当てる必要
    • ピクセルの明るさが中間値より暗ければ黒、明るければ白に変換
    • これだけだと 境界がはっきりしすぎて不自然な画像 になる
  • ディザリング は一部のピクセルを意図的に逆の色に変換し、パターンを作成
    • 明るいグレーでも一部を黒に、暗いグレーでも一部を白に
    • ピクセル密度の変化で グレーの濃淡 を錯覚させる

しきい値マップによるディザリング

  • しきい値マップ(threshold map) は0(最も暗い)~1(最も明るい)までの値を持つグリッド
  • 各ピクセルの明るさと 対応するしきい値 を比較
    • 明るさがしきい値を超えていれば白、下回れば黒に変換
  • すべてのピクセルでこの判定を繰り返し、 白黒パターン を生成
  • しきい値マップは、元画像の明るさに応じて 黒白ピクセル密度 が変化するよう設計
    • 明るい領域は白が多く、暗い領域は黒が多い配置
  • 遠目で見ると グレー階調 に見える錯覚

大きな画像の場合のディザリング手順

  • しきい値マップを画像サイズに合わせて拡張
  • 各ピクセルの明るさとしきい値を比較し、白黒を決定
  • 結果として 2色のみ で元画像の雰囲気や濃淡を再現
  • 階調の違いは ピクセル密度の違い として表現

ディザリングの本質と今後の展開

  • ディザリングは「 色を増やす効果」ではなく、 色を減らす技術 であるという逆説
  • 今回は 基礎部分のみ を解説、しきい値マップの作り方や他のアルゴリズムは次回以降で扱う予定
  • エラーディフュージョン法 など、しきい値マップを使わない手法も存在
  • アルゴリズムごとに 独自の見た目 が生まれるため、別記事で解説予定

今後のシリーズ予告と案内

  • 次回は しきい値マップ生成アルゴリズム を詳解
  • 最終回は エラーディフュージョン法 に特化して解説
  • Three.js/WebGL などの視覚的・インタラクティブな学習体験も紹介予定
  • 続編もぜひご期待ください

作者・プロジェクト紹介

  • visualrambling.space はDamarによる個人プロジェクト
  • X/Twitter(@damarberlari) で新着記事や情報を発信中
  • Three.js/WebGL、ディザリング、ビジュアライゼーション、インタラクティブラーニング など幅広い話題を扱う
  • 興味があれば フォローやシェア を推奨

Hackerたちの意見

ダニエル・シフマンのコーディングトレインからの2つの動画:画像をドットに変える:ディザリングの魔法 https://www.youtube.com/watch?v=0L2n8Tg2FwI コーディングチャレンジ181:加重ボロノイスタイプリング https://www.youtube.com/watch?v=Bxdt6T_1qgc

なんて美しいウェブ体験なんだ!

「オブラ・ディンの帰還」のディザリング効果の開発についての進行中のフォーラム投稿へのリンクを貼っておくね:https://forums.tigsource.com/index.php?topic=40832.msg136374... インタラクティブな3Dシーンでのディザリングの難しさは、カメラの回転に対してディザリングを安定させることだよ。そうしないと、星が瞬いているような効果になっちゃう。これはレイトレースゲームの反射に見られる「ホタル」に似てる。

これはオブラ・ディンのディザからインスパイアされた技術についての動画だけど、サーフェスを安定させる方法だよ:https://www.youtube.com/watch?v=HPqGaIMVuLs(説明) https://www.youtube.com/watch?v=EzjWBmhO_1E(デモ)

数日前に別のディザリングの投稿があったけど、誰も私の質問に答えてくれなかった… ここに来る人の中で知ってる人がいるかもしれないから再投稿するね。「パレットディザリングができるアプリケーションやツールを知ってる人いる?アイデアは『ここにRGB値で指定されたn色のパレットがあって、ここにフルカラーのRGB画像がある。指定されたパレットを使って、できるだけ良いディザリング画像を出してほしい』って感じ。使ったツールは期待外れで、バンディングやアーティファクトがいっぱい出た。要するに、白黒じゃなくてカラーでの素晴らしいディザリングが欲しい。」追記:回答ありがとう!全てのリンクをチェックするね。

これは妥協だらけの難しい問題になるだろうし、「最良のディザリング画像」の定義をどうするかに完全に依存するね。相対的な明るさやコントラスト、エッジを保つことを気にする?人間の色の認識は難しいし、あなたが示した概要では、提供されたn色のパレット(それと、nのオーダーはどれくらいのことを言ってるの?)が、提供されたフルカラー画像の満足のいくレンダリングには不十分な可能性があるよ。

これを使ってクエイク風のテクスチャを作ってるんだけど、ちょっと使いづらいけど自分には合ってるよ。 https://captain4lk.itch.io/slk-img2pixel

別のスレッドにコメントしたんだけど[0]、Photoshopを使ってないなら関係ないかも。DITHERTONE Proっていうプラグインがあって、ドット絵のアルゴリズムや色調整をかなり細かくコントロールできるよ。実際のデザインでは、画像を作るためにPSを使ってるから、これを使うことが多いかな。リアルタイムで結果を調整できるし。CLIやスクリプトを使ってドット絵を作るためにdidder [1]も何回か使ったことがあるけど、そっちも結構いい結果が出るよ。ただ、繰り返しのバッチ処理向けで、パレットや選んだアルゴリズムがちゃんと目的のものを出すか確認する必要があるけどね。[0] https://news.ycombinator.com/item?id=45726845 [1] https://github.com/makew0rld/didder

その投稿に返信したんだけど(君に対してではないし、君が求めてるものとは違うかも)、自分のJSキャンバスライブラリの「パレットを減らす」フィルターのリンクを貼ったよ。色の配列をパレットとして供給することもできるし、フィルターが「最も一般的な色」のパレットを計算するために必要な色数を設定することもできる。OKLAB色空間で色の距離を計算するんだ。 https://scrawl-v8.rikweb.org.uk/demo/filters-027.html フィルターコードを見たい人は、GitHubのリポジトリにあるよ。 https://github.com/KaliedaRik/Scrawl-canvas/blob/064469928a3...

GIMPならこれができるよ。パレットを定義して、画像->フォーマットメニューから出てくるダイアログでリストからパレットを選ぶだけ。

もし誰かがこれを実装したいなら、私のPhomemo M02に貢献してもらってもいいよ(安い) https://github.com/K0IN/Phomemo-M02-Web

Vueを使ってるみたいだから、VueでMITライセンスのドット絵ウェブアプリを作ったよ。まだ何かに埋め込んだことはないけど、試してみていいよ。 https://github.com/allen-garvey/dithermark

美しいデモだけど、ディザリングを「利用可能な色調よりも多くの色調の“幻想”」と呼ぶのは正確じゃない気がする。ディザリングされた画像にローパスフィルターを適用して、しきい値を設けたローパスフィルター画像と比較すると、「幻想的な」色調はディザリングされたバージョンに実際に存在していて、フル解像度の画像では異なる表現になってるだけだよ。同様に、クラスDアンプはローパスフィルターが適用される前に純粋にオン/オフのパルスを出すけど、誰もその出力を聴覚的な「幻想」とは呼ばないよ。画像のディザリングの場合、ローパスフィルターは自分の視覚と画面までの距離じゃない?

これは錯覚だと思う。よく見てみると、自分が認識している色は実際には存在しないって分かるから。RGBのコンピュータースクリーンで白が見えるのは、目がサブピクセルの色を識別する解像度を持ってないからなんだよね。でも、黒と白だけのドット絵ではグレーが見えるけど、現実がどうなってるかはあまり努力せずに分かる。個人的には、これが錯覚の定義に合ってると思う。

これはハーフトーン(実際のパレットよりも多くの色を持つ見かけのパレットを作る技術で、どこでも同じように丸めてるわけじゃない)だけど、個人的にはドット絵とは思わない。自分にとってドット絵っていうのは、パレット(またはハーフトーンで得られる見かけのパレット)がバンディングを避けるには十分大きくないときに発生するバンディングを消すことを意味する。ここで示されているハーフトーン技術は、2色のパレットを使って20色くらいの見かけの色に増やすけど、それでも20色でもかなり明らかなバンドができる。もっと多くの色(例えば、グレースケールなら256色、RGBなら256^3色)を使うか、ドット絵を使うことでそのバンディングをほぼ消すことができる。デモの最後で触れられている「誤差拡散」技術が、自分が言ってることをやってると思う。ノイズがドット絵の鍵で、今回のデモにはノイズが見当たらない。すべてが決定論的なんだ。でも、プレゼンテーションは素晴らしいね!

興味が湧いたよ。この技術の名前としてドット絵がまだ受け入れられてるみたいだね。 https://en.wikipedia.org/wiki/Ordered_dithering

実はこれをRustで実装してるところなんだ、タイミングが変だね。面白い記事だ。

友達がGo用に最高で最も完全なディザリングライブラリを作ることを目指して書いたのがあって、なかなか良い出来だと思うよ。リファレンス実装を探してるなら、チェックしてみる価値あり!彼の作品はこちらだよ: https://github.com/makew0rld/dither

すごく面白いプレゼンテーションだった!最初の方のスライドで、黒と白のピクセル配置のパターンだけで、だいたい8種類のグレーの濃淡があることが示されてた。画像の「拡大」ビューを使って、異なるグレーの濃淡を分類して、特定のピクセルのグループに対してどんなパターンが必要かを決定することってできるのかな?これって、しきい値フィルターが達成することと同じ結果になるか、もしくは別のディザリング手法になるかもしれないね。ちょっと頭の中で整理しようとしてるところ。

視覚化の方法はすごくクールだけど、正直言ってしきい値マップは意味がわからない。マップの作り方やしきい値の選び方についての説明がなかったように思う。グレーのピクセルが白、黒、グレーのピクセルを通過する様子を示して、そこからこのパターンを一般化していったけど、これって俺がバカなだけ?それとも、著者にとってはあまりにも明白すぎて説明する気がないのかな?

パート2ではそれがどうやって形成されるかについて話すって言ってたし、パート3では誤差拡散ディザリングについて話すらしいよ。