Unity を検索

ライトプローブを使用した静的ライティング

2019年8月28日 カテゴリ: Engine & platform | 7 分 で読めます
取り上げているトピック
シェア

Is this article helpful for you?

Thank you for your feedback!

Unity 2019.2 では、Lightmap Static フラグが廃止され、Contribute Global Illumination フラグに差し替わりました。また、ライトマップとライトプローブのどちらからグローバルイルミネーションを受けるようにするかの選択も可能になりました。これらの変更は、ベイキングのパフォーマンスやシーンのライティングの質などに大きく影響を及ぼす可能性があります。これについて詳しく見ていきましょう。

ライトマッピングとライトプローブ

グローバルイルミネーションには、ライトが光源から照射された後にサーフェスからサーフェスへどのように跳ね返るかを算出するための複雑な計算が必要です。これを、ランタイムにおいて負荷の高い計算を加えることなく正確に行うのは、基本的に困難です。この問題を解決しながらもできるだけ高品質な結果を得るためのアプローチとして一般的なもののひとつは、高負荷な計算処理を、編集モードで実行される事前計算の段階で行うようにすることです。

これを行うためには前提として「シーン内のいくつかのオブジェクトと光源が相対的に同じ位置に留まり、変形せず、角度も変更されず、見た目に関わるプロパティも一切変更されない」ことが求められます。これを前提とした上で、ライトマッピングというテクニックを使ってライトの計算を行うことが可能となります。

Unity の Lightmap Static フラグは、このようなオブジェクトをマークするために提供されました。この機能名は、それが作成された当初は理に適っていましたが、静的オブジェクトのみがライトマップを使用するという意味も暗に含まれるものでした。しかし、静的ライトマップは、グローバルイルミネーションをシーン内に保持する数多ある方法のひとつに過ぎず、一定のデメリットもあります(これに関しては後述します)。

ライトマッピングのアプローチをグローバルイルミネーションに使用した場合、非静的(あるいは動的)オブジェクトは、(それらが静的であるという前提に反するため)グローバルイルミネーションに寄与することができません。後から動くことになるオブジェクト用にグローバルイルミネーションを計算すると、そのオブジェクトが元々照らされた位置でしか正しいライティング結果を得られません。これは、従来のライトマッピングの重大な制約のひとつです。

動的オブジェクトは、ライトプローブによって、他の静的オブジェクトからグローバルイルミネーションを受けることができます。ライトプローブは、全方向からのライトのサンプルが格納された、空間内における位置です。このライトは「球面調和関数」と呼ばれる特殊な値にエンコードされます。これによってランタイム中に、オブジェクトがワールド内を動き回る間、動的オブジェクトは周囲のライトプローブから値を受け取ることができるようになります。これにより動的オブジェクトは局所的なライトを受けられるようになり、周囲のライティング環境に正しく統合されて(馴染んで)見えるようになります。

技術的に、静的オブジェクトがライトマップの代わりにライトプローブを使用することの弊害となるものは何もありません。

使用しない理由があるでしょうか?

テクセルのコスト

ライトマップを使用しなければならないオブジェクトは展開されている必要があり、また、ライトマップ内にそのための領域が確保されている必要があります。ライトマップ内に投影される各オブジェクトは、解像度によって、一定量のテクセルを確保します。

例えば、ライトマップの解像度が 1 テクセル/1 ユニットの単位キューブ(寸法 1x1x1)は、各面に 1 テクセルずつを確保します。つまり、合計 6 テクセルとなります。ライトマッパーはこれらのテクセルのひとつひとつに関して、そのテクセルのワールド位置に到達するライトを計算する必要があります。この計算は、レイをキャストし、光源が発見されるまでシーン内でそのレイを跳ね返させ続けるという方法で行われます。使用テクセル数が多いほど、結果を計算するために掛かる処理量も増大します。小さなオブジェクトが多数あるシーンでは、この処理量の合計が結果的に大きくなります。事実、ライトマップのベイキングに極端に時間が掛かったり失敗に終わったりする場合の最も一般的な原因は、この種のオブジェクトの展開やチャート作成やライトマッピングです。

ライトマップの解像度が 1 に設定された状態で、ちょうど 1 テクセルを占領している Unity キューブ

小石やがれきなどの小さなオブジェクトや、ワイヤーやポールのような細いオブジェクトは、「無駄なテクセル」を発生させやすくなります。これらは オブジェクトの全体的な見た目には大きく寄与しないにも関わらず、計算時間を増大させ、ライトマップ内の領域を消費します。

細いオブジェクトは「オブジェクトの長さが 1 ~ 2 ピクセルで取り囲まれるため、見た目に与える影響が非常に小さくなる」ような展開をしばしば発生させます。これに類似して小さなオブジェクトは、ライトマップ内に、(そのオブジェクトの画面上でのサイズが小さいために)ほとんど(あるいはまったく)見た目に寄与しない幾つかのテクセルを生成する傾向にあります。結果として、ビジュアル的に重要性の低いテクセルのために、多くの計算時間が費やされるだけでなく、必要なライトマップ領域が増大することになります。

ライトプローブによって簡単に照らすことができる小さなオブジェクトの選択例

ライトマップの生成に掛かる時間を最適化する良い方法のひとつは、このような小さなオブジェクトを非静的にすることでライトマップの計算から取り除くことです。これにより(計算が必要となる)ライトマップの占有テクセル数が削減されます。ただし、これらのオブジェクトがシーン内のライティングに大きな影響を与えているケースも考えられます。例えば、非常に鮮やかな色の付いたオブジェクトや、エミッシブマテリアルの付いたオブジェクトが含まれる場合を考えてみてください。こうしたオブジェクトは Lightmap Static でなければシーンのグローバルイルミネーションに寄与することができません。結果として、目標とするライティング結果に対して重要な役割を担うオブジェクトの効果が欠如してしまうという場合もあります。

以上、この種のオブジェクトの扱い方として 2 つの選択肢があることが分かりました。つまり、(ベイク時間が長くなってライトマップ内の領域を無駄にする可能性があっても)この種のオブジェクトをライトマップしてシーン全体にその影響を含めるようにする選択肢と、あるいはその影響を無くして全体的な見た目とグローバルイルミネーションの質を犠牲にする選択肢です。この葛藤をどう解決すれば良いのでしょうか?

代わりにライトプローブを使用する

Unity 2019.2 では、オブジェクトにライトプローブからのグローバルイルミネーションを受けさせながらもシーンのライティングに寄与させることが可能になりました。これは、インスペクター内の Mesh Renderer の下に追加された小さなドロップダウンメニューから有効化できます。

新しいオプション ―「Contribute Global Illumination」(グローバルイルミネーションに寄与する)および「Receive Global Illumination」(グローバルイルミネーションを受ける)「

ここでは、メッシュレンダラーがライトマップからグローバルイルミネーションを受けるようにする(静的オブジェクトの場合の従来の唯一の選択肢)か、ライトプローブから(動的オブジェクトの場合の従来の唯一の選択肢)グローバルイルミネーションを受けるようにするかを選択できます。

Contribute Global Illumination フラグを有効にすると、そのオブジェクトがライトマッパーのグローバルイルミネーションの計算に含まれるようになります。オブジェクトは常に静的であるという前提は引き続きありますが、ライティングに求められる忠実度によって、オブジェクトがライトプローブを使用するかライトマップを使用するかを明示的に制御することが可能になりました。「Contribute Global Illumination(グローバルイルミネーションに寄与する)が、ライトプローブから Receive Global Illumination(グローバルイルミネーションを受ける)」オブジェクトは、やはりその周囲に影響を与えます。例えば「背の高い街灯が落とした影(シャドウ)が周囲のライトマップの計算に含まれ、かつ、この街灯に使用されているエミッシブマテリアルが周囲のシーンを照らす」ということです。

本機能を使用する

本機能が新しく追加されたことで、問題となる小さなオブジェクトや細いオブジェクトの最適化が非常に簡単に ― Mesh Renderer の Receive Global Illumination フィールドを Light Probes に設定するだけで ― 行えるようになりました。この設定をすれば、オブジェクトがライトマップ内で大きな領域を占有しなくなるので、これらのテクセルがライトマッパーに不必要に負荷を掛けることがなくなります。

ライトプローブを使用するもうひとつの大きなメリットは(展開に時間が掛かりがちな)本格的な UV が必要ないことです。ライトプローブの使用によって素晴らしい見た目になる動的オブジェクトで、一切動いたり回転したり修正されたりしないものがある場合には、そのオブジェクトに Contribute Global Illumination フラグを設定することも可能になっています。この設定を行うとそのオブジェクトは、ベイク時間を増大させることなく、ライトマップされた周囲のオブジェクトに影響を与えることができます。この時間の節約によって、使用メモリを削減しながらも生産性を向上させることができるのです。

まとめ

この革新によって、動的(あるいは非静的)オブジェクトをライトプローブで照らすことが可能になりました。このおかげで、グローバルイルミネーションの計算に含まれるオブジェクトに関して、間接光をライトプローブから受けるかライトマップから受けるかの指定が可能になったので、ライトマップ内のテクセル使用量が削減することができます。総じて、今回の変更によって期待される効果は、ライトマップの計算時間の大幅な削減、使用メモリの抑制、そしてランタイムのパフォーマンスの向上です。

プロジェクトのグローバルイルミネーションを最適化するこの他の方法をお知りになりたい方は、Unite 2018 で行われたこちらの講演動画をご視聴ください。

Unite Copenhagen が 9 月に開催されます

さらに詳細を学びたい方は、9 月に開催予定の Unite Copenhagen へぜひご参加ください。このイベントは、世界中から集まる何千人もの才能溢れるクリエイターやトップレベルの開発者と交流できる、またとない機会です!

学び、交流し、参加しよう

  • 何十もの技術系セッション、ポップアップ講演、基調講演で、Unity の最新機能、ヒントやコツ、ワクワクするような新情報が公開されます!
  • 楽しい交流イベントや「Unity at Night」パーティで業界のリーダー達と交流し、新しい友達を作りましょう。
  • ワークショップや質疑応答セッション、コミュニティイベントで Unity スキルをレベルアップさせ、キャリアの前進につながる人脈を開拓しましょう。

Unite Copenhagen についての詳細は Unity のウェブサイトでご覧いただけます。Unity の TwitterFacebook では最新のニュースを配信していますので、ぜひフォローしてください!

2019年8月28日 カテゴリ: Engine & platform | 7 分 で読めます

Is this article helpful for you?

Thank you for your feedback!

取り上げているトピック