Mantra – MicroPolygon


どうも篠島です。今回はMantraのMicropolygon Renderingについて説明したいと思います。

 

今回のサンプルファイルです。
MicroPoly.zip

 

恐らく多くの方が主なレンダリングエンジンの違いはなんだろう・・・と思われているかと思います。今回はMicropolygon Rendering の説明です。

Micropolygon Rendering  は RenderMan が使っていた REYES アルゴリズムを用いたものです(最近のRenderManでは REYES ではなく RIS が使われています)。レンダリング時にスクリーンをタイルに分割し、そのタイルの中にあるジオメトリだけをメモリに読み込み、タイルのレンダリングが終了するとメモリを開放して次のタイルに移行、ジオメトリのロード、レンダリング・・・というプロセスをタイルの数だけ繰り返していきます。これはメモリの容量が多くなかった昔は、どんな大きなシーンでもレンダリング出来るということで重宝されてきましたが、現在はメモリの大容量化に伴い、この利点は少なくなってきました。他にもモーションブラーやディスプレイスメントがすごく綺麗に表現できると言われています。

RYEYS でのレンダリングのプロセスを簡単に説明すると以下のようになっています。

  • Bound : カメラから見えない部分は削除
  • Dice : プリミティブをマイクロポリゴンに分割
  • Shade : 各頂点でシェーダーの計算
  • Sample : ピクセルの色をサンプリング
  • Visibility : 隠面消去処理
  • Filter : 各サンプリングをブレンドしてピクセルの色を計算(ピクセルフィルター)

Bound

カメラの視界の外にあるプリミティブは必要ないので削除します。カメラの中にプリミティブが含まれても、プリミティブが大き場合は分割(Split)され、カメラ外のプリミティブを削除、プリミティブ再分割・・・を繰り返してプリミティブのサイズが十分に小さくなるまでこのプロセスを繰り返します。下のGIFはあるプリミティブが分割されて削除されるループのイメージです。

Dice

小さく分割されたプリミティブは更にマイクロポリゴンというピクセルサイズの非常に小さなポリゴンに分割されます。下の図はプリミティブがマイクロポリゴンに分割されるイメージです。(分かりやすいようにプリミティブ一つだけを分割しています)

Shading

そしてこのマイクロポリゴンの各頂点でシェーダーを評価します。注意しなければならないのが、ジオメトリがオブジェクトの後ろに隠れて見えていない場合でも、全部の頂点でシェーダーの計算がされます。そして各頂点が色と透明度情報を持ちます。

マイクロポリゴンの頂点にシェーディングを行った結果を表したイメージが下の図です。そして面の部分の色は、頂点の色と透明度を各頂点からの距離に基づいて補完されます。

シェーディングを行った後に、マイクロポリゴンが切り離され(Bust)、それぞれのマイクロポリゴンが頂点を4つもちます。下のGIFは分かりやすくバラバラになった様子を表していますが、実際には頂点は隣のマイクロポリゴンと同一の場所にあります。その後、そのマイクロポリゴンがカメラ内に含まれているかどうかテストをして(ディスプレイスメントによってマイクロポリゴンがカメラ外に出る場合がある)、カメラ外のマイクロポリゴンを削除します。

 

Sampling

そして各ピクセル内をレンダラで設定した分だけサンプルします。上で説明したとおり、サーフェース上の各サンプルの色は頂点の色を補完した値となります。

各サンプルポイントはカメラからの同一線上にあるマイクロポリゴン全ての色と透明度情報を取得し、それらをブレンドしてこのサンプルポイントの最終的な色と透明度の値にします。また、Zバッファに深度のデータを保存します。下の図はサンプルポイント上にある複数のマイクロポリゴン(青い部分)を表したものです。

一つのピクセルに対して複数サンプリングを行うので、それぞれのサンプリングの色と透明度をブレンドした物が最終的なピクセルの色となります。下はイメージ図でピクセル内にある赤いポイントがサンプルポイントとします。

 

Visibility と Filter

隠面消去処理はサンプリング毎の色をブレンドする際に行われます。各サンプルの色と透明度を元にをブレンド(Filter)して最終的なピクセルの色と透明度を得ます。Mantra のデフォルトは 2×2 Gaussian filter になっており、近傍ピクセルのサンプルポイントからも色を取得してブレンドしてピクセルの色を決定しています。

 

Micropolygon Rendering の欠点

先程書いた通り、カメラから見える見えないに関わらず、シェーディングはジオメトリの全ての頂点によって行われます。ということはもし遠景に100万ポリゴンのオブジェクトがあっても、カメラの前に単純なボックスが置かれていてハイポリオブジェクトが見えなければ、後ろにただ存在しているだけで100万ポリゴンの頂点にシェーディング計算をする必要があり、無駄な計算が増えてしまいます。

 

試しにHoudiniで検証

この検証用シーンをサンプルとしてこの記事にデータをUPしています。各頂点でシェーディング計算が行われる MicroPolygon の処理速度がどの程度なものかを検証してみました。使用したシーンは Grid の後ろに高解像度のSphereを200個コピーしたものです。カメラからは Grid が画面を覆っていて、Sphere は全く見ることが出来ません。Sphere をコピーする際に Pack しています。Pack しないとメモリ消費量が物凄い事になり Houdini がクラッシュします。

MicroPolygon と RayTracing のレンダリング結果が以下になります。Sphere一つに頂点が60万個。それを200個コピーしたので、1億2000万個の頂点があり、1億2000回もシェーディングの計算をしなければなりません。MicroPolygon の場合はメモリの消費量も計算時間も多くなっていますが、レイトレースだと一瞬で終わっているのが分かるかと思います。

この様にあからさまに効率の悪いシーンの作り方は実際にはしないと思うので、通常に使用していた場合のパフォーマンスの差は数秒程度の微々たるものかとは思いますが、高解像度のモデルがシーン内にあるとシェーディングの計算が見えない部分まで行われてしまうので、パフォーマンスが落ちると事があるいう事は覚えておいて損はないでしょう。