1 ポイント 投稿者 GN⁺ 2024-11-21 | 1件のコメント | WhatsAppで共有
  • ラスタライズで生じる jaggiespixel crawling は静止画像よりも動きの中で目立ちやすく、この記事では WebGL の円形デモで複数のアンチエイリアシング方式を比較する
  • SSAA・MSAA・FXAA はそれぞれ、ダウンサンプリングのコスト、ハードウェア依存性、後処理ベースの形状歪みという異なる制約を持つ
  • Analytical Anti-Aliasing は図形の数学的な境界が分かっている場合、signed distance field で境界までの距離を求め、エッジ周辺を 1 ピクセル幅で alpha fade する
  • ピクセルサイズは 2D ではオブジェクトやレンダリングサイズから直接計算でき、3D の遠近がある場合は dFdxdFdyfwidth のような Screen Space derivatives が必要になる
  • 追加バッファや特殊ハードウェアなしで WebGL 1.0/OpenGLES 2.0 でも実装可能だが、図形全体の SDF が必要で、1 ピクセルより小さい高周波形状には限界がある

WebGL の円デモで見るアンチエイリアシング

  • この記事の目的は、rasterization で現れる jaggies を減らすさまざまな Anti-Aliasing 手法を見ていき、最後に Analytical Anti-Aliasing の実装を紹介することにある
  • 比較対象は SSAA、MSAA、FXAA、MLAA/SMAA 系、AAA と続く
  • デモは WebGL canvas 上で動く円を描画し、アンチエイリアシングは静止画像よりも 動き の中で理解すべきだという前提で構成されている
  • サンプル canvas はデバイスのネイティブ解像度でレンダリングし、赤いボックスは 4 倍拡大ビューを提供する
  • aliasing が見えにくい高解像度画面に向けて、Native、1/2、1/4、1/8 のレンダリング解像度切り替えを用意し、integer scaling を使っている

基本的な円レンダリングが作る問題

  • 最も単純な円レンダリングは、fragment shader で length(uv) < 1.0 なら色を出力し、そうでなければ discard する方式である
  • 円は実際の geometry 解像度には依存せず、4 つの vertex で作った quad 上で shader が円の内側と外側を判定して描画する
  • varying vec2 uv は fragment ごとに補間され、中心が 0、範囲が -1 から +1 の座標を提供する
  • この方式は Alpha testing に相当し、length(uv) の値は後の AAA で使われる signed distance field につながる
  • 低解像度では円が blocky に見え、動かすとピクセル列が現れたり消えたりする pixel crawling や wobble が強く目立つ
  • 1/4、1/8 解像度は単純な拡大ではなく、3D で小さい、あるいは遠くにある要素を表す例としても使われる

SSAA: 単純だが高コストなダウンサンプリング

  • SSAA は Super Sampling Anti-Aliasing の略で、より大きい解像度で描画した後に小さく downsample する方式である
  • サンプル実装では (canvas.width / resDiv) * 2(canvas.height / resDiv) * 2 サイズの texture に円を描き、標準解像度の framebuffer にダウンサンプリングしてから画面に blit する
  • 2 倍解像度レンダリングは出力ピクセル 1 つあたり入力ピクセル 4 つを使うため、メモリと計算量が 4 倍になる
  • 実際のサンプルではアンチエイリアシングは起きるものの、期待より弱く見える
    • 透明度の段階は 4 段階あるはずだが、観察上 2 段階しか見えない区間がある
    • 低解像度では 4 段階の透明度は主に 45 度の対角線付近で現れる
    • 軸に揃った下部では完全不透明と 50% 透明しか見えず、25%、75% の段階が抜ける
  • 原因は円形状そのものを 2 倍解像度でサンプリングしているのではなく、すでに quantized された円の結果を再サンプリングしているためである
  • サンプル実装は 2x resolution texture と linear interpolation を使うため、実際には VRAM を 5 倍使う
  • 正しい SSAA は中間 buffer なしで scene を複数回サンプリングし、結果を合成する方式であり、レンダリングパイプラインとの深い統合が必要になる

MSAA: ハードウェアベースのサンプリングの長所と短所

  • MSAA は supersampling の一種だが、主にモデルのシルエット・重なり合う geometry・Alpha to Coverage が有効なテクスチャエッジに適用される
  • 実装は GPU ハードウェアとグラフィックスベンダーに依存し、サポートレベルはハードウェアやドライバによって異なる
  • WebGL 1 は MSAA をサポートしないため、サンプルは WebGL 2 context を使う
  • サンプル UI は No MSAA、2x、4x、8x、16x、32x、64x と、レンダリング解像度 Native、1/2、1/4、1/8 を比較する
  • gl.MAX_SAMPLES で利用可能な最大サンプル数を読み取り、選択可能なオプションだけを有効化する
  • モバイル GPU では renderbufferStorageMultisample() の呼び出しが実際には 4x MSAA に強制されることがある
    • Android では 2x の選択を許可してもドライバが 4x に強制する
    • iPhone と iPad では 2x を選ぶと 4x になり、透明度が 50% 刻みに近い値へ丸められるため、サンプルでは二重エッジが生じる
  • MSAA はハードウェア任せの方式なので、ユーザーのデバイスが必要な機能をサポートしていない場合がある
  • サンプリングパターンは予想と異なる結果を生み、ハードウェアによっては円エッジの透明度段階が「順序がおかしく」見えることがある
  • 特定の条件では依然として強力である
    • forward rendering
    • あまり高密度すぎない geometry
    • tile-based rendering architecture を持つ GPU
  • Rahul Prasad は、モバイルでは MSAA はデスクトップほど高コストではなく、一部のモバイル GPU では 4x MSAA が無料になり得ると説明している
  • 追加資料として KhronosGroup Vulkan-Samples の MSAA color resolve deep-dive が言及されている

MLAA、SMAA、FXAA へ続く後処理の流れ

  • 2009 年の Alexander Reshetov の論文は、blocky な aliasing 画像からエッジを見つけ、ピクセル形状ごとのフィルタリング規則でブロック状エッジを減らすアプローチを提示した
  • この morphology ベースのアプローチは MLAA につながり、その後 sub-pixel artifact の除去により重点を置いた SMAA へと改良された
  • 一部のユーザーは MLAA/SMAA 系をぼやけすぎだと見なし、「vaseline on the screen」という表現が生まれた
  • 後処理アンチエイリアシングは、不安定なハードウェアサポートから離れ、AA が shader ベースへ移っていく流れを示している

FXAA 3.11: 高速な後処理 AA の構造と限界

  • FXAA は Timothy Lottes による Fast approximate anti-aliasing アルゴリズムで、MLAA に着想を得た方式である
  • 公開された最終版は FXAA 3.11 で、デモは 2011 年 8 月 12 日リリース版をベースにしている
  • デモは円形シーンを Native、1/2、1/4、1/8 解像度で比較する
  • 基本設定では FXAA_PC 1FXAA_QUALITY_PRESET 12fxaaQualitySubpix 0.75fxaaQualityEdgeThreshold 0.166fxaaQualityEdgeThresholdMin 0.0833 を使用する
  • FXAA は中心ピクセルと上下左右の輝度をまずサンプリングし、local contrast が閾値より低ければ元のピクセルを返す
  • early exit でなければ対角方向の輝度までサンプリングし、水平方向・垂直方向の edge 方向を計算した後、両方向に探索して edge の端を探す
  • 最終的にピクセル座標を移動して texture2D をサンプリングし、公式 whitepaper の基準では単純に edge を blur する方式ではない
  • 円形デモでは静止時のエッジは滑らかに見えるが、円が動くと形状が歪む
    • 軸に揃った上下部分で小さな突起が現れたり消えたりする
    • 低解像度では円が丸い形を失い、PlayStation 1 のグラフィックスのように揺れる
  • 各ピクセルごとに 3x3 の近傍しか考慮しないため、その領域が大きな円の一部であることを認識できない
  • FXAA はより複雑なシーンをアンチエイリアシングするために作られており、複数の設定とプリセットを提供する
  • NeoTokyo° シーンを使った full demo では aliased output から luminance channel を計算して FXAA を適用し、すべての preset と setting を操作できるようになっている

FXAA の入力とパラメータ条件

  • FXAA_GREEN_AS_LUMA を 1 に設定すると luma の代わりにグリーンチャンネルを使い、このとき RGB 入力は非線形色空間である必要がある
  • FXAA の入力 RGB は LDR である必要があり、具体的には tonemapping の後に FXAA を適用する必要がある
  • FXAA_GREEN_AS_LUMA を使わない場合は、FXAA 実行前に alpha チャンネルへ perceptual space の luma を保存しておく必要がある
  • luma を正しく計算してはじめて FXAA は正常に動作する
  • FXAA_QUALITY_PRESET は性能と品質をトレードオフする設定である
    • 12 は default
    • 1529 は highest quality
    • 39 は EXTREME QUALITY
  • fxaaQualitySubpix は sub-pixel aliasing の除去量を調整する
    • 既定値は 0.75
    • 1.00 はより滑らかで、0.50 はよりシャープだが sub-pixel aliasing の除去は少ない
    • 0.00 はオフの状態
  • fxaaQualityEdgeThreshold はアルゴリズムを適用するために必要な最小 local contrast を決める
  • fxaaQualityEdgeThresholdMin は暗い領域を処理対象から切り落とす
  • FXAA は、すでにポストプロセスのパイプラインがある場合や deferred shading を使っている場合、性能コストが低いことがある
  • モバイルグラフィックスではメモリアクセスが高コストなため、FXAA のために render-to-texture 構成を新たに作る必要があるなら、コスト面の利点は弱まる

Analytical Anti-Aliasing の要点

  • Analytical Anti-Aliasing は、必要な図形が分かっている状態で、ピクセルをあらかじめアンチエイリアス済みの形で描画する方式である
  • 2D または 3D 図形を描く際に、図形の境界を正確に 1 ピクセル分だけフェードさせる
  • 例では円を Native、1/2、1/4、1/8 解像度で比較し、低解像度でも edge smoothing と shape の保持を示している
  • circle-analytical.fsdist = length(uv) で円の signed distance field を計算する
  • 円境界付近のピクセルを 1 ピクセル幅でフェードするために、alpha = (1.0 - dist) / pixelSizeAdjusted を使う
  • この方式は artifact なく滑らかで、filtering 量を調整でき、追加 buffer や追加ハードウェア要件もない
  • extension なしで標準の WebGL 1.0 または OpenGLES 2.0 でも動作する
  • 1 ピクセル smoothing はシャープだが、画面解像度・サイズ・円の位置の組み合わせによっては、軸に揃った 90 度の側面が依然として flat に見えることがある
  • 対角線方向のピクセルサイズである √2 px = 1.4142... を基準に filtering すると flat な印象を減らせるが、図形はごくわずかにぼやける

“Analytical” の意味と SDF ベース実装

  • グラフィックスプログラミングで “Analytical” とは、意図した shape の構成をあらかじめ把握し、その数学的定義に対して計算して作る効果を意味する
  • この用語は computer graphics で緩やかに使われており、文脈によって複数の意味を持ちうる
  • 実装は signed distance field をベースにしており、サンプリングするすべての point で目的の shape までの距離が分かっていることを前提とする
  • この情報は SDF text rendering のように texture に bake することもでき、単純な shape では数式で per-pixel に導出することもできる
  • signed distance に応じて shape border を fade out し、fade 距離を 1 ピクセルサイズにすると smooth edge が得られる
  • 実装上の重要な問いは、shader がどうやってピクセルサイズを知るのか、distance を基準にどう blend するのかである
  • このアプローチは motion-stable な pixel-perfection を提供するが、traditional rasterization とは相性がよくなく、図形全体の signed distance field が必要になる

ピクセルサイズ計算: 事前計算、dFdx/dFdy、fwidth

  • 境界フェード幅を円半径の 95% のような固定値にすると、特定のサイズや解像度では見栄えがよくても、サイズが変わると過度に滑らかになったり aliasing が発生したりする
  • ピクセルサイズは Screen Space derivatives が解決する問題の一つである
  • dFdxdFdyfwidth は、ある値が画面ピクセル単位でどれだけ変化するかを求められるようにする
  • 例では pixelSize = fwidth(dist) または pixelSize = length(vec2(dFdx(dist), dFdy(dist))) によって距離の変化量を求める
  • Screen Space derivatives は 3D パースを含む変換も正しく反映するが、WebGL 1 の標準には含まれていないため、GL_OES_standard_derivatives 拡張または WebGL 2 が必要になる
  • length() 方式は dFdx と dFdy が作るベクトル長を求め、fwidth()abs(dFdx()) + abs(dFdy()) の近似値を使う
  • fwidth() の近似は対角線方向で大きくスケールしすぎるため、フェードが対角線でより強く適用されることがある
  • Unity 拡張 Shapes は、fwidth() ベースの AAA を “Fast Local Anti-Aliasing”、length() ベースの方式を “Corrected Local Anti-Aliasing” と呼んでいる
  • 2D ではコンテキストのレンダリングサイズと quad サイズが分かっているため、ピクセルサイズをオブジェクトごとに直接計算できる
  • 例では gl.uniform1f(pixelSizeCircle, (2.0 / (canvas.height / resDiv))) のように高さ基準のピクセルサイズを渡しており、この方式は WebGL 2 や拡張なしでも古いハードウェアで動作する

alpha blending と step 関数の選択

  • フェード幅を求めたら、次は不透明度を調整する必要がある
  • 2D では Alpha blending がシンプルな選択肢である
  • 別の選択肢は MSAA と Alpha to Coverage を併用する方式で、3D シーンで正しい blending のために depth-buffer write が必要な場合に使える
  • アルファは距離ベースでフェードさせる必要があり、一般には start と end の間を補間する step 関数が使われる
  • GLSL のアンチエイリアシング実装では smoothstep() がよく使われるが、この文脈では 1〜2 ピクセル内の関数なので、目に見えるような曲線はほとんどない
  • smoothstep() から Hermite interpolation を取り除くと、clamp された線形補間である linearstep() になる
  • 1 つの quad に図形が 1 つしかない場合は、clamp も取り除ける
  • 最終的なアルファは float alpha = (1.0 - dist) / (pixelSize * smoothingAmount); のような単純な除算で計算できる
  • 性能面で依然として高コストなのはピクセルごとに行う除算であり、現代の GPU は Hermite interpolation の乗算や加算を Fused Multiply-Add に最適化できる

クアッド境界、MSAA、0.5 ピクセル補正

  • MSAA + Alpha to Coverage と rasterizer の間には、一部ハードウェアでのみ現れる相互作用がある
  • MSAA + Alpha to Coverage を使うと、サンプル数に関係なく quad の片側でちょうど 0.5 ピクセルが消えることがある
  • 例ではこれに対応するため、SDF に dist += pixelSizeAdjusted * 0.5 という形で 0.5 ピクセル分の余裕を足している
  • 2D では NV_conservative_raster_dilate に近い処理を自前で実装できる
    • vertex shader で quad を 0.5 ピクセル拡大する
    • fragment shader で signed distance field を 0.5 ピクセル縮める
  • ページの 2D デモはこの方式で動作しており、vertex *= size + pixelSize がその役割を担っている
  • ガンマと premultiplied alpha の問題もあらゆる AA で重要だが、AAA に集中するためここでは扱わない

複数図形と3Dへの拡張

  • 1つの quad 内に複数の図形を描画でき、それぞれにアンチエイリアシングを適用できる
  • 複数の図形がある場合は、両方の図形を各ピクセルごとに評価し、結果を clamp・weight・sum する必要があり、そうすることで交差点でもアンチエイリアシングが維持される
  • 色のオーバーレイを別 pass で描くよりも、必要な図形出力の中で一度に色を付けるほうがコストは低い
  • 3D の例では、動くカメラと遠近法の中に置かれた 2D rounded square を使う
  • 3D fragment shader は roundedBoxSDF で rounded box の SDF を計算し、length(vec2(dFdx(dist), dFdy(dist))) でピクセルサイズを求める
  • カメラと遠近行列の乗算がある場合、Screen Space derivatives を使ってピクセルサイズを得る方法は信頼できる
  • 理論上は derivatives なしで fragment coordinates に逆遠近行列をピクセルごとに掛けることもできるが、性能コストが高い
  • 境界の中心にフェードを置くと、小さなサイズや強い遠近での図形の歪みを減らせるが、エッジが quad の外に出て hard edge や clipping が生じることがある
  • NVIDIA は境界に追加ピクセルを提供する NV_conservative_raster_dilate 拡張を導入したが、WebGL では使えず、NVIDIA ハードウェアに限定される

実際の実装事例

  • Freya Holmér の Unity 拡張 Shapes は、このアプローチの機能面で最も完成度の高い実装と評価されている
    • SDF を MSAA でアンチエイリアシングするか、AAA 方式で blending する
    • motion blur、shape-respecting color gradients、1ピクセル未満の線を opacity fade する機能を含む
    • 1ピクセル未満の線に対する手法は Line Thinness Fading と呼ばれる
  • Valve Software は Orange Box の開発中に、Source engine に signed distance field rendering を広範に導入した
    • Team Fortress 2 の HUD で、滑らかでありながら鮮明な UI 要素を作るのに目立って使われた
    • 固定解像度の画像を高解像度に拡大しても滑らかなシルエットを出せる line art shader system を開発した
    • outline と drop-shadow にも対応し、3D 空間の看板のような world element にも適用できる
  • Valve は SIGGRAPH 2007 の論文で実装を公開しており、その論文には 3D ゲームワールドの事例も含まれる
  • Viktor Chlumský の “Shape Decomposition for Multi-channel Distance Fields” は、Valve 論文の脚注にある手法を発展させた事例である
    • 関連作業には msdfgenmsdf-atlas-gen が含まれる
  • Multi-channel distance field 方式は RGB と median term を使って鮮明なテキストを作り、alpha channel には古典的な SDF を入れて glow や drop shadow のような効果を処理する
  • CJK 文字は微細なディテールのため、より大きな texture が必要であり、大きな texture を縮小すると独自の artifact が生じることがある
  • Google Maps は道路 segment に capsule shape ベースの AAA を使っていると、Hacker News ユーザー aappleby が言及している
    • aappleby は約10年前に自分が書いたものだと述べている
    • Spector.js WebGL debugger で確認したところ、streets draw call の shader code が図形依存の blended alpha を示しているように見えると説明している

SDF 方式の限界と TAA 議論

  • Yakov Galka は、SDF アプローチは特定の点で SDF をサンプリングするため、SDF に高周波成分があると aliasing が生じうると指摘している
  • 1ピクセルより小さい円を rasterize する場合、この文章のアプローチだけでは aliasing を完全に除去できない可能性がある
  • Yakov Galka は、polygonal および bezier shape をアンチエイリアシングして rasterize する真に解析的な方法として、J. Manson と S. Schaefer の Wavelet Rasterization に言及している
  • 記事公開後のコメントでは TAA 批判が強かったというフィードバックがあり、TAA が解決しようとしている問題や、他の手法では解決しにくい問題を十分に扱っていなかったと認めている
  • Timothy Lottes は、TAA を明確な技術的進化と見なしつつも、motion clarity には限界があると述べている
  • FXAA 4 は 2-frame blender であり TXAA とは根本的に異なり、TXAA には MLAA がなく MSAA ベースである
  • TAA をより正しく理解するための資料として、Inside 開発者 Lasse Jon Fuglsang Pedersen による GDC 発表 Temporal Reprojection Anti-Aliasing in INSIDE が勧められている
  • AAA は、ネイティブ解像度でさまざまなサイズの図形を滑らかで鮮明かつ motion-stable に描画できる手法と評価されている

1件のコメント

 
GN⁺ 2024-11-21
Hacker News のコメント
  • 投稿者です。質問があれば答えます

    • Google Maps はすべての道路区間にカプセル形状の AAAを使っています。約10年前に私が書きました :D
    • 素晴らしい記事です。MSDF フォントのアンチエイリアシングを理解しようとしていて、いくつかの主張を見ました
      アンチエイリアシングは sRGB 空間ではなく線形 RGB 空間で行うべきだという主張 [1] [2] と、一方で何十年もそうしてこなかったためフォント側が補正されてきており、場合によっては sRGB のほうがよいという主張 [3] [4] があります。線形 vs sRGB 空間でのアンチエイリアシングについて助言があるか気になります
      [1] https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-ga...
      [2] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
      [3] https://news.ycombinator.com/item?id=12023985
      [4] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
    • 些細な訂正ですが、WebGL は WebGL1 から MSAAをサポートしています。ただし WebGL1 ではキャンバスでのみ可能で、サンプル数は制御できず、アンチエイリアシングをオン・オフできる程度です
      WebGL2 にもまだMSAA テクスチャオブジェクトはなく、MSAA レンダーバッファだけをサポートしているため、シェーダーから個別のサンプルを直接読むことはできません。カスタムの解決(resolve)レンダーパスに有用な機能ですが、これは WebGPU でしかできません
    • アップスケーラーに依存する最近の流れが行き過ぎて、多くの AAA ゲームがぼやけてアーティファクトの多い結果を出していることには同意します。ただ、Digital Foundry のこの詳細分析 [1] を見た後では、DLSS のような技術にしか得られない動きの安定性と鮮明さがあり、SSAA より優れることさえあるという論理はかなり説得力がありました
      そのため今では「TAA == ぼやける」ではなく、「TAA + 機械学習を適切に使えば、現在の 3D ゲームで可能な最高のアンチエイリアシング」という考えに変わってきたのですが、どう見ているか気になります
      [1] https://youtu.be/WG8w9Yg5B3g
    • この記事を書くのにどれくらいかかったのか気になります
      私もリアルタイム可視化ベースのブログ記事を何度か書いたことがありますが、ものすごく時間がかかりました。それでも、それが正しい方向のように思います。コンテンツがあふれる時代には、もっと時間がかかっても、より少なく高品質なコンテンツを作るほうが全員にとって有益だと思います
  • アンチエイリアシング自体より、その周辺の問題のほうが大きいです。ゲーム設定で選べるいくつもの略語が互いに何が違うのかほとんど説明されておらず、その半分はまったく知らないものです
    もちろん調べることはできますが、ユーザーフレンドリーさにもう少し気を配ってくれるとよいですね。この記事は今後参照するのに役立ちそうです

    • ゲーム/グラフィックスは確かに専門用語が多い分野です。魔法使いになりたいのでなければ、単に切り替えて結果を見ればよいでしょう。Dolphin のように設定に詳しいツールチップを付ける方式は気に入っていますが、常にある程度の暗黙知は残らざるを得ません
      メタ的には、最近は略語に反対する雰囲気をよく見る気がします。今ほど調べやすい時代もなかったと思います。学習を妨げたり、一種の門番役になったりするレベルの略語も確かにありますが、概念に有用な粒度で名前を付けなければ仕事はできないので、ゲームのグラフィック設定の略語はかなり合理的な部類だと思います
  • WebGL の例でグラフィックスプログラミングを分析するやり方が天才的です。媒体の強みをきちんと活かしたハイパーテキストです。https://pudding.cool/ で見かけそうな記事を思い出させますが、深さはずっと上です
    しばらくレンダリングエンジンで MSAAx4 を使ってきて、最近は FXAA/TAA 実装に切り替えるか悩んでいたのですが、実際に切り替えるかはもうよく分かりません。ここで多くを学びましたし、UI 要素には解析的アプローチを試してみると思います。グラフィックスプログラミングの記事が HN に頻繁に上がるわけではありませんが、さらに関心がある人には、フレーム分析記事を集めたこのリソースをおすすめします:
    https://www.adriancourreges.com/blog/

    • Steve Wittens も https://acko.net/ で、WebGL を交えた数学イラストのようなこの種の記事をたくさん書いています
      特に好きな記事は https://acko.net/blog/how-to-fold-a-julia-fractal/ です。三角関数と複素数の関係を理解するのに、これほど役立った資料を見たことがありません
    • TAA は本当に嫌いです。特に低フレームレートではゴーストがひどすぎます。ゴーストを避けるために、わざとより遅いアルゴリズムに切り替えることがよくあります
  • 円と拡大部分のあるフレームがメッセージを伝えるやり方が見事です。記事全体がとても読みやすいです

  • SDF または mSDF は未来ではなく、すでに十分に優れた古典である
    「ピクセルごとにすべてのベジエ曲線セグメントを解かなければならないので性能が大きく低下する」という部分のほうが、むしろ未来、あるいは現在だと思う。Slug と DirectWrite はすでに良好な性能で使われている
    https://sluglibrary.com/
    https://learn.microsoft.com/en-us/windows/win32/directwrite/...

    • 暗黙曲線レンダリングも忘れてはいけない [0]。特許はまもなく失効する予定 [1]
      [0]: https://www.microsoft.com/en-us/research/wp-content/uploads/...
      [1]: https://patents.google.com/patent/US20070097123A1/en
    • 約20年前に Microsoft Game Studios 向けにLoop/Blinn 論文の実装を書いたことがあるが、今でも使われているのか気になる
      プロダクション品質にするには本当に多くの作業が必要だった。その論文のボロノイベースのテッセレーションは、多くのアジア系文字で病的に悪化した
    • 記憶が完全に間違っているかもしれないが、Slug で使っているアルゴリズムには特許が絡んでいなかっただろうか?
  • 記事をスクロールしていたら、NeoTokyo のスクリーンショットがすぐ目に入った。あの廊下を何千回も走り回った。数年にわたってその MOD のサーバーを運営し、小さいながら腕がよくて良いコミュニティと本当に楽しい時間を過ごした

    • さらに驚くのは、今でも活発にプレイされていることだ。毎週金曜の夜にはサーバーが1つ満員になり、時には土曜・日曜にもそうなる。かなり熱心なファン層がいて、これほど古いマルチプレイヤーゲームでそのような献身ぶりを見たことがない
  • 2D と 3D のレンダリングエンジンをどちらも書いた立場から少し補足すると、両者は本当に違う。次元が1つ増えるだけではなく、目的、ユースケース、期待値がまったく違う
    だから「ここで話したすべての内容は 3D にも拡張できる」というより、この記事全体は 2D レンダリングではなく、ほとんど3D レンダリングについての記事だと言いたい。2D レンダリングの観点からこのテーマを扱った良い記事としては、https://ciechanow.ski/alpha-compositing/ がある
    3D では誰も気にしないが、2D では非常に重要なアンチエイリアシングの基準が正確性とバイアスである。たとえば AAA はバイアスが大きく、不正確だ。同じ形状を同じ位置に何度も描くと、より不透明または暗くなる。MSAA では同じことは起こらず、誤差は制限されており、バイアスもない

    • JS/TS で WebGPU ベースの3D ベクターレンダラーを構想していたところ、昨日あなたのプロジェクト [0] を見た
      太い線の描画が特に興味深い。難しいからだ [1]。最近これ [2] も見て、すべての図形を2次ベジエ曲線セグメントに変換してその手法を使えるのか気になった。追ってみる価値のある方向だと思うか知りたい
      [0] https://github.com/Lichtso/contrast_renderer
      [1] https://mattdesl.svbtle.com/drawing-lines-is-hard
      [2] https://scribe.rip/@evanwallace/easy-scalable-text-rendering...
    • この記事がそのまま 3D に一般化できるとは言いにくい
      提示されている解法は符号付き距離場に依存しているが、重要な部分である「何までの距離なのか?」をさらっと流している。2D ではオブジェクトと背景の境界、つまりシルエットまでの距離を測ればよいので明確だ
      3D ではオブジェクトが回転しながら自己遮蔽が起こり得るため複雑になる。何を基準に SDF を測るのか? 3D オブジェクトの 2D 投影シルエットは常に変化し、単純に事前計算することはできない
  • Captain Disillusion のリンクがうれしかった。その人を知らなかったが、作品はすばらしい。映像効果に関心のある人向けの直接リンク: https://www.youtube.com/@CaptainDisillusion

  • 記事はよく構成されているが、TAA を攻撃している部分は混乱を招く可能性があると思う。SDF アンチエイリアシングは、いかなる意味でも TAA の代替ではない
    TAA はあらゆる種類のエイリアシングを扱うが、ここでは境界エイリアシングだけを扱っている。多くの最新ゲームは間接照明やその他の効果にモンテカルロベースのアプローチを使っており、これは実質的に TAA を必要とする

  • 「モバイルチップは正確に MSAAx4 をサポートしていて状況が奇妙だ。Android では 2x を選べるが、ドライバーはいずれにせよ 4x に強制する」という部分は少し不思議に思う
    自分の Android スマートフォンでは 2x と 4x の違いがはっきり見えるが、iPhone 側のように「丸く」見えるわけではない