Version: 2020.1
ディファードシェーディングレンダリングパス
Vertex Lit レンダリングパス

古いディファードレンダリングパス

このページでは、 Unity のビルトインレンダーパイプラインの古いディファード (ライトプレパス) レンダリングパス を説明します。ディファードライティングの技術的な概要については こちらの記事を参照してください。

ノート: 古いディファードレンダリングパスは、レンダリングの一部の機能 (例えば、スタンダードシェーダー、リフレクションプローブなど) をサポートしていないため、Unity 5.0 で開始した旧式の機能と考えられています。新しいプロジェクトでは代わりに ディファードシェーディング レンダリングパスの使用を検討するべきです。

ノート: 平行投影を使用している場合は、ディファードレンダリングはサポートされません。カメラの投影モードが平行投影に設定されている場合は、カメラは常にフォワードレンダリングを使用します。

概要

ディファードライティングを使用する場合、オブジェクトに影響を与えることができるライトの数に制限はありません。すべてのライトは、ピクセルごとに評価されます。つまり、それらがすべて法線マップ等と正しく相互作用することを意味します。さらに、すべてのライトは、クッキーと影を設定することができます。

ディファードライティングには、ライティングの処理オーバーヘッドはライトが照らすピクセル数に比例するという利点があります。これはオブジェクトを照らす数に関係なく、シーンの中のライトのボリュームのサイズによって決定されます。したがって、パフォーマンスは、ライトを小さくすることによって向上します。また、ディファードシェーディングは非常に一貫性のある予測可能な動作をします。ライトの効果はピクセルごとに計算されるので、大きな三角形でライティングの計算に失敗してしまうことはありません。

不利な面は、ディファードシェーディングは、アンチエイリアスのための実際のサポートがなく、半透明のオブジェクトを処理できないことです (これらは、フォワードレンダリングを使用します)。さらに、メッシュレンダラーの Receive Shadows (影を受ける) フラグは限られた範囲でサポートされ、カリングマスクは 4 つまでに限られています。つまり、カリングレイヤーマスクには、すべてのレイヤー数から 4 つの任意のレイヤーを引いた数のレイヤーが含まれます。よって、32 レイヤーなら 28 レイヤーを設定しなければなりません。そうでないと、グラフィックスのアーティファクトが発生します。

要件

深度レンダーテクスチャと 2 面ステンシルバッファをサポートした、Shader Model 3.0 (またはそれ以降) のグラフィックスカードが必要です。 GeForce FX 以降のもの、Radeon X1300 以降のもの、Intel 965 / GMA X3100 以降のものなど、2004 年以降に製造された多くの PC 用グラフィックスカードは ディファードライティングをサポートしています。モバイルに関しては、すべての OpenGL ES 3.0 対応 GPU は、ディファードライティングをサポートします。 いくつかの OpenGL ES 2.0 対応のモバイルもディファードライティングをサポートしています (深度テクスチャをサポートしているモバイル)。

パフォーマンスの考慮点

ディファードライティングでは、リアルタイムライトのレンダリングのオーバーヘッドは、ライトが照らすピクセル数に比例し、シーンの複雑さには依存しません 。そのため、小さな点やスポットライトをレンダリングするのは非常に負荷が軽く、それらが全部、または、部分的にシーンのオブジェクトによっておおわれる場合、さらに負荷が軽くなります。

もちろん、影のないライトよりも影のあるライトがはるかに高価です。ディファードライティングでは、影を投影するオブジェクトは、影を投影するライトごとに 1 回以上レンダリングされる必要があります。さらには、影を適用するライティングシェーダーは、影を無効化した場合と比べて、レンダリングオーバーヘッドが大きくなります。

実装に関する詳細

ディファードライティングが使用されるとき、Unity でのレンダリングプロセスは 3 つのパスで行われます。

  1. ベースパス: オブジェクトがレンダリングされ、深度、法線、スペキュラーでスクリーンスペースのバッファを生成します。
  2. ライティングパス: 先に生成されたバッファを使用して、別のスクリーンスペースのバッファにライティングを計算します。
  3. 最終パス: オブジェクトは再度レンダリングされます。計算されたライティングを収集し、カラーテクスチャと合成して、環境/発光のライティングを追加します。

ディファードライティングをハンドリングできないシェーダーをもつオブジェクトは、このプロセスが完了した後に、フォワードレンダリングパスでレンダリングされます。

ベースパス

ベースパスでは各オブジェクトを 1 回レンダリングします。ビュー空間の法線とスペキュラーの強さは 1 つの ARGB32 レンダーテクスチャにレンダリングされます (法線は RGB チャネル、スペキュラーの強さはアルファチャネル)。プラットフォームとハードウェアが Z バッファをテクスチャとして読み込める場合は、深度は明示的にレンダリングされません。Z バッファがテクスチャとして読み込まれない場合、深度は シェーダーの置き換えによって別のレンダリングパスでレンダリングされます。

ベースパスの結果として、シーンのコンテンツを満たした Z バッファと、法線マップとスペキュラーの強さを含むレンダーテクスチャが生成されます。

ライティングパス

ライティングパスは深度、法線マップ、スペキュラーの強さにもとづいてライティングを計算します。ライティングはスクリーン空間で計算されるため、処理にかかる時間はシーンの複雑さとは無関係です。ライティングバッファは 1 つの ARGB32 レンダーテクスチャで、ディフューズライティングを RGB チャネル、モノクロのスペキュラーライティングをアルファチャネルに含みます。ライティングの値は対数的にエンコードされ、ARGB32 テクスチャで通常可能であるレンジより範囲が広いダイナミックレンジを提供します。カメラで HDR レンダリングが有効のときには、ライティングバッファは ARGBHalf フォーマットで、対数エンコードは行われません。

カメラのニアクリップ面を横切らないポイントライトとスポットライトは、シーンに対して深度テストを有効にして 3D シェイプ (の前面) としてレンダリングされます。ニアクリップ面を横切るライトは 3D シェイプも使用してレンダリングされますが、代わりに逆深度テストによって背面としてレンダリングされます。これにより、一部またはすべて塞がれたライトの描画の負荷をとても低くすることができます。ライトがカメラのファークリップ面とニアクリップ面の両方を同時に横切ってしまう場合、上記の最適化を使用することはできず、ライトは深度テストなしのいびつな四角形として描画されます。

上に説明したものはディレクショナルライトには適用されず、常にフルスクリーンの四角形としてレンダリングされます。

ライトの影が有効化されている場合、それらもレンダリングされパスに適用されます。影にも負荷がかかることに注意してください、シャドウキャスター (影の投影元) もレンダリングされる必要があり、より複雑なライトシェーダーも適用する必要があります。

唯一利用可能なライティングモデルは Blinn-Phong です。別のモデルを使用したい場合はライティングパスシェーダーを自ら修正することが可能で、Built-in Shader から取得した Internal-PrePassLighting.shader ファイルの修正バージョンを Assets フォルダー配下の Resources フォルダーに格納します。そして、Edit->Project Settings->Graphics のメニューから Graphics (グラフィックス) を開き、“Legacy Deferred” のドロップダウン リストから “Custom Shader” を選択します。次に、使用しているライティングシェーダーに表示されるシェーダーオプションを変更します。

最終パス

最終パスは最終的なレンダリング画像を生成します。ここで、ライティングを収集するシェーダーによりすべてのオブジェクトは再びレンダリングされ、テクスチャと合成し、エミッシブなライティングを加えます。ライトマップも最終パスで適用されます。カメラの近くでは、リアルタイムライティングが使用され、ベイクした間接光のみが加えられます。これはカメラから離れた場所にある完全にベイクされたライティングとクロスフェードします。

ディファードシェーディングレンダリングパス
Vertex Lit レンダリングパス