Unreal Engine でのレンダリング

ゲーム エンジンでのレンダリングの概要
レンダリングとは、シーンのオブジェクトのコレクションから画面の最終画像 (フレーム) を生成するプロセスを指します。
フレームのレンダリングに使用するソフトウェアは レンダリング エンジン と呼ばれ、これらのエンジンは通常、次のように分類されます。
-
オフライン レンダリング:処理時間より品質を優先する高品質のレンダリング向けの設計となっています。オフライン レンダリングは通常、レンダリングされる最終フレームの品質と比較してレンダリング時間が重要ではないアプリケーションで使用されます。
-
リアルタイム レンダリング:パフォーマンスを念頭に置いた設計となっており、フレームをすばやくレンダリングします。一般的なリアルタイム フレーム レートのターゲットは、1 秒あたり 30 (33ms)、60 (16ms)、120 (8ms) フレーム (FPS) ですが、フレーム レートは要因の数によって時間とともに変化する可能性があります。リアルタイム レンダリングを使用して開発するプロジェクトでは、一貫したフレーム レートを維持するためにパフォーマンスと品質のバランスを見つける必要があります。リアルタイム レンダリング エンジンは通常、ビデオ ゲーム、シミュレーション、建築ビジュアライゼーションなどのインタラクティブ メディアで使用されます。
Unreal Engine は、モバイルから強力なデスクトップ コンピュータまでの各種プラットフォームのニーズに対応する、リアルタイム レンダリング向けに設計された強力なツール スイートです。Unreal Engine は、高品質のリアルタイム レンダリングとオフライン レンダリングの両方に対応しています。Unreal Engine を使用すれば、モバイル、コンソール、デスクトップ プラットフォームでのインタラクティブな 2D 体験や 3D 体験から、映画制作やテレビ制作における最終フレームのレンダリングまで、あらゆるものを作成できます。
市場の他のリアルタイム エンジンとは異なり、Unreal Engine は、特にリアルタイムとパフォーマンスを念頭に置いて設計された数多くの独自機能を備えています。その目標は、開発を簡素化するとともに、高い品質とパフォーマンスを維持しながらすばやく結果を得ることにあります。
Lumen グローバル イルミネーションおよび反射 システム、Nanite 仮想化ジオメトリ、仮想シャドウ マップ などの機能は、コンソール アプリケーションとデスクトップ アプリケーション「のみで役に立つ」機能でこのような開発を簡素化するという目標を達成するうえでの重要なステップとなります。モバイル プラットフォームは、ライティングをテクスチャにベイクする必要がある動的ライティングと事前計算されたライティングのワークフローをサポートします。
Unreal Engine でのレンダリングの概要
ゲーム エンジンは、レンダリング パイプライン と呼ばれることが多い一連のステップを実行して画像 (またはフレーム) を画面にレンダリングします。このセクションでは、Unreal Engine でデフォルトのディファード レンダリング パスを使用してこのような処理を行う方法について説明するとともに、必要に応じてこれらのステップと Unity のディファード レンダリング パスを比較します。
Unity Engine には、ビルトイン、ユニバーサル、高解像度という 3 つの独自のレンダリング パイプラインが用意されています。各パイプラインは特定のユース ケース向けの設計となっており、通常は新しいプロジェクトを開始する前に選択されます。
Unreal Engine には、ハンドヘルド デバイスやモバイル デバイスから現行世代のコンソールや PC まで、ターゲット プラットフォームに基づいて各機能を拡張する 統合レンダリング パイプライン が用意されています。そのため、単一のパスに制限されることなく、プロジェクトに最適なレンダリング パスとサポート対象機能を選択できます。
Unreal Engine のレンダリング パイプラインは、デフォルトの ディファード レンダリング パスで使用することも、フォワード レンダリング パスで動作するように設定することも可能です。さらに、モバイル レンダリング パスを有効にして、Vulkan モバイル レンダラ などの低電力デバイスに対応することもできます。各レンダリング パスでサポートされるレンダリング機能の詳細については、レンダリング パスでサポートされる機能 に関するドキュメントを参照してください。
以下の画像は、Unreal Engine が ディファード レンダリング パスを使用して各フレームを実行し、最終画像をレンダリングするステップの概要をビジュアル化したものです。

