レイトレースするシーンをメモリに格納できない場合、マシンにRAMを追加しないと、シーンのさまざまな部分を1ピクセルあたり数回ディスクから読み込む必要があるため、実際のタイムスパンでレンダリングするのは現実的ではないようです。 。
これを回避する方法はありますか?メモリにロードする必要がある回数を減らすために、シーンの特定のサブセットを含む多数の計算を一度に実行するいくつかの方法を考えています。そのような場合に速度を向上させる他の方法はありますか?
レイトレースするシーンをメモリに格納できない場合、マシンにRAMを追加しないと、シーンのさまざまな部分を1ピクセルあたり数回ディスクから読み込む必要があるため、実際のタイムスパンでレンダリングするのは現実的ではないようです。 。
これを回避する方法はありますか?メモリにロードする必要がある回数を減らすために、シーンの特定のサブセットを含む多数の計算を一度に実行するいくつかの方法を考えています。そのような場合に速度を向上させる他の方法はありますか?
回答:
シーンが完全にメモリに収まらない場合は、コア外レンダリングのフィールドに入っています。ここには本質的に2つのアプローチがあります。a)オンデマンドでシーンを生成するb)オンデマンドでシーンをロードする
前者のアプローチは、モデルがCatmull-Clarkなどを使用して大幅に細分割され、メモリを大量に消費する可能性がありますが、ベースメッシュ自体がメモリに簡単に収まるほとんどのアニメーションワークフローとうまく連携します。Pixarにはこれに関するいくつかの論文があります(たとえば、複雑なシーンでのレイレイトレーシングのためのレイディファレンシャルとマルチレゾリューションジオメトリキャッシング)。ただし、モデルの主な目的は、モデルがレイに当たったときにのみ細分割され、それだけ分割されることです。このような光線には妥当です(たとえば、拡散相互反射はミラー反射よりも精度が低くて済みます)。残りはジオメトリキャッシュによって処理されます。ジオメトリキャッシュは、細分割されたモデルをメモリに保持し、うまくいけば、適切なエビクション戦略によってプロセスを効率化します。
すべてのベースメッシュがメモリに快適に収まる限り、コアから外れて、メモリに収まらないサブディビジョンレベルでメッシュを簡単にレンダリングできます。ジオメトリキャッシュは、使用しているメモリの量に合わせて適切にスケーリングされるため、RAMとレンダリング時間を比較することができます。これは私が信じている車でも使用されました。
2番目のアプローチはより一般的であり、サブディビジョンの多用に依存しません。その代わり、シーンはアーティストによって作成された可能性が最も高く、すでに個別にメモリに収まるかなり小さいオブジェクトに分割されているという事実に依存しています。次に、2つの階層(kDツリーまたはバウンディングボリューム階層)を保持するという考えになります。シーン内のオブジェクトのバウンディングボックスのみを格納するトップレベルの階層と、実際のジオメトリを格納するローレベルの階層です。オブジェクトごとに、このような低レベルの階層が1つあります。
このアプローチでは、理想的にはすでにバウンディングボックスを各オブジェクトとともにディスクに格納しています。シーンが読み込まれると、最初は最上位の階層のみを構築します。つまり、ジオメトリではなく、境界ボックスを確認するだけで済みます。次に、光線の追跡を開始し、階層を通過します。レイが最上位階層のリーフノードに当たる(つまり、オブジェクトの境界ボックスに当たる)と、そのオブジェクトがメモリに読み込まれ、下位レベルの階層が構築されます。次に、光線はそのオブジェクトの追跡を続けます。低レベルの階層を可能な限りメモリ内に保持するオブジェクトキャッシュと組み合わせると、これは適切に実行できます。
このようなアプローチの最初の利点は、ヒットしないオブジェクトが読み込まれないことです。つまり、シーンの可視性に自動的に適応します。2番目の利点は、多くのレイをトレースする場合、レイに当たったときにオブジェクトをすぐにロードする必要がないことです。代わりに、そのレイを保持し、十分なレイがそのオブジェクトに当たるまで待機して、複数のレイヒットで負荷を分散することができます。
また、このアプローチを、プロダクションパストレース用のソート済み遅延シェーディングなどのレイソートアルゴリズムと組み合わせて、インコヒーレントレイによるスラッシングを回避することもできます。前述の論文では、Big Hero 6で使用されているDisneyのHyperionレンダラーのアーキテクチャについて説明しているため、制作規模でシーンを処理できる可能性が高いです。
シーンを空間構造に編成する場合(通常の方法はバウンディングボリューム階層)、一種の仮想シーンを使用できます(この用語は、仮想テクスチャーを参照して作成しています)。
メモリマネージャは、一度に読み込まれる限られた数のバウンディングボックスのみを保持し、1つを取得することで構成される操作を抽象化します。
このようにして、ボックスは必要な場合にのみロードされます。光線がバウンディングボックスに当たると、衝突を解決するためにボックスがロードされます。後で別のボックスをロードする必要があるときに、未使用のボックスを削除して、新しいボックス用のスペースを作ります。
これらすべてのボックスが読み込まれ、削除されると、光線の一貫性が速度の主要な要素になります。既にロードされているボックスを最初に処理するようにレイを並べ替えることにより、ロードを延期することでさらに改善できると思います。
あなたがしていることは、以前にヒットしたことに基づいてディスクから三角形をメモリにロードすることです。まず、近接した三角形から始めます。その理由は、ある領域では光線が同じ三角形に繰り返し当たる可能性が高いためです。そして、最終的には多少効率的になります。(このため、最後のヒットの三角形を、順序を気にしないオクルージョントレースにキャッシュすることをお勧めします)
次に、三角形を空間ツリーに格納します。これにより、ディスクからすばやく検索して、メモリ内のどの部分を近接して更新することができます。したがって、光線の邪魔になるブランチのみをロードします。オクツリーのようなボクセルツリーのようなものであれば、2次光線を並べ替えて、コヒーレンスによってそれらを解決することもできます。BSPツリーは、剪定領域にもやや優れています。
これが失敗する場合もありますが、ノイズをレンダリングしない場合、ほとんどのシーンバケットでかなり効率的です...