- 画像の輪郭と形状を保持するASCIIレンダリング手法を開発し、従来方式のぼやけたエッジの問題を解決
- ピクセル単位の単純な明暗マッピングではなく、各文字の視覚的な形状(shape)を数値化してマッチングする高次元ベクトルベースのアプローチを使用
- 文字ごとに上・下・左・右領域の密度を測定して、2次元から6次元へ拡張したshape vectorを生成し、より精密な文字選択を実現
- 境界線の鮮明さを高めるため、**グローバルおよび方向性コントラスト強調(contrast enhancement)**アルゴリズムを適用
- GPUアクセラレーションとキャッシュ、k-d木探索などにより、リアルタイムASCIIレンダリング性能を確保し、高品質な視覚効果を実現
画像からASCIIへの変換
- ASCIIには95個の印字可能文字があり、等幅フォントを使って画像をグリッドに分割
- 各セルの明るさを計算し、文字密度に応じてマッピング
- 単純な最近傍補間(nearest-neighbor interpolation)は、境界がギザギザになるjaggies現象を引き起こす
- **スーパーサンプリング(supersampling)**によってセル内部で複数のサンプルを取得して平均輝度を計算すると滑らかになるが、それでも境界はぼやける
- 問題の核心は、文字をピクセルのように扱っていることにあり、文字固有の形状を考慮していない点にある
文字形状(Shape)の活用
- 各文字はセル内で視覚的密度分布が異なる
- これを数値化するため、セル内部に**サンプリング円(circle)**を配置し、各領域の文字占有率を計算
- 上・下2領域の占有率をベクトルで表現して2次元shape vectorを生成
- 各文字のshape vectorを事前計算しておき、画像のサンプリングベクトルと**ユークリッド距離(Euclidean distance)**で最も近い文字を選択
6次元形状ベクトルへの拡張
- 上・下の2次元だけでは、
-、p、qのような中間・左右中心の文字を表現しにくい
- セルを6個のサンプリング円に拡張して、上・中・下、左・右の差をすべて捉える
- 6次元shape vectorは文字形状をはるかに精密に反映し、円形・対角線の文字もよく表現できる
- 3Dシーンをレンダリングすると、外形線は鮮明だが、面どうしの境界がぼやける問題が発生
コントラスト強調(Contrast Enhancement)
- サンプリングベクトルの各要素を**指数(exponent)**で調整し、暗い値はより暗く、明るい値は維持
- ベクトルを正規化した後に指数を適用し、再び元の範囲に戻す
- この過程により境界線の視覚的な区別が強化され、文字選択がより明確になる
- 均一な明るさの領域では変化がほとんどなく、滑らかなグラデーションを維持
- ただし一部の境界では**階段状(staircasing)**の現象が発生
方向性コントラスト強調(Directional Contrast Enhancement)
- 各セルの外側にも外部サンプリング円を配置し、周辺の明るさ情報を収集
- 外部サンプリングベクトルの明るい値が内部ベクトルの対応要素を暗く調整し、境界方向のコントラストを強化
- 外部サンプリングを拡張して上段・中段・下段の間の影響を広げると、滑らかで鮮明な境界表現が可能
- グローバルなコントラスト強調と組み合わせると、3Dシーンの境界線が明瞭で可読性の高いASCIIレンダリングを実現
性能最適化
- 文字選択時に最近傍探索を単純反復すると遅いため、k-d木を用いて多次元空間で高速探索を実行
- キャッシュにより同一のサンプリングベクトルの結果を再利用
- 各ベクトルを5ビット単位で量子化し、メモリ効率の高いキャッシュキーを生成
- 範囲を8に設定して、品質とメモリ使用量のバランスを維持
- キャッシュされた探索は非常に高速で、数千個の文字でもリアルタイム処理が可能
- サンプリングベクトル計算はGPUへ移し、内部・外部サンプリング、コントラスト強調演算をシェーダーパイプラインで処理
結論
- 文字の形状をベクトルとして数値化して活用するアプローチは、ASCIIレンダリングの解像感と鮮明さを大きく向上させる
- この方式は**単語埋め込み(word embedding)**に似た概念で、他の視覚的問題にも応用の可能性がある
- 初期実装は遅かったが、GPUアクセラレーションとキャッシュ、k-d木探索によってモバイルでも滑らかなFPSを確保
- 色ベースのASCII表現は扱っておらず、今後さらに多様な形状・コントラストの組み合わせを試せる可能性に言及
- ASCIIレンダリングは単なる視覚効果を超え、形状認識とベクトル表現の拡張可能性を示す事例である
1件のコメント
Hacker Newsのコメント
ベクトルを正規化したあとにユークリッド距離を計算するなら、単純な行列積(matmul)でも同じ結果を得られる。 正規化済みベクトルでは、ユークリッド距離はコサイン距離の線形変換だから。 実際の距離値ではなく**順位(ranking)**だけが重要なら、sqrt演算を省略しても同じ結果になり、少しだけ高速に計算できる。
こういう種類の記事が本当に好きだ。一見すると単純そうでも、うまく作るには深い探究が必要になる。 Lucas PopeがReturn of The Obra Dinnのディザリングシステムを開発したときに書いた記事もおすすめ。 Lucas Popeの開発記
「土星の画像をChatGPTで生成した」という一文を見て驚いた。 本物の土星の写真なんてパブリックドメインでいくらでもあるのに、なぜわざわざ偽物の画像を作ってインターネットを汚染するのか疑問だ。
例を見るたびに「いいけど、もっと改善できそうだな」と思っていたのだが、著者が実際にそれを解決していて感心した。 本当に美しい記事で、ブログ全体がこういう深い水準なので購読する価値がある。 alexharri.com/blog
ascii-side-of-the-moonプロジェクトを作ったとき、ASCIIレンダラーを自作してみようかと考えていた。 結局はchafaを使ったが、いつかまた挑戦したいと思っている。 これをライブラリとして公開する予定があるのか、あるいはWebサイトのコードを参考にしてよいのか気になる。
「ASCIIアートでshapeを活用した例は見たことがない」という発言についてだが、実際にはshapeを使うジェネレーターがある。 ascii-silhouettifyというプロジェクトで、色領域の輪郭に合わせて最も大きい文字を選ぶアルゴリズムを使っている。
Acerolaが2024年にエッジ検出ベースのASCIIレンダリングを試していた。 明るさベースのパスの上に方向性のある記号(| / - \)を重ねて表現する方式だった。 関連動画を参照。
ほとんどのASCIIフィルターは**グリフの形状(shape)**を考慮していない。 chafaは各グリフを8×8ビットマップとして扱っていて、そのアプローチが印象的だった。 chafaのソースとギャラリーを見ると、その精巧さが感じられる。
余暇に点字ベースのカラーグラフィックスを実験している。 解像度は十分だが、色表現の精度が足りず、サンプリング後に**コントラスト補正(contrast fixup)**が必要になる。 著者のサンプリング手法を色コントラストの強化に応用できるとよさそうだ。 以前はSobelフィルターでコントラストを高めようとしたが、文字グリッドと整列しないため失敗した。
本当に優れた技術的アプローチと深い分析だった。 最後にCognition cube arrayの改良版が見られるのではと期待していたが、なくて残念だった。 以前YouTubeで、サブピクセルの色コントラストを使ってより良いファビコンを実現したデザイナーを思い出した。 関連記事(Web Archive)