Mantra – RayTracing


どうも篠島です。前回に引き続き今回は Mantra の RayTracing エンジンについて説明したいと思います。

 

RayTracing は Micropolygon に比べて非常に単純で、カメラからプライマリレイを放ち、オブジェクトに当たったところでシェーダーの計算をし、次にどこにセカンダリレイを飛ばすかを決定します。そしてセカンダリレイが他のオブジェクトに当たると、そこでそのオブジェクトのシェーダーを呼び出して色を計算します。この様に各セカンダリレイの結果を集め、全てのサンプルの結果をブレンドして最終的なピクセルの色にします。これによりrefrected rayで反射、refracted ray を使って屈折の表現も容易に行うことができます。Mantra の設定によりこれらのレイが何回シーン内をバウンス(反射)できるかを設定することもできます。

 

カメラから放たれるプライマリレイの本数は Mantra の Pixel Samples で設定できます。デフォルトは 3×3 で一つのピクセルに対して9本放ちます。

 

そしてプライマリレイ一本あたり、Mantra の設定により複数のセカンダリレイを若干異なる方向へ飛ばします。デフォルトの設定では1~9本のレイが放たれますが、これは最初に少ないレイを飛ばして、それぞれのサンプルされた結果の値があまりにも異なっていれば、さらにレイを飛ばし、サンプル同士の結果の相違が Noise Level で指定したノイズの値以下になるか、セカンダリレイの数が Max Ray Samples の値になるまでレイを飛ばします。

 

Pixel Samples、 Min Ray Samples 、 Max Ray Samples の設定を変更してレンダリングしたのが下のGIFで、プライマリ、セカンダリレイ各1本の設定と、Mantra デフォルトの設定での比較です。見て分かる通りサンプル数が少ないとノイズだらけになってしまいます。

Mantra  をチューニングしてレンダリング速度アップさせたい場合は、飛ばすレイの数と許容できるノイズレベルの調整になってくるのですが、実際モーションブラーだったりエリアライトを使うとその分サンプルも増えてレンダリングが遅くなってしまいます。なのでシーン内のシェーダーを確認して、反射の設定が0.01とか、微妙に映り込むけど殆ど視認出来ないような場合は、いっその事反射を無しにして飛ばすレイの数を減らせばレンダリング時間を短縮できます。

 

シェーダーで全てをコントロール ( Micropolygon と RayTracing )

Micropolygon は頂点でシェーダーの計算、RayTracing はレイがジオメトリに当たった場所でシェーダーの計算が行われますが、その時ジオメトリに割り当てられたシェーダーによって挙動が大きく異なります。H13からは BSDF モデルを使ったシェーディングが使われるようになり、Principled シェーダーを使ってしまうと嫌でも物理的に正しい計算が行われます(レイを飛ばす方向をコントロールできない)。BSDFについては過去の記事を参照してください。

話を少し昔に戻して、BSDF を使わないシェーダーを使うとします。すると内部には illuminance loop VOP があり、各ライトに対してどの様な処理を行うかを自分でカスタマイズする事ができます。他にも RayTrace VOPで自分の好きな方向にレイを飛ばして、レイが当たった先のオブジェクトのシェーダーを評価してその色を取ってくる等、自由にセカンダリレイの振る舞いをカスタマイズできるわけです。

 

Micropolygon の話

前回の MicroPolygon の部分では触れませんでしたが、本来 MicroPolygon だけであれば、反射、屈折などの表現はできません。しかし Mantra でレンダリングエンジンを Micropolygon にしても反射ができてしまいます。なぜならばジオメトリに割り当てられたシェーダーがレイをどこに飛ばすかを定義しているためです。MicroPolygon エンジンを使ったとしても、シェーダーでレイトレースするように設定がされている為に反射や屈折の表現ができます。なので、MicroPolygon だからレイトレースを使わないという事ではなく、デフォルトでマイクロポリゴンとレイトレースのハイブリッドの様になっています。

前回の記事でタイル内に含まれるジオメトリだけを読み込む為にメモリが節約できると書きましたが、実は反射や屈折を表現するために、シェーダーの中でレイトレースするような設定がされている場合、レイを飛ばした時にジオメトリに当たることができるように、シーン内のジオメトリをカメラ内に入っているかどうかに関わらずメモリ内にロードしなくてはなりません。最近のシェーダーだと反射とか普通にあるので、結局ジオメトリをメモリにロードしなければならず、タイル内だけのジオメトリを読み込んでメモリ節約とはならないケースが多いです。

例えばカメラ内にオブジェクトが有り、カメラ外に数千万ポリゴンの高解像度のジオメトリがあるとします(あまりにもポリゴン数が多いためバウンディングボックス表示にしています)。

 

下のGIFはPrincipled シェーダーを使って Reflectivity の値を 0 と 0.1 にしてレンダリングした結果です。少しでも反射があると周りのジオメトリがメモリに読み込まれるために、レンダリング時に使用されるメモリが増加するのが分かるかと思います。

 

これは反射だけではなく全てのレイに言えることで、例えばライトがカメラの外側にあり、何かしらのジオメトリがライトを遮っている場合、影を落とすためにそのジオメトリもメモリにロードされます。

 

サンプリングの違い

Micropolygon と RayTracing のサンプリングには下のような違いがあります。Micropolygon はマイクロポリゴンの頂点だけにシェーダーの計算がされますが、RayTracingではレイがヒットした場所でシェーダーが計算されます。なので極端な話、飛ばすレイの数が多くなれば多くなるほど RayTracing の処理には時間がかかる事になります。

実際のシーンだとジオメトリの数が大量にあったりしてマイクロポリゴン数が多くなり、無駄なシェーディング計算も増えてしまうので、そこまで神経質になる必要はありません。求める絵の質感、速度が得られる方のレンダリングエンジンを使うといいと思います。