Point

アンリアルエンジンではプロジェクトがどのようにビルドされているのか?

リアルタイムレンダリングは、プロジェクトが空っぽの時がパフォーマンスの最高潮です。この時点から先の作業はすべて、結果として処理を遅らせることになります。言い換えれば、リアルタイムレンダリングでの開発は損失を管理することです。また、その損失に対して最大限のビジュアル効果を得るために、「この作業がどのような影響を与えているのか?」を理解することが大事です。

レンダリングの大まかな流れ

*この記事はディファードレンダリングに焦点を当てています

RealtimeRendering_BigPicture

ざっくりというと、ハードドライブ→ RAM → CPU  ⇆  GPUという流れです。


まずは、ハードドライブに情報があるところから始まります(画像左)。

つぎに、この情報がRAM(メモリ)に渡されます。
プロジェクト稼働中はメモリが常に情報を保有しています。メモリだけではなく、情報が渡されるときの帯域幅の理解も大事です。

そのあと、メモリからCPUやGPUに情報が行きます。
メモリから運ばれた情報はCPUで計算され、GPUに移動するなど、行ったり来たりします。それぞれ別のレンダリングの役割がありますが、この間ほぼCPUとGPUは同期しながら動いているので、お互いがお互いのボトルネックになります。そのため、GPUが重たすぎる場合、いかにCPUの効率が良くてもプロジェクトは重たくなります。この場合、いくらCPUのパフォーマンスをあげても、GPUを改善するまでプロジェクトは問題を抱えたままです。正しく最適化するには問題がどこにあるか突き止めるのが先です。

レンダリングの流れを細かく

レンダリングの前に

レンダリングの前には、準備があります。GPUから実際にレンダリングが始まります。

rendering-threads

1. CPU

CPUとGPUは同じスピードで処理が行われかつ同期していますが、ますはCPUのスレッドが最初に稼働します。レンダリングが始まる前に、オブジェクトが「どこにあるか・どういった状態か」を調べます。

2. ドロー(主にCPU)

CPUにて調べられた情報を受け取り、「なにを表示するか」を決定します。受け取った情報をすべてレンダリングすると重すぎるためです。そのためオブジェクトごとに、以下の計算が行われます。上から順に計算が行われます。簡単な計算を先に行い計算の必要なオブジェクトを少なくしたあとで、最後に一番重い計算を行います。

  • ① Distance Culling: 距離に応じてオブジェクトを消す
  • ② Frustum Culling: 写っていないオブジェクトを消す
    › 常にon設定
  • ③ Precomputed Visibility: オブジェクトを範囲ごとに指定
    › 使いどころが難しい。CPUの効率は上げるが、メモリが重くなる。設置するVolumeのひとつひとつに情報を蓄える必要があるため。
  • ④ Occlusion Cullung: オブジェクトがみえるかの最終確認
    › 確認が必要なオブジェクトの個数が10000個を超えると重たくなりがち

3. GPU

これで事前準備が整ったので、ここから実際のレンダリングが始まります。ジオメトリのレンダリングです。ドローコールごとに計算が行われます

ドローコールとは

ドローコールがなにを指すのかの理解はとても大事です。あやふやな方はこちらの記事を参考にしてください。

レンダリング開始

さきほど準備完了したジオメトリの情報を取得しながら、レンダリングが開始されます。マテリアルの設定によって、DepthPassがピクセルシェーダーの前か後に行われますが、以下の順番でレンダリングされます、

バーテックスシェーダー ⇨ ラスタライズ ⇨ G-buffer ⇨ ピクセルシェーダー(ライティングやシャドウなど) ⇨ ポストプロセス

1. バーテックスシェーダー(GPUのみ)

バーテックスシェーダー(Vertex Shader)は、風に揺れるアニメーションなどで使われます。
頂点をオフセットしているだけで実際にはモデルを変形しておらず、 CPUでは処理されません。この動画の雲が揺れているアニメーションも頂点をオフセットしているだけです。そのため、コリジョンなどは元のモデルの位置で計算されます。かなり最適化されているので、パフォーマンスはいいです。

2. ラスタライズ

ドローコールごとに行われる処理で、3Dデータをピクセルに変換する計算のことです。バックグラウンドで実行されており、コントロールすることはできません。その意味ではそこまで重要ではありません。

3. G-Buffer

G-bufferとは、レンダリングする複数の画像のことで、ラスタライズ後に行われます。ラスタライズと合わせて、この過程ををBassPass呼びます。重要なレンダリングの基礎となる部分です。これらの画像はマテリアルやライティングなどの合成に使われます。ジオメトリから情報を受け取るのはここまでで、これ以降の処理はすべてこのG-bufferを使います。簡単にいうと、フォトショでフィルターを使うような作業になります。
グラフィックメモリ ( vRAM )と帯域幅を多く使います。

4.ピクセルシェーダー

ジオメトリのレンダリングとそれに伴うドローコールと並んで、パフォーマンスに大きな影響を与えるのがこの部分になります。ただトピックが多く長くなりすぎてしまうので、それぞれについて別の記事で説明したいと思います。

ポストプロセス

名前の通り、プロセスの最後に行われる視覚効果のことです。
ピクセルシェーダーの処理を使ったり、GBufferを再利用して合成したりします。これもカバーするトピックが多いので、具体例を含めた解説を別でまとめます。以下を予定しています。

  • › ポストプロセスでグレインエフェクトを作る
  • › ポストプロセスマテリアルを使ったスタイライズドフィルター
参考:Rendering Master by Sjoerd De Jong at Unreal Academy