プログラミング
meshoptimizerを最適化し、数分で数十億のトライアングルを処理 (2025年)
Optimizing meshoptimizer to process billions of triangles in minutes (2025) (zeux.io)
要約
このブログ記事では、グラフィックスライブラリmeshoptimizerの最適化について詳述しています。特に、NVIDIAのRTX Mega Geometry技術とNaniteのクラスタリングパイプラインに対応するため、数十億ものトライアングルを含む大規模なシーンを効率的に処理する手法に焦点を当てています。記事では、クラスタリング、圧縮、レンダリングといった技術的な課題と、それらを解決するためのmeshoptimizerのアルゴリズム改善について解説しています。
全文翻訳
ビット、ピクセル、サイクルなど
Arseny Kapoulkine (メール、, )
著者
Arseny Kapoulkine (メール、, )
仕事、プロジェクト、出版物
投稿
このブログが気に入ったら、RSSでフォローして古い投稿を読んでください。
最近の投稿はこちら:
AVX-512によるジグザグデコーディング
接線フレームの量子化
meshoptimizer 1.0リリース
数分で数十億のトライアングル
フラクタルを軽視しないでください
測定加速構造
独立の年
アンラーニングメトリクスとアルゴリズム
Xは当然遅い
« フラクタルを軽視しないでください
meshoptimizer 1.0リリース »
数分で数十億のトライアングル
2025年9月30日
今年の初め、NVIDIAは印象的なZorahデモとともに、新しいレイトレーシング技術RTX Mega Geometryをリリースしました。このデモは、約100GBのUnreal Engineシーンとして配布されました。これは、NvRTXというUnreal Engineの特別なブランチでのみ開くことができます。このデモは、クラスタリングレイトレーシングという新しいドライバー公開レイトレーシング機能と、NaniteクラスタリングLODパイプラインの組み合わせの適用を示しました。これにより、Unreal Engineが現在レイトレーシング用に生成するNaniteプロキシメッシュを使用せずに、非常に高精細なシーンをフルレイトレーシングでストリーミングおよび表示することが可能になりました。これは私にはUnreal Engineに特化しすぎていたため、あまり実験できませんでしたが、9月初旬にNVIDIAがvk_lod_clustersオープンソースサンプルのアップデートをリリースしました。これには、とりわけ、ZorahシーンがglTFファイルとして含まれていました。当然、これは私の好奇心をそそり、meshoptimizerでの階層的クラスタリングLODのサポートを改善するためにかなりの時間を費やすことになりました。
テクノロジー
この後の内容は、Naniteについてある程度理解していると、より理解しやすくなります。もしそうでない場合は、Brian KarisらのNanite: A Deep Diveを強くお勧めします。そこでは詳細が語られています。ここでは基本的な流れを要約するだけです。おそらく多数のトライアングルを持つトライアングルメッシュが与えられた場合、私たちのタスクは1) 任意の詳細レベルでメッシュを表すことができる階層構造を生成すること、2) その構造の一部を適切な詳細レベルでストリーミングすること、3) 適切な詳細レベルでメッシュの表示部分をレンダリングすることです。使用する構造は、メッシュの複数の異なる領域で複数の詳細レベルを表すことができることが重要です。これにより、大規模モデルにスケールしながら詳細を適切に分散させることができます。また、レンダリングが効率的であることも重要です。ここで選択される構造はクラスタのグラフ(DAG)です。各クラスタは少数のトライアングル(例えば128個まで)で、指定された詳細レベルでのメッシュの小さなパッチを表します。構造にはさまざまな詳細レベルのクラスタが含まれており、ランタイムコードは視覚的な誤差を最小限に抑える責任があります。クラスタは、結果の視覚誤差が1ピクセル未満である場合にのみ、より粗いクラスタに置き換えられます(そして、結果の切り替えはTAAまたはその他の時間的フィルターによって隠されます)。この技術には3つの難しい部分があります。高精細メッシュからの構造生成、ストリーミング効率化のための結果の圧縮、そして結果のリアルタイムレンダリングです。最初の部分については少しだけ話します。
構造を構築するために、メッシュは一連のクラスタに分割されます。隣接するクラスタはより大きなグループにマージされます。各グループは独立して単純化され、グループの境界エッジが保持されます。その後、結果のグループはさらにクラスタに分割され、プロセスは許容可能なクラスタがなくなるまで再帰します。結果の表現があらゆる詳細レベルでクラスタ間に亀裂を生じさせないように、アルゴリズムの組み合わせ方には多くのニュアンスがあり、個々のアルゴリズムには多くのトレードオフがあります。これは間違いなく論文の主題であり(実際、このトピックについては複数の論文が書かれています)。
Naniteが2021年にリリースされて以来、複数の異なるエンジンがこの処理パラダイムを採用し始めています。私が現在取り組んでいるオープンソースのジオメトリ処理ライブラリであるmeshoptimizerは、2024年から、結果の構造を構築するためにmeshoptimizerが提供する複数の異なるアルゴリズムを組み合わせる方法の例を含んでいます1。エンドツーエンドの例があることで、アルゴリズムの改善や高レベル技術のバリアントの実験がはるかに容易になりました。この例のコードを使ってZorahシーンを処理できるでしょうか?
スケールの感覚
上記のスクリーンショットは確かに見栄えが良いですが、その忠実度を得るには、Nanite以外にもテクスチャ、シェーディング、ライティングの作業が大量に必要です。幸いなことに、私たちはジオメトリ部分だけに関心があります。これは私たちの仕事を簡単にすべきですよね?前述のように、オリジナルのZorahシーンはUnreal Engineのアセットですが、NVIDIAはオープンソースのVulkanサンプルの一部としてZorahのglTFシーンを公開しました。見てみましょうか?
zorah_main_public.gltf.7z
16.4億トライアングル、インスタンシングで189億トライアングル
ディスク上で36.1 GB
レンダーキャッシュ
ディスク上で62 GB、ダウンロードまたは生成可能
…おお。
ジオメトリのみを含む36GBのglTFファイルです。さらに、ほとんどのメッシュには頂点属性データが含まれておらず、位置情報のみです!(サンプルコードはシェーダーコードで位置から法線を導出しています)。
このglTFファイルをBlenderにインポートしようとすると、メモリ不足になるまで約10分かかります2。当然、Unreal Engineははるかに高速です。つまり、このファイルのUEインポートはメモリ不足になり、5分弱でクラッシュします3。明らかに、処理は非常にメモリを消費し、192GBのRAMでも十分ではありません。
幸いなことに、このファイルをインポートする必要はありません。このファイルを処理するNVIDIAのサンプルコードを実行するだけで済みます。しかし、9月初旬にそれを試みたところ、16スレッドを使用しようとした際にもメモリ不足になりました。実験的に、システムで他に何も実行していない限り、8スレッド(--processingthreadpct 0.25)を使用して処理コードを確実に実行できることを見つけました。プロセスには約180GB以上のRAMが必要でした。7スレッドを使用すると、その間コンピューターをある程度使用できるようになりました…実行に約30分かかりました。
このシーンがいかに大きいかについて十分に準備ができたところで、これらすべてを少し実用的にする一連の最適化について話す時が来ました。
ベースライン
この質問の階層構造を構築するには、クラスタリング(メッシュをクラスタに分割)、パーティショニング(クラスタをグループ化)、および単純化(クラスタグループをより少ないトライアングルに削減)が必要です。幸いなことに、meshoptimizerはこれらすべてに対応するアルゴリズムを提供しています。
バージョン0.25以降、meshoptimizerには2つの主要なクラスタリングアルゴリズムがあります。1つはラスタライゼーションとメッシュシェーダー向けに構築されており、ジオメトリをメッシュレットに密にパックすることで生成されるメッシュレットの数を最小限に抑えようとします。もう1つはレイトレーシングと新しいクラスタリングレイトレーシング拡張機能向けに構築されています。前者は過去8年間、段階的な改善と修正を重ねて進化してきました。後者は比較的最近のもので、NVIDIAがRTX Mega Geometryの作業4を公開した後に特別に開発されました。
2つのアルゴリズムが存在する必要がある理由は、レイトレーシングに使用されるクラスタリングは、クラスタの境界が正確にどこにあるかに非常に敏感であるということです。レイトレーシングに最適なクラスタリングにより、個々のクラスタを取得し、それぞれにマイクロBVHツリーを構築し、結果のクラスタ全体に1つのBVHツリーを構築し、結果の構造を通してレイをトレースすることが可能になります。
vk_lod_clustersサンプルはレイトレーシングに最適化されたクラスタを必要とするだけですが、私の元のデモはラスタライゼーションに最適化されたクラスタを使用していたため、それから始めます。
デモコードが最初に書かれたとき、それは基盤となるアルゴリズムに取り組むのに役立つように構造化されており、再利用可能ではありませんでした。これを、従いやすく、シンプルでクリーンなインターフェースを提供するコードに作り直すのに時間がかかりました。コードはメッシュと多くの設定パラメータを入力として受け取り、コールバックを介してクラスタのグループを生成します。この再利用への変換