このプロセスは左から順に進められ、ステップ 2 ~ 5 は同時に実行されます。
レンダリング パイプラインの各ステップと各フレームのレンダリングの手順の詳細については、以下をご覧ください。
シーンの準備とオクルージョン

Unreal Engine には、ゲーム (CPU)、描画、GPU スレッドという 3 つのプライマリ スレッドがあります。
ゲーム (または CPU) スレッドは、レンダリング プロセスを開始する前にシーンのすべてのオブジェクトのトランスフォームを収集します。これには、各オブジェクトの最終トランスフォームを収集する前のすべてのアニメーション、物理シミュレーション、人工知能 (AI) の処理が含まれます。
その後、トランスフォームの情報は CPU の 描画 スレッドに渡されます。描画スレッドは、現在のカメラ ビューの可視オブジェクトのリストをビルドし、カメラに映っていないその他すべてのオブジェクトを削除する カリング プロセス を実行します。これらのオブジェクトは描画する必要がなく、レンダリングしなければパフォーマンスが向上します。
このプロセスでは、次のステップが (順に) 実行されます。
- 距離カリング:カメラから特定の距離以上離れているすべてのオブジェクトを削除します。
- 錐台カリング:カメラの錐台 (ビュー) 内に表示されていないオブジェクトを削除します。
- オクルージョン カリング:シーンの残りすべてのオブジェクトの可視性ステートを正確にチェックします。この方法は負荷が高いため、残りの可視オブジェクトが他のオブジェクトによってオクルードされる (隠れる) かどうかを確認するためのさらなるテストが行われる、オクルージョン プロセスの最後に実行されます。
可視オブジェクトの最終リストは、レンダリング プロセスを開始するために GPU スレッド に渡されます。
Unity の場合
Unity は、レンダリング パイプラインの中で 錐台 および オクルージョン カリング を実行します。さらに、CullingGroup API を使用することで距離カリングを実行できます。これらの手法を組み合わせることにより、シーンの可視オブジェクトの最終リストが作成されます。
ジオメトリ レンダリング

このステップでは、Unreal Engine がシーンの可視オブジェクトのリストを確認し、3D 頂点データを画面上に表示されるピクセル データに変換する次のステップに向けてそれらのオブジェクトを準備します。
頂点シェーダー
シェーダーは、GPU で直接実行され、一連の計算を行うために使用されるコードです。シェーダーは効率に優れており、GPU は多数のシェーダーの計算を同時に実行できます。
頂点シェーダーは、次のプロセスを実行します。
- ローカルの頂点位置をワールド位置に変換:オブジェクトの頂点データはローカル空間に格納されますが、オブジェクトがワールドに配置されると、頂点情報はワールド空間の座標に変換される必要があります。
- 頂点のシェーディングとカラーリングを処理:頂点シェーダーは、オブジェクト自体の頂点カラー データだけでなく、頂点のスムージングも処理します。
- 場合によって追加のオフセットを頂点位置に適用:頂点シェーダーは、特定のエフェクトを得るために画面上の頂点の位置をオフセットすることがあります。これはオブジェクトのマテリアルを通じて行われ、ワールド位置オフセットと呼ばれます。
深度パス
Unreal Engine は、各オブジェクトをレンダリングする前に 深度パス (早期 Z パス) を実行し、それぞれのオブジェクトとの関連でオブジェクトの位置を決定します。これにより、Unreal Engine が画面上で同じピクセルを複数回レンダリングしてしまう状況を回避します。これは オーバードロー と呼ばれ、パフォーマンスに大きな影響を及ぼす可能性があります。このエンジンは、可能な限りこれを回避しようとします。
ドローコール
深度パスの後、GPU は、メッシュやマテリアルなどの同じプロパティを共有するすべてのポリゴンを同時に描画して各オブジェクトをレンダリングします。これは ドローコール として知られています。
同じマテリアルを割り当てられたオブジェクトのすべてのポリゴンは、同じドローコールとしてカウントされます。ただし、一意のマテリアルには、それぞれ別のドローコールが必要です。たとえば、画面上の各オブジェクトに対してはドローコールを少なくとも 1 回実行する必要がありますが、オブジェクトに割り当てられたマテリアルの数によってドローコール数が多くなることがあります。
Unreal Engine の Nanite 仮想化ジオメトリ は、特定のマテリアルですべてのオブジェクトのすべてのポリゴンを同時にレンダリングします。フレーム バジェットは、ポリゴン数、ドローコール数、メッシュ メモリ使用量の制限を受けなくなりました。
Unity の場合
Unity のレンダリング パイプラインでは、深度パスを行い、ドローコールを使用してシーンのオブジェクトを描画する、同じようなステップが実行されます。
ラスタライズとジオメトリ バッファ

