
2026/03/11 23:10
「符号付き距離場を描画する再帰的アルゴリズム」
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
著者は、再帰的な分割と探索を用いたレイマーチングアルゴリズムと線形補間シェーディングを組み合わせることで、Signed Distance Field(SDF)レンダリングをリアルタイムで十分高速にできることを示しています。手法では、ビュー遠近フラストムを四角形に分割し、レイを一括してマーチングしつつオブジェクトに近づいたら再帰的に処理します。これによりピクセルあたりのレイ数が3〜4倍減少し、GPUとCPU両方でフレームレートが3倍向上します。小さなパッチ(≤10 px)の四隅すべてが整列した法線を持つオブジェクト内にある場合、そのパッチ全体を一度にシェーディングし、平坦表面ではピクセルあたり1サンプル未満に抑えることができます。SDFは距離関数で形状を定義し、合成可能であり、従来は球追跡レイマーチング(sphere-tracing)を用いていましたが、ラスタリゼーションやレイトレーシングと比べて計算コストが高いです。2016年に著者はSDFコードのコンパイラ風最適化を検討し、完全なコンパイラが必要であることを指摘しました。バウンディングボリュームはオブジェクト評価を減らすのに役立ちますが、コストを根本的に排除するわけではありません。新しい技術により、CPUのみで動作する3Dゲーム(MacBook Air M1 で約50 FPS)も実現でき、「cone marching」と呼ばれるGPUフレンドリーなマルチパスバリアントを開発し、同様の目標を共有します。これによりハイブリッド手法が可能になり、リアルタイムエンジンでのGPU負荷を低減できる道が開かれます。
本文
Signed Distance Fields(SDFs)、別名インプリシットサーフェスは、3Dオブジェクトを定義する数学的手法です。ポリゴンとラスタライズが命令型プログラミングに相当するとすれば、SDF はグラフィックスの関数型パラダイムと言えるでしょう。このパラダイムでは、オブジェクトは「その表面までの符号付き距離」を計算する関数で定義されます:距離はオブジェクトの外側が正、表面でゼロ、内側が負になります。
SDF の魅力は、簡単に組み合わせられる点です。ある形状を別の形状から引き抜いたり、変形・ねじれさせたり、空間自体を曲げることも可能です。ポリゴンでは困難だった操作が極めて容易になります。このパラダイムにより、3D シーンはコードだけで定義でき、比較的短いプログラムでも「無限の手続き都市」のようなものを生成できます。まるで未来型グラフィックス技術のようです。FORTRAN のプログラマたちが Lisp コードを初めて見たときに抱いた驚嘆感覚に似ています。
SDF を広く普及させ、手軽に扱えるようにしたのは Inigo Quilez への大いなる功績があります。この技術はデモシーンでも広く使われるようになり、Mercury と呼ばれるチームは「64KB のデモ」を制作しました。音楽・テクスチャ・ロジックすべてが自己完結型実行ファイルに収まっており、全てが手続き的に生成されていました。そのデモは当時としては驚異的なグラフィックスを SDF を駆使して作り出しました。
SDF のレンダリングの標準アルゴリズムはレイマーチング(またはスフィアトレーシング)です。理解しやすく実装も簡単で、ポリゴンのラスタライズよりはるかに直感的です。画像平面への投影やクリッピングといった複雑な処理を必要とせず、SDF を直接サンプリングするだけです。ただし、その代償として計算コストが高くなる点があります。1 画素あたりに SDF のサンプル数が多くなる場合(特に複雑な SDF の場合)があるためです。レイマーチングは通常、レイトレーシングよりも遅いですが、SDF の魅力的な性質を考えると、より高速なレンダリング手法を探求する価値があります。
2016 年に私は部分評価(コンパイラ技術の一種)を用いて SDF レンダリングを最適化しようと試みました。区間演算が役立つ場合もありますが、SDF 用の完全なコンパイラを構築するのは手間がかかります。よりシンプルなテクニックとして、バウンディングボリュームでビュー frustum に intersect するオブジェクトだけを絞り込み、ピクセルあたりのサンプリング数を減らす方法があります。しかし SDF は依然として高価です。
SDF を使ったリアルタイム 3D グラフィックスは、現代 GPU が複数回関数評価を1画素に対して実行できるようになってから実用化されました。CPU 上では、すべてのコードが一つの言語で書けるという利点があります。GPU と CPU の API 間でデータをやり取りする必要がありません。
最近私は CPU でのレンダリングに再帰的な分割&征服アルゴリズムを考案しました。ビュー frustum を小さな四角形へ再帰的に subdivide します。最初はフルアンブレラをカバーする単一レイから始め、可能な限りすべてのレイを同時に進めます。オブジェクトに近づくと、そのパッチを四分割し再帰的に処理します。GitHub の Rust 実装は、ピクセルあたりのレイ数を 3〜4 倍削減し、単純なシーンでフレームレートを 3 倍以上向上させることを示しています。混雑したシーンやフラクタルでは効果が薄れますが、十分に空間が広く表面が平坦な場合には明らかなメリットがあります。
さらに、このアルゴリズムを線形補間で拡張し、10×10 ピクセルまでのパッチ全体をシェーディングします。四隅がすべてオブジェクト内部にあり法線が整列している場合、そのパッチは平坦な表面上にあるとヒューリスティックに推測でき、ピクセルあたり 1 サンプル未満で済みます。この近似手法はフラットシェーディングされたオブジェクトに適しています。
他者が同様のアイデアを持っているかどうか気になり、オンライン検索を行いましたが結果は得られませんでした。X(旧 Twitter)で概念を共有し、Inigo Quilez に連絡しました。当初は再帰分割が GPU には向かないと考えていましたが、複数のシェーダーパスで似た効果を実現できることに気づきました。まず 8×8 ピクセルパッチごとにレイマーチング・コーン(cone marching)を行い、その開始距離を第二パスへ渡すという手法です。
既に GPU 上で多重パス技術が適用されていることは確認済みで、一般的には「Cone Marching」と呼ばれています。以下のようなオンライン記事があります:
- 「5 分以内に Cone Marching をマスター」
- 「Mandelbox フラクタルを Cone Marching で高速化」
- 「Three.js における Cone Marching」
- 「DD2018: Sebastian Aaltonen – GPU ベースの粘土シミュレーションと Ray Tracing 技術(Claybook)」
これらの技術を利用すれば、再帰アルゴリズムで単純な SDF オブジェクトを 50 FPS 程度までレンダリングでき、補間シェーディングを併用すると MacBook Air M1 の CPU コア単体で 100 FPS を達成できます。コードはまだ最適化の余地が大きいですが、SIMD やマルチコア CPU でさらに磨けば、720p(おそらく 1080p)で「CPU だけで実装された一人称シューティングゲーム」を実現する可能性があります。GPU 上では、SDF グラフィックスを用いたゲーム開発はすでに十分に実行可能で、多数の効率化テクニックが存在します。
© 2011–2026 Maxime Chevalier‑Boisvert. All rights reserved.