プロのライティングには、シーンのムードづくりと、ターゲットとなるプラットフォームの性能や技術的な限界との間で、微妙なバランスをとることが求められます。この記事では、Steven Cannavan が Unity 2021 LTS のユニバーサルレンダーパイプライン(URP)を使ったライティングに関するヒントを紹介します。
ゲーム開発業界で 15 年の経験を持つベテランで、Accelerate Solutions - Games チームのシニア開発コンサルタントである Steven は、Unity のスクリプタブルレンダーパイプライン(SRP)を専門に扱っています。彼は最近リリースされた e ブック「Introduction to the Universal Render Pipeline for advanced Unity creators」への主要な貢献をした 1 人でもあります。この e ブックはこちらのページで入手することができます。この記事の続きでご紹介するヒント(その他にも多数)は、フルバージョンのガイドでご覧いただけます。
まず、主要な設定項目を見てみましょう。まず、URP のグローバルライティング設定の大部分は、ユニバーサルレンダーパイプラインのアセット(URP アセット)にあります。
これらの設定を表示するには、プロジェクトウィンドウで URP アセットを選択し、インスペクターを開いてください。レンダラー固有の設定を調整するには、プロジェクトウィンドウでレンダラーアセットを選択し(例:URP ユニバーサルレンダラー)、インスペクターでそのレンダラーの設定を調整します。
ライトレイヤーの名前を調整するには、Edit メニューを開き、Project Settings > Graphics > URP Global Settings を選択してください。シーンの設定を変更するには、Lighting ウィンドウ(Window > Rendering > Lighting)にアクセスします。
URP アセットには、ライティングに影響を与える複数の設定があります。それは Lighting と Shadows セクションで扱われますが、さらに一部の設定はインスペクターの Rendering、Quality、および Post-procesisng セクションにも表示されます。
ダイナミックレンジのプロパティは、Unity が輝度をどのように保存するかを決定します。この輝度データを利用して、トーンマッピングやポストプロセッシングを行うと、リアルなエフェクトを得ることができます。
ハイダイナミックレンジ(HDR)を有効にするには、インスペクターで URP アセットを開き、Quality 設定を展開し、HDR プロパティを有効にします。HDR がアクティブでない場合、URP はデフォルトでローダイナミックレンジ (LDR)を使用します。たいていの場合、HDR を有効にしておけば最高の品質を維持できます。
HDR が無効だと、ライティングの結果やその他のエフェクトが 0.0 ~ 1.0 の輝度範囲に制限されたものになります。LDR は、パフォーマンスと帯域幅のメリットが期待できる反面、視覚的な忠実度に影響を及ぼします。
HDR が有効になっていると、URP は 1.0 より大きい(輝度の)値をサポートする中間テクスチャにレンダリングします。これらの値は高い輝度を表し、ポストプロセッシングと組み合わせることで、よりリアルなビジュアルを作り出したり、カメラエフェクトをシミュレーションしたりすることができます。レンダリングプロセスの最後に、URP は HDR コンテンツを LDR フォーマットに解決します(ポストプロセッシング中または最終ビットマップ転送中)。URP は、ポストプロセッシング時にトーンマッピングを適用することも可能です。
すべてのプラットフォームが HDR の出力をサポートしているわけではないので、LDR への解決は必要です。例えば URP は、HDR コンテンツを表示できるプラットフォームでの HDR の出力に対応していません。
注:HDR ディスプレイのサポートは、Unity 2022 LTS の URP で PC およびコンソール向けに提供される予定です。
プロジェクトに最適なダイナミックレンジの選び方は、そのプロジェクトのアートスタイル、およびパフォーマンスについて考慮する事柄が何かによって異なります。リアルなビジュアルが必要なプロジェクトや、明るいところと暗いところの差をくっきり出したい場合は、HDR が最適です。しかし、LDR もより単純なライティングやスタイル化されたライティング、およびブルームのような高レンジのポストプロセッシングエフェクトを必要としないプロジェクトでは良い選択となりえます。
上に示した RenderDoc 画像では、鏡面反射と HDR スカイボックスがあるために、0.0 ~ 1.0 の範囲外の領域があります。最終版の画像では、これらがブルームに寄与し、よりリアルなシーンを作り出します。
HDR はパフォーマンスにも影響します。HDR のシステムリソースの必要量は、使用するテクスチャフォーマットと、画像を表示可能な形式に変換するために URP が実行しなければならない追加のステップによって決まります。
浮動小数点数テクスチャフォーマットは一般的にサイズが大きいため、必要なメモリや帯域幅も大きくなります。フォーマットのサイズが大きくなればなるほど 1 ピクセルあたりのビット数が増え、ひいては処理するためのメモリや電力も大きくなります。ローエンドのデバイスでは、オーバーヒートする可能性につながり、問題となります。この問題を解決するために、URP はB10G11R11_UFloatPack32 API フォーマットを使用しようとします(プラットフォームがこれをサポートしており、preserveFramebufferAlpha が無効な場合)。このフォーマットの帯域幅リソースへの要求水準は LDR と同様です。
画面解像度 | フォーマット | レンジ | 1 ピクセルあたりのビット数 | サイズ(MB) |
---|---|---|---|---|
1920x1080 | R16G16B16A16_SFloat | HDR | 64 | 15.82 MB |
1920x1080 | B10G11R11_UFloatPack32 | HDR | 32 | 7.91 MB |
1920x1080 | R8G8B8A8_UNorm | LDR | 32 | 7.91 MB |
1920x1080 | R8G8B8A8_SRGB | LDR | 32 | 7.91 MB |
注:R16G16B16A16_SFloat はアルファをサポートし、青チャンネルの精度低下による変色がないなど、32 ビット版と比較していくつかの利点を備えています。そのため、Unity2022.2 以降では、高精度のテクスチャを使用するかしないかを手動で設定することができます。
URP アセットの Lighting セクションで、Main Light と Additional Lights の両方の設定を変更することができます。Main Light は、シーンで最も強いディレクショナルライトです。Additional Lights は、残りのディレクショナル、スポット、ポイントの各種ライトです。シーンにはこれらのライトを多数置くことができますが、画面上に表示できる数や Forward Renderer パスの Per Object Limit に対しては一般的な制限がかかります。
Main Light は、シーンの Lighting 設定(Window > Rendering > Lighting > Environment)で Sun Source として指定したライトか、最も明るいリアルタイムのディレクショナルライトのいずれかです。実際には、これは通常、Render Mode を Auto または Important に設定し、Mode を Mixed または Real-time に設定した場合には、最も明るいディレクショナルライトになります。
Render Mode オプションの Important または Auto を使うディレクショナルライトの明るさは、Color のグレースケール値に、ライトの Intensity を掛け、シャドウイングライト用のモディファイアを掛け合わせたものになります。 すなわち、((Red の値) x 0.3 + (Green の値) x 0.59 + (Blue の値) x 0.11) x (Intensity の値) x (モディファイアの値) となります。
シーンに Not Important のディレクショナルライトしかない場合、URP はライトの Intensity 値を比較し、Main Light となるライトを決定します。しかし、Unity はシャドウイングのライトにモディファイアを使うため、暗いライトが Cast Shadows を有効にしている場合、それより明るいライトよりもその暗いライトを Main Light に選択する可能性があります。
Lighting セクションで、Main Light と Additional Lights の両方のシャドウについて、Altas のサイズを割り当てることができます。Main Light の場合、 この設定は、Main Light がシャドウカスケードに使う Altas URP と、URP アセットの Shadows セクションの設定に影響します。Additional Lights セクションでは、Shadow Resolution のティアを設定することができます。URP は、シャドウを持つすべての可視状態のライトを、その解像度(Custom、High、Medium、Low)に基づいてアトラスに収めようとします。
しかし、URP がこれらのシャドウを希望の解像度でレンダリングするために必要なサイズがアトラスより大きい場合、URP はシャドウを縮小したり、場合によっては完全に除去したりすることがあります。これは、ライトの最小限の解像度(ハードシャドウでは 8x8、ソフトシャドウでは 16x16)に対して十分なスペースがない場合、またはハードウェアの制限を超えた場合に発生します(モバイルの場合)。つまり、多数のライトが見えている場合や、少数のライトがアトラスのかなりの部分を占めている場合(たとえば、ポイントライトはアトラス上で 6 スライスという大きなスペースを必要とします)、パンクチュアルライトのシャドウの質が大きく変わってしまうのです。
これを克服するために、いくつかの戦略があります。
Per Object Limit 設定(Additional Lights の下)は、フォワードレンダラーパスを使って URP がレンダーするオブジェクトに影響を与えられるライトの数を制限します。したがって、ユニバーサルレンダラーがフォワードパスを使う場合、この制限はすべてのオブジェクトに影響します。ディファードパスの場合、この制限はフォワードレンダリングテクニックによるマテリアル(たとえば Complex Lit や Transparent マテリアル)を使うオブジェクトにのみ影響します。
オブジェクトが制限を超える数のライトで照らされた場合、Unity は最も重要でないライトを落とします。オブジェクトの中心の強度とライトの Render Mode の両方を見て、Unity はどのライトを落とすかを決定します。そのため、アーティファクトが目に見える形で出てくることがあります。
オブジェクトを照らすライトの数の上限を上げるとこの状況は改善されますが、その上限は 8 までしか上げられません。またローエンドのデバイスでは、パフォーマンス上の理由から、普通はそれより低い上限を設定することが望ましいとされています。ほとんどのプロジェクトでは上記のことは問題にならないはずですが、もし問題になった場合はおすすめの回避策がいくつかあります。
注:Unity 2022.2 以降では、Forward+ Renderer がオプションとして用意されています。あるピクセルに影響を与えることができるライトの数を増やし、Per Object Limit による制限を解除します。
URP は最近、Main Light となるディレクショナルライトに対するライトクッキーのサポートを追加しました。Additional Lights にも同様のサポートがありますが、こちらの場合、ライト間でアトラスを共有する必要があります。このアトラスのサイズは、Additional Lights セクションの Cookie Atlas Resolution と Cookie Atlas Format の設定で制御することができます。
クッキーを持つパンクチュアルライトが可視になると、URP はそれをアトラスに追加します。アトラスに十分なスペースがない場合、URP はクッキーをスケールダウンします。ライトが見えなくなっても、再ビルドが必要になるまで(つまり、アトラス全体のスケーリングファクターが変わるまで)ライトはアトラスに留まります。これは一般的に、URP がほとんどアトラスを更新しないことを意味します。
実際には、URP はスロットが変更されたときのみスロットを更新します。これは、クッキーがレンダーテクスチャ を使っているか、エディターでクッキーのテクスチャを再インポートした場合に発生する可能性があります。クッキーの使用に必要なリソースはほとんどのデバイスで低いはずですが、画像の品質に問題がある場合は、アトラスと個別のライトクッキーの画像の大きさを再検討してください。ライトはすべて同じではありませんし、クッキーのテクスチャも同じです。アトラスの空きを増やすには、重要度が最も低いクッキーのテクスチャのサイズを小さくすればいいのです。
もちろん、クッキーのアトラスのフォーマット にはいくつかのオプションがあります。プロジェクトに最も適したものがどれであるかは、メモリ要件とクッキーのソースになるテクスチャに依存します。
ほとんどの場合、デフォルトのオプションである Color High で十分ですが、他のフォーマットを検討した方が良い場合があります。
注:クッキーもリソースを必要とするため、ローエンドのプラットフォームには適さない可能性があります。もしプロジェクトでクッキーを使用しないのであれば、この追加のリソース要求を避けることができます。
URPは、リフレクションプローブを使うためのいくつかのオプションを提供しています。Unity がプローブを使ってサンプリングをする場合、ブレンデッドプロジェクションプローブ(Blended Reflection Probes) またはボックス投影(Box Projection)テクニックを使用するようプロジェクトを設定することができます。
Blended Probes オプションが有効になっている場合、URP は最大 2 つの個別のリフレクションプローブを評価し、それぞれのプローブからサンプリングします(バウンディングボックスとブレンド距離に基づいて、それがピクセルに十分に影響する場合)。各プローブの合算した重みが閾値の 0.99f を下回る場合、URP はアンビエントプローブも使用します。これは優れた品質の反射を提供しますが、やはりシェーダーのために多くの帯域幅と計算能力を必要とするため、ローエンドのデバイスには適さないかもしれません。
Blended Probes オプションを有効にしたとき使用できるボックス投影テクニックは、URP が反射をサンプリングする方法を変えます。Box Reflection テクニックを無効にすると、URP は反射を、その発生源が無限遠にあるものとして扱います。計算に必要なのは、ピクセルの法線から相対的に求められた カメラ ビューに対する反射ベクトルだけなので、これは安価です。視覚的には、オブジェクトの位置に関係なく同じように反射しているように見えることがあり、狭い密閉されたシーンでは非常に目立つことがあります。
URP アセットでボックス投影を有効にすると、URP のリフレクションプローブの扱い方が変わります。特に、URP は反射を有限なものとして扱い、反射ベクトルをボックスの範囲に対応させるように調整します。この結果、反射はより局所的なものに見えるようになり、同じリフレクションプローブを使用するすべてのオブジェクトは、オブジェクトの位置により正確にマッピングされた反射を受け取ることができます。
この追加リソースはブレンデッドプローブほどは要求されませんが、ボックス投影を使うとシェーダーの複雑さが増し、パフォーマンスに影響を与えます。室内や通りなどの密閉された場所のシーンで使うことをおすすめします。また、鏡のような反射率の高い面に対しても、ボックス投影はより説得力のある結果を提供します。
ビルトインレンダーパイプラインでは、メッシュレンダラーごとにリフレクションプローブを設定することができます。2021.2 バージョンの URP にはこのオプションがありません。これはフォワードとディファードの両方に対する URP の実装によってこの値がアクセス不能になっているためで、これを変更するとリフレクションプローブのブレンディングが壊れてしまうからです。古いプロジェクトを Unity 2021 LTS にアップグレードする場合、アップグレード前に必ずデフォルトの Blend Probes オプションに設定してください。
URP アセットのプロパティで Mixed Lighting と Light Layers を有効にすることができます。デフォルトでは、これらのオプションは表示されません。インスペクターの右上にある 3 点アイコン(⋮)をクリックし、Show Additional Properties を選択して表示するか、Core Render Pipeline 設定(Preferences > Core Render Pipeline)で調整します。
デフォルトでは Mixed Lighting が有効になっています。これは動的ライティングとベイク済みライトが相互に作用するオプションです。シーンでこれを使用するには、Baked Global Illumination を有効にし、Lighting ウィンドウ(Windows > Rendering > Lighting > Scene)で Subtractive または Shadowmask モードを選択し ます。Mixed Lighting を無効にすると、Unity はビルド時に Mixed Lighting を含むシェーダーバリアントをプロジェクトから削除します。
URP の新機能であるライトレイヤーでは、ライトを特定のレンダーレイヤーに設定できます。特定のジオメトリにのみ影響を与えるライトを扱う際に便利です。各ライトは、カスタムのシャドウレイヤーを持つことができます。これはそのライトのシャドウパスからジオメトリを含めたり除外したりするために使われます。
Max Distance はグローバルな設定で、ゲーム内のすべてのシャドウに影響します。Unity がリアルタイムシャドウをレンダリングするために使うカメラからの最大距離を表します。ディレクショナルライトの場合、URP はシャドウマップに影をレンダリングします。Max Distance の値は、カメラの視錐台のうちどのくらいの領域を、またカメラからどの程度の距離までを、マップがカバーあるいはリーチするかを決定します。追加のシャドウは位置を持つので、この距離に基づいてカメラから遠すぎると判定された場合はシャドウパスから除外されます。Unity は、この距離よりも遠くにあるピクセルには影をつけません。
Cascade Count 設定により、Main Light になるディレクショナルライトのカスケードの回数を設定することが可能です。Unity は、カメラに近いシャドウをより詳細に描くために、視錐台をこれらのカスケードに分割し、一方 URP は、カスケードを _MainLightShadowmapTexture にパックします。つまり、Cascade Count を 1 に設定すると、URP はテクスチャ全体を使用します。そうでない場合は、各カスケードがアトラスの 4 分の 1(シャドウの解像度の半分のサイズ)を使用します。
Working Unit オプションにより、URP がカスケード分割に使用する単位を指定することができます。Metric を選択した場合、URP は分割の中に現れる数値をメートルで計測します。一方、Percent は、各分割の Max Distance に対するパーセンテージを表示します。Split フィールドの値を変更することで、手動で分割を調整することができます。あるいは、Last Border プロパティの下にあるインフォグラフィックに、色分けされた分割をドラッグするだけでも調整が行えます。
Last Border プロパティは、Main Light またはシャドウを落とすパンクチュアルライトから影を受けるすべてのピクセルに影響します。Last Border の 値 は、ピクセルが Max Distance に近づいたときに、URP が影をフェードアウトさせる距離(線形フェード)です。
Depth Bias(深度バイアス)と Normal Bias(法線バイアス)の設定は、プロジェクトにおけるデフォルトのバイアスを制御します。Bias 設定を Custom に変更すると、手動でバイアスを設定したり、各ライトを微調整することができます(下のスクリーンショットを参照)。
Conservative Enclosing Sphere オプションを使うと、シャドウの視錐台カリングを改善できます。これを有効にすると、Unity はカスケードがより良くフィットするようにカリングを調整し、シャドウカスケードの隅での過度のシャドウカリングの発生を回避することができます。ただし、この操作で URP がカスケードの選択に使用するバウンディングスフィアのサイズと位置が変わるため、既存のプロジェクトでこのオプションを有効にすると、カスケードの距離の調整が必要になる場合があります。
さらに、シャドウパスで Depth Bias と Normal Bias を使用してパスの結果を変更し、シャドウアクネなどの一般的なシャドウイングに関する問題を解決できます(ドキュメントの影のトラブルシューティングを参照)。Depth Bias は基本的に(正の値に設定すると)シャドウパスでジオメトリをライトから遠ざける効果を持ち、Normal Bias は法線がライトから遠ざかる方向に向くシャドウキャスターを縮小させます。
この調整の効果は URP がシャドウキャスターをライトから遠ざけることでセルフシャドウを軽減することですが、元の境界内にとどまるため、セルフシャドウのバグも軽減することができます。Unity は、URP によるシャドウキャスターの移動の全体量を、視錐台と解像度のサイズに URP アセットまたはライトで設定されたバイアスを掛けたものを基に計算します。
ほとんどの場合、デフォルト値で問題ないはずです。アーティファクトがある場合は、まず適切な値を探し、可能ならば各ライトを個別に調整しましょう。
Soft Shadow オプションは、URP でソフトシャドウをサポートするためのグローバルなオーバーライドです。これを有効にすると、URP はすべてのライトに対してハードシャドウ とソフト シャドウをサポートするようになります。これはシェーダーのパフォーマンスに影響を与えることがあります。そのため、ローエンドのプラットフォームでは、この機能を使用しない Quality Level を追加するのが良いでしょう。
Unity は、URP がシャドウをサポートするシェーダーからピクセルをレンダリングするたびに、シャドウテクスチャ上で複数回(モバイルおよびスタンドアロン型デバイスでは 4 回、その他のプラットフォームでは 9 回)サンプリングする必要があります。つまり、ソフトシャドウは帯域を消費するのです。
複数回サンプリングするということは、キャッシュミスやメモリフェッチが起きる可能性も増し、各ピクセルもわずかながらリソースをより多く必要とするようになります。オーバードローは、こうした帯域幅の要求をさらに高めることになります。そのため、Unity 2022.2 以降では、ライトごとのソフトシャドウの品質(サンプル数)を制御するオプションが用意されています。
Unity は、ユニバーサルレンダラーを使って、URP がシーンをレンダリングする方法を設定します。Rendering セクションには、このアセットが使用するレンダリングパスが含まれ、Forward または Deferred のいずれかを選択できます。
デフォルトのパスはフォワードレンダリングパスです。ハードウェアと URP アセットによって定まる制限内で、特定のオブジェクトに有効なすべてのライティング情報を使い、各オブジェクトをレンダリングします。この制限を超えるレンダリングサポートが必要なプロジェクトでは、ディファードパスの利用を検討します。
ディファードレンダリングパスでは、不透明なジオメトリを G バッファにレンダリングします。Unity は G バッファをディファードシェーディングパスで使用し、可視であるライトを各々レンダリングします。つまり、不透明なマテリアルで、Lit または Simple Lit シェーダーを使用しているオブジェクトは、それらに影響を与えるライトの数が非常に多くなる可能性があることを意味します。Complex Lit や Baked Lit などの一部のシェーダーはフォワードパスのみを使用するため、URP はディファードライティングパスの後にそれらのシェーダーのレンダリングを行います。特筆すべきは、URP はすべての透明なマテリアルをフォワードパスでレンダリングすることです。
もう 1 つのオプション(デフォルトで有効)は、透明なオブジェクトにシャドウをつけることができます。ビルトインレンダーパイプラインとは異なり、URP はシャドウを受ける透明なマテリアルをサポートしています(ただし、シャドウを落とす透明なオブジェクトはサポートしていません)。
スクリーンスペースアンビエントオクルージョン(SSAO)のためのレンダラー機能は URP パッケージの一部で、アセットの Renderer Feature のセクションにあります。これを使うと、シーンでよりリアルなシャドウを描くことができます。
Lighting ウィンドウ(Window > Rendering > Lighting)には、ベイク済みライティング、環境値(スカイボックス、霧、太陽)、および反射の設定があります。ビルトインレンダーパイプラインと URP のライティング設定に決定的な違いはありませんが、注意すべき例外が 2 つあります。URP では、Lens Flare (SRP) コンポーネントがレンズフレアを処理します。また、ハローは現在サポートされていません。
各シーンは、共有設定を含む Lighting 設定ファイルを指定することができます。シーンごとに異なる設定を持つためには、複数の設定を作成する必要があります。これらの設定は、4 つのセクションに分かれています。Scene、Environment、Real-time lightmaps、Baked lightmaps の 4 つです。
URP とビルトインレンダーパイプラインとで Lighting ウィンドウには実質的な違いがないため、この記事では対象外としています。しかし、Unity に慣れていない方には、ライティングに関するドキュメンテーションを読み、Unity Learn の初心者向けチュートリアルを試して、キャッチアップすることをおすすめします。
URP はプロジェクトに使うことができるライティングモデルを 3 つ提供しています。
この 3 つのモデルには、いずれも特徴があります。混ぜて使うのは珍しいケースだと思われますが、場合によっては個性的な表情が生まれるかもしれません。Baked Lit ジオメトリと Lit または Simple シェーダーを混ぜて使うことで、より強力なパフォーマンスを得られる場合もありますが、通常は 1 つを選択し、それに従うのが最善です。
URP の物理ベースライティングは、最小限の Cook-Torrance BRDF をベースにしています。Blinn-Phong モデルよりもリソースを消費しますが、より物理的に正しい方法でマテリアルをレンダリングし、硬質なリアリズムからカートゥーン的なものまで、ビジュアルの幅を広げることができます。
Complex Lit シェーダーは Lit シェーダーのスーパーセットで、追加機能としてクリアコートが使えます。これは、マテリアルの上の薄い透明な層をシミュレーションするものです。ただしクリアコートを使うと、URP でライティングを 2 回評価する必要があるため、クリアコートは単独で Complex Lit シェーダーの 2 倍のリソースを消費することに注意してください。
一方、Simple Lit シェーダーの Blinn-Phong モデルは、何年も前からある、シンプルで物理的に正しくないモデルです。多くの名作ゲームがこのモデルを採用していますが、その理由の大部分はハードウェアの制約によるものです。レトロゲームの雰囲気を再現したいときなど、物理ベースでないアプローチにアートスタイルが合う場合に適しています。
最後に、Baked Lit シェーダーは、ライトマップまたはライトプローブを使用してオブジェクトをライティングするだけのものです。物理的に正しくはありませんが、オブジェクトをレンダリングするための安価な方法を提供します。唯一の欠点は、ライトマップまたはライトプローブのみを評価するため、反射や動的なライトは使えないということです。
以下の場合は、Simple Lit の使用を検討してください。
以下の場合は、Lit または Complex Lit、これらの両方の使用を検討してください。
以下の場合は、Baked Lit の使用を検討してください。
URP についてもっと知りたい方は、今すぐ無料のガイドを入手してください。このガイドは、ビルトインレンダーパイプラインからユニバーサルレンダーパイプラインにプロジェクトを移行しようとしている、経験豊富な Unity 開発者やテクニカルアーティスト向けに作成されたものです。またこの e ブックは、Unity の経験が浅い開発者に URP の詳しい説明を与えてくれるでしょう。