ラスタライズ プロセス では、3D 頂点データを画面上に表示される 2D ピクセル データに変換します。このプロセスは、頂点シェーダーが実行され、そのデータのすべてが処理された後に始まります。
Unreal Engine の ジオメトリ バッファ (GBuffer) には、シーンのジオメトリに関する情報を格納する一連の画像が含まれます。これらの画像には通常、シーンの ベース カラー、ワールド法線、メタリック、ラフネス、スペキュラ のライティング情報などが含まれます。これらの GBuffer の画像は、画面上に表示される最終画像を作成するために構成されます。
これらの構成された画像を変換するプロセスは、レンダリングされる各フレーム、および頂点データがピクセル データに変換され、GBuffer への画像の正しいパーツを描画する各ドローコールに対して実行されます。
Unity の場合
Unity のディファード レンダリング パスでも GBuffer を使用してシーンに関する重要な情報を格納します。Unity の場合、GBuffer は、オブジェクトのアルベド、スペキュラ、法線、エミッシブ / ライティング情報など、(別の名前で参照される) シーンに関する同様の情報を格納します。
テクスチャのレンダリング

Unreal Engine は、テクスチャ ストリーミング を使用してテクスチャをレンダリングし、シーンへのテクスチャのロードを最適化します。テクスチャ ストリーミング システムは、テクスチャ ミップマップ を使用します。これらは、解像度の異なる同じテクスチャの事前に計算された画像のシーケンスです。これに関しては、メッシュではなく、テクスチャの 詳細度 (LOD) のようなものだと考えることができます。このエンジンは、各画像の解像度が以前の画像の半分になるこれらのミップマップを自動的に作成します。
Unreal Engine は、カメラからの距離に基づいてゲームプレイ中にテクスチャのミップマップをストリーミングします。これは、帯域幅とメモリ消費を最適化するとともに、カメラから離れた場所のノイズを低減するために自動的に実行されます。
テクスチャのサイズは、ミップマップを受け取れるように 2 の乗数に設定する必要があります。一般的なテクスチャ サイズには、3840 x 2160 ピクセル (4K) と 1920 x 1080 ピクセル (HD) があります。なお、テクスチャを特定の比率にする必要はなく、1920 x 480 ピクセルのテクスチャでもミップマップを受け取れます。
Unity の場合
Unity の ミップマップ ストリーミング システムでは、テクスチャ ミップマップを使用してランタイム時にテクスチャをストリーミングします。Unreal Engine と同じように、このシステムはカメラからの距離とカメラに対する角度に基づいて適切なテクスチャ ミップマップを自動的にストリーミングします。
ピクセル シェーダーとマテリアル

オブジェクトが GBuffer に完全にレンダリングされると、Unreal Engine は、各オブジェクトのマテリアル プロパティとピクセル シェーダーを使用して画面上の各オブジェクトのシェーディングを開始します。
ピクセル シェーダー は、画面上のピクセルの色を変更するための一連の計算を実行します。ピクセル シェーダーは GPU で実行され、非常に効率に優れています。Unreal Engine の マテリアル システム を駆動し、ライティング、フォグ、反射、ポストプロセス エフェクトを計算するときに使用されます。
マテリアル システムは、マテリアル エディタ とともにハイレベル シェーダー言語 (HLSL) のシェーダー テンプレートを使用して、画面上のオブジェクトに適用される最終マテリアルを作成します。これらのマテリアルは、テクスチャなどのパラメータを使用して各オブジェクトの外観を定義できます。
Unity の場合
Unity には、プロジェクトのシェーダーを作成するための Shader Graph と (Unreal Engine のマテリアルに相当する) いくつかの事前ビルド済みシェーダーが装備されています。Unreal Engine のマテリアル エディタは、Unity の Shader Graph に相当します。
反射

シーンのすべてのオブジェクトをシェーディングすると、Unreal Engine はマテリアル プロパティに基づいてオブジェクトの反射のレンダリングを開始します。
Unreal Engine は、4 つのシステムを使用してシーンに反射をレンダリングします。これらのシステムは、次の順序で実行されます。
- 反射キャプチャ:事前に計算され、特定の位置のスタティック キューブマップに格納されます。
- 平面反射:平面との間の反射をキャプチャします。
- スクリーン空間反射 (SSR):使用可能な画面情報を使用してオブジェクトの正確な反射をリアルタイムで描画します。
- Lumen 反射:シーンのあらゆるラフネス値の反射に対処します。これらの反射には、スカイライト、クリア コート マテリアル、透過、さらには単一レイヤーの水マテリアルのサポートが含まれます。
Unreal Engine は、3 つのメソッド間でブレンドし、スクリーン空間反射を優先してから平面反射にフォールバックした後、最後に反射キャプチャにフォールバックします。最終的な反射の結果は、GBuffer のラフネス、スペキュラ、メタリック画像と組み合わせられます。
Lumen グローバル イルミネーション を使用している場合は、自動的に Lumen 反射が使用されます。ただし、Lumen GI なしで Lumen 反射を使用することもできます。その場合、Unreal Engine は Lumen 反射でベイクされたライティングを使用します。
Unity の場合
Unity の 反射プローブ は同じような機能を備えており、シーンの反射データの事前計算に使用されます。
静的ライティングおよびシャドウ

反射がレンダリングされると、Unreal Engine はシーンのすべてのオブジェクトの静的ライティングおよびシャドウをレンダリングします。
Unreal Engine は、Lightmass グローバル イルミネーション システムを使用してシーンのライティング情報を事前計算します。ライティングおよびシャドウ情報は ライトマップ UV テクスチャ に格納され、このテクスチャは、シーンのオブジェクトをレンダリングするときにオブジェクトのベース カラーとブレンドされます。
このシステムは非常に高速ですが、必要なメモリが多く、シーンが変更されるたびに事前に計算する必要があります。
Lightmass グローバル イルミネーション システムは、モバイル デバイスや低電力デバイスをターゲットとするプロジェクトに適したオプションです。
Unity の場合
Unity の プログレッシブ ライトマッパー システムと Enlighten によるベイクしたグローバル イルミネーション システムは、シーンのライティングを事前に計算するときに同じような機能を提供します。
動的ライティングおよびシャドウ

静的ライティングがレンダリングされると、Unreal Engine は、動的グローバル イルミネーション システムである Lumen を使用して動的 (リアルタイム) ライティングおよびシャドウをレンダリングします。
Lumen は、次世代のコンソールとハイエンド PC 向けに設計された、完全に 動的なグローバル イルミネーション および 反射 システムです。このシステムは、複数のレイ トレーシング手法を用いてグローバル イルミネーションと反射に大規模に対処します。
Lumen は無限のディフューズ バウンスを提供し、Nanite 仮想化ジオメトリ とシームレスに連携します。さらに、このシステムは 仮想シャドウ マップ と連携して高解像度のリアルタイム ソフト シャドウを作成します。
Lumen は、シーンのあらゆるラフネス値の反射に対処する Lumen 反射 を提供します。これらの反射には、スカイライト、クリア コート マテリアル、透過、さらには単一レイヤーの水マテリアルのサポートが含まれます。
Lumen は、Unity における Screen Space Reflection に相当する機能です。
Unity の場合
Unity は、Enlighten リアルタイム グローバル イルミネーション を使用してシーンで動的ライティングを提供します。このシステムは、ライトマップとともに事前計算された可視性情報を使用してランタイム時に間接ライトのバウンスを計算することにより、リアルタイム グローバル イルミネーションを提供します。
Lumen は間接ライトのバウンスを提供するために事前計算されたデータを必要としないため、この点は Lumen と異なります。
フォグと透過

動的ライティングおよびシャドウをレンダリングすると、Unreal Engine は次にフォグ エフェクトと透過エフェクトをレンダリングします。
Unreal Engine は、カメラからの高さと距離に基づいてフォグ密度をレンダリングする、指数関数的高さフォグ システムを使用して フォグ エフェクト をレンダリングします。さらに、このシステムは ボリュメトリック フォグ を生成できます。
透過オブジェクトは 半透明マテリアル を使用し、プロセスのこの段階でレンダリングされます。Unreal Engine は、ディファード レンダリング パスを使用するときに GBuffer で提供される情報を使用して透過をレンダリングします。また別の方法として、フォワード レンダリング パスを使用してより正確な透過エフェクトを生成するようにマテリアルを設定できます。
Unity の場合
Unity は、シーンの 線、指数、指数 2 乗 フォグをサポートします。
ポスト プロセス エフェクト

フォグと透過がレンダリングされたら、Unreal はイメージに追加エフェクトを適用できます。これらのエフェクトは、最終イメージの処理後に適用されるため ポスト プロセス エフェクト と呼ばれます。このエフェクトはピクセル シェーダーに依存し、GBuffer で提供される情報を使用します。
一般的なポスト プロセス エフェクトとしては、ライト ブルーム、被写界深度、ライト シャフト、トーンマッピング、モーション ブラーなどがあります。
このポスト プロセス ステップの一環として、Unreal Engine は テンポラル スーパー解像度 (TSR) を適用できます。TSR は、Unreal Engine が美しい 4K 画像をレンダリングするために使用する、プラットフォームに依存しない テンポラル アップスケーラー です。高い負荷のかかるレンダリングの計算を多数のフレームに分散することにより、少ない負荷で画像をレンダリングできます。
レンダリング チェーンでは、テンポラル スーパー解像度は被写界深度の後で処理され、それに続くモーション ブラー、ブルームなどのすべてがアップスケーリングされます。

GBuffer にこれらのエフェクトが適用されると、Unreal Engine は画面に最終画像をレンダリングします。
前述のステップでは、画面に対して 単一フレーム が生成されます。これらのステップは、多くの場合、ゲームのターゲット フレームレートに応じて 1 秒間に 30 ~ 60 回繰り返されます。
Unity の場合
Unity では、選択したレンダリング パイプラインに基づいたポスト プロセス ソリューションが用意されます。利用可能なエフェクトの多くは、Unreal Engine で利用可能なエフェクトと似ています。
さらに Unity 6 には、空間およびテンポラル アップサンプリング手法を使用して高品質のアンチエイリアス画像を生成するソフトウェアベースのネイティブ スケーラーである、Spatial-Temporal Post-processing (STP) が備わっています。
Unreal Engine のレンダリング機能の概要
Unreal Engine で画面にフレームをレンダリングするステップについて理解したら、このエンジンに備わっている特定のレンダリング機能の詳細をご確認ください。
Unreal Engine のレンダリング機能の詳細については、環境のライティング に関するドキュメントを参照してください。