[Unity] 室内シーンのライティング調整

  • Unityでのライトマップ
  • Post Processing Stackを使った露出調整
  • Reflection Probe

今回はライトマップの説明になります。Unity 2017.2.0f3を使用しました。
Unity 5.6.3や2017.1ではいくつかライトマップ回りで不都合がありましたので、修正が入っている2017.2にて進めていきます。
前回の建物のシーンでライティングを行います。

その前段階として、
Unityでリアルなシーンをレンダリングする場合のチェック項目を別ページにまとめました
こちらも確認しておくようにしてくださいませ。

Shade3DのようなオフラインレンダラとUnityなどのリアルタイムで大きく異なる部分として、レンダリングがあります。
Unity上では以下のような感じになっています。

この段階では間接照明がまだ考慮されてないというのもありますが、レイトレーシングで環境光を上げたような単調な表現になっています。
リアルタイム表現の場合は、レイトレーシング手法を使ったレンダリングは行われません。

リアルタイムのライティングで必要な要素

Unityでのリアルタイム表現の場合は、ライティングのためにいくつかの要素があります。
なお、リアルタイムエンジンによっては差があったり名称が異なる部分もありますので、ここでは「Unityの場合は」の説明になります。

  • Directional Light(ディレクショナルライト)、Point Light(点光源)、Spot Light(スポットライト)、Area Light(面光源、これはベイクのみ)を配置
  • Lightmap (ライトマップ) として照明結果をベイク
  • Light Probe (ライトプローブ) で光をキャッシュ
  • Reflection Probe (リフレクションプローブ) で映り込みをキャッシュ

ディレクショナルライトはShade3Dの無限遠光源の動きと同じで、向きや明るさ/色などを持ちますが位置情報を持っていません。また、減衰もしません。
太陽光などで使用されます。

また、これはライティング要素ではありませんが、後処理のポストエフェクトも重要です。
これはUnity製のアセットである「Post Processing Stack」というのを使用します。
これらの一連の流れを書いていくことにします。

各種光源での表現

光源要素はHierarchyウィンドウの「create」をクリックしたポップアップメニューの「Light」から選択できます。

Directional Lightは、太陽光のような向きを持っていて位置を持たない光源。

背景が空模様の場合は、Directional Lightの向きにより背景色も同期させることができます。

Point Lightは、中心位置から球状に放射される光源。

Spot Lightは、中心位置から指定の向きに、円錐状に放射される光源。

影はそれぞれオン/オフできます。
「Directional Light」「Point Light」「Spot Light」については、Shade3Dと同じような感じになります。
光源のパラメータは、Hierarchyウィンドウで光源を選択したときに表示されるInspectorウィンドウで指定します。

Area Lightでの表現

「Area Light」はInspectorウィンドウの「Light」の「Type」で「Area(baked only)」となっています。

InspectorウィンドウでArea Lightのパラメータを変えても変化はありません。
Area Lightは「ベイク」である必要があり、光が照らされる形状は「Static (静的)」である必要があります。
いくつかの知識がいりますので、この部分を説明していきます。

ベイクとStatic/Dynamic

シーンに配置するすべての形状は、大きく「Static (静的)」と「Dynamic (動的)」に分けます。
これは、ユーザ側で手動で与えます。
また、「Area Light」の場合は「ベイク」しないと光の影響は反映されません。
その前に「ベイク」とはなんでしょうか ?

ライトマップ/ベイクとは ?

「Bake(ベイク)」は日本語だと「焼き付ける」といった表現になるでしょうか。
「Lightmap(ライトマップ)」は、各形状の表面に対してテクスチャを割り当てて光の状態を焼き付ける(ベイク)することで表現されます。
以下の画像は、Area Lightを配置してライトマップを行った例です。

この場合は、地面のPlaneと4つのリンゴ形状を「Static」としてライトマップを計算しています。
「Dynamic」形状は、ライトマップ計算からは除外されます。
このベイクされたライトマップのテクスチャは、メインメニューから「Window」-「Lighting」-「Settings」を選択して表示される「Lighting」ウィンドウで
「Global maps」を選択すると、みることができます。

「Lighting」ウィンドウで、各種ライトマップの設定を行うことになります。
この場合は、1テクスチャに対して地面のPlaneと4つのリンゴ形状のライトマップ情報がベイクされています。
形状が増えた場合は、ライトマップ用のテクスチャは自動的に複数作成されます。

ただ、形状が増えた場合にすべての形状をライトマップに反映してしまうと、以下の問題が出てきます。

  • ライトマップ計算の時間増加
  • ライトマップ用の使用メモリの増加
  • ベイクは固定の状態でテクスチャに焼き付けられるため、動く形状には割り当てできない

ライトマップの計算は、ここでテーマとしている建物だとPC性能にもよりますが10分~20分くらいの計算時間となります。
ここに、室内の家具や小物、その他の建物を配置して町を作る、などを行ってすべてをライトマップにベイクすると時間がかなりかかるのが想像できるかと思います。
また、ライトマップは物理的なテクスチャを作成しますので、GPU側のメモリを消費してしまいます。
また、計算でテクスチャに焼き付けるため、動く形状があるシーンの場合は違和感が出てしまいます(キャラクタが歩いたのに、地面の影が焼き付いたままなど、、)。

そこで、個々の形状を「Static」か「Dynamic」のいずれかに分けます。

StaticとDynamic

地形(Terrain)や建物や固定の家具など、動かない形状は「Static(静的)」とし、これに対してライトマップを割り当てるようにします。
草や木/動くキャラクタなどは「Dynamic(動的)」とし、これに対してはライトマップは割り当てません。
ライトマップ計算したStatic形状に加えて、「Light Probe」というのを配置して光をDynamic形状に間接的に与えることで、
全体的な動くシーンでの整合性をとる、というのがリアルタイムでのざくっとしたライティングのコツになります。
「Light Probe」については次回以降に説明予定です。

形状ごとのStatic/Dynamicの割り当てはInspectorウィンドウの「Static」チェックボックスをオンにするとStaticとなり、
オフにするとDynamicとなります。

ライティングとしては、「Static」にしたほうがよりリアルな表現になります。

ライトマップを行う手順

さて、それでは実際のシーンを元にライトマップの設定とArea Lightの反映を行っていきます。

Lightmap用のUVを指定

Projectウィンドウでシーンに配置する形状(ここではapple)を選択し、Inspectorウィンドウで「Generate Lightmap UVs」チェックボックスをオンにします。

Inspectorウィンドウで「Apply」ボタンを押すと、変更が確定されます。
これで、空いているUVに対してライトマップ用のUVが自動で割り当てられるようになります。
個々の形状にてUV1を使用している場合は、UV2にライトマップ用のUVが割り当てられることになります。
ただ、Unity 5.6/2017では、ここがオフでもライトマップのUVは正しく割り当てられているように見えます。

シーンの配置オブジェクトをStaticにする

Hierarchyウィンドウで、シーンに配置している形状を選択します。
まとめて選択して指定も可能です。
Inspectorウィンドウ右上の「Static」チェックボックスをオンにします。

ここでStaticとした形状がライトマップで考慮される形状になります。
この段階で、自動でライトマップは計算されます。

Lightingのパラメータの確認

メインメニューから「Window」-「Lighting」-「Settings」を選択して表示される「Lighting」ウィンドウでライトマップの設定を行います。
初期状態では、自動でライトマップが計算されます。

これくらいの簡単なシーンの場合はこのままで問題ありません。
Directional Lightを与えたり、室内シーンの場合はこのパラメータの調整が必要になってきます。

ここまでで、ライトマップ用のUVを指定しStaticにすると、
ライトマップのベイクが行われてArea Lightが反映されるというところまで進みました。

次に、建物のシーンでのライトマップを指定します。

建物のライトマップを指定

Generate Lightmap UVsを指定

Projectウィンドウで建物形状を選択し、Inspectorウィンドウで「Generate Lightmap UVs」チェックボックスをオンにします。

Staticを指定

シーンの建物形状のルートを選択し、Inspectorウィンドウ左上に「Static」チェックボックスをオンにします。

「Change Static Flags」メッセージボックスが表示された場合は、「Yes, change children」ボタンを押すと、子の形状(GameObject)に対してもStaticの設定が割り当てられます。

現段階で以下のようになっています。

この解説の一番はじめの画像よりは、室内は暗くなっているのを確認できます。

Lightingの調整

ただ、室内の床のテクスチャが見えにくくなっていたり、Staticにする前とさほど変わりがないように見えます。
また、中央に見える縦樋の影が濃くて大雑把になっています。
以降はLightingウィンドウを表示し、ライトマップの設定を行います。

Sun SourceにDirectional Lightを指定

HierarchyウィンドウからDirectional Lightをドラッグし、「Environment」の「Sun Source」にドロップします。

次に、ライトマップエンジンを初期状態の「Enlighten」から「Progressive」に変更します。

「Enlighten」と「Progressive」の違いは?

Unity 5.6以前は、「Enlighten」というライトマップエンジンが使用されていました。
これは、間接照明を高速に計算するライトマップ計算エンジンになります。
速い反面、大雑把に間接照明計算が行われます。
そのため、建物シーンなどの場合は取りこぼしが起こることが多く、うっすら影になってほしい部分が明るくなるといった現象が起きます。
「Progressive」は「Progressive Lightmapper」と呼ばれており、Unity 5.6から追加されたUnity専用のライトマップ計算エンジンになります。
パストレーシングで計算されるもので、より正確にライトマップ計算されますが計算時間がかかります。
Unity 5.6.3/2017.1/2017.2段階ではProgressive Lightmapperはまだプレビュー版です。
ですが、かなり高機能です。

「Lighting」ウィンドウの「Lightmapping Settings」の「Lightmapper」より
ライトマップエンジンを切り替えることができます。

今回はよりきれいにライトマップを表現したいため、「Progressive」を使用することにします。

「Progressive」とライトマップのベイク設定

Directional Lightを使用したライティングの場合は、リアルタイムで光源計算されます。
リアルタイムの場合は、形状に差し込む光の間接照明は荒いものになります。
光源が移動しないものとした場合は、光源をStaticな形状にベイクしてしまう(ライトマップする)ほうがよりリアルになります。

Lightingウィンドウでは、以下の変更を行いました。

  • 「Realtime Lighting」の「Realtime Global Illumination」チェックボックスをオフにする
  • 「Mixed Lighting」の「Lighting Mode」で「Baked Indirect」を選択
  • 「Lightmapping Settings」の「Lightmapper」で「Progressive (Preview)」を選択

また、HierarchyウィンドウでDirectional Lightを選択し、Inspectorウィンドウで「Mode」を「Mixed」とします。

Mixedを指定することで、Staticな形状が落とすベイクの影と、Dynamicな形状が落とすリアルタイムの影のどちらもを表現できるようになります。

これで、自動的にライトマップ計算が行われます。
Progressiveの場合は計算時間がかかります。途中経過はメインウィンドウ右下に計算経過情報が表示されます。
ライトマップ計算後、以下のように縦樋の影が緩やかになりました。
また、屋根と壁の境目もうっすらと影がついています。

これらのライティングは、ライトマップとしてベイクされたものになります。
光源やStaticな形状が動いた場合は再計算されます。
室内が影になっていてわかりにくいため、Directional Lightの向きを調整して窓から光が入るようにします。

室内からライティングを確認

それでは、次にカメラを室内に持っていきます。
Hierarchyウィンドウで「Main Camera」を選択し、Sceneビューでカメラを移動/回転させて見たい位置に移動します。

Main CameraのInspectorウィンドウで「Field of View」を80度に変更しました。
右下の「Camera Preview」でカメラからのビューを確認できます。

Directional Lightの向きを調整して、窓から光が差し込むようにしてみます。
光源を変更した場合は、再びライトマップ計算が行われますのでしばらく待ちます。

Gameビューに切り替えると、
光が窓から差し込む部分は明るいですが、間接照明があまり効いていないように見えます。
また、影になった部分のテクスチャが単一色になっているように見えます。

ライティングの調整

以下の調整を行います。

  • 「Lightmapping Settings」の「Bounces」を4にする
  • 露出の調整 (Post Processing Stack)
  • マテリアルのMetallic/Smoothnessでの反射が白い (Reflection Probe)

「Lightmapping Settings」の「Bounces」を4にする

これは、室内はほとんどが間接照明にならないといけないはずが、
光の反射回数が初期状態では「2」と小さいために光が回り込まない、という問題があります。
そこで、Lightingウィンドウの「Lightmapping Settings」の「Bounces」を2から4に変更します。


こうすると、さらに計算時間がかかることになります。

露出の調整 (Post Processing Stack)

外の太陽と比較すると室内は暗くなるため、ここでは露出を調整するようにします。
スクリーンでのイメージエフェクトについては、Unityの場合は「Post Processing Stack」(https://www.assetstore.unity3d.com/jp/#!/content/83912)というアセットを使用します。
このアセットは、リアルタイムに表示された画像に対して
全体の色合い調整(Color Grading)のほか、SSAO(Screen Space Ambient Occlusion)、DOF(Depth Of Field)、Bloom、Vignetteなどをかけることができます。

使い方は以下の手順になります。

  1. 「Post Processing Stack」をAsset Storeからプロジェクトにインポート
  2. 「Post-Processing Profile」を作成
  3. Main Cameraにコンポーネントとして「Post-Processing Behaviour」を追加し、「Post-Processing Profile」を割り当て

「Post Processing Stack」の各種設定は、「Post-Processing Profile」という設定に対して行います。
これはプロジェクトにファイルとして配置されます。
Projectウィンドウを右クリックしたポップアップメニューより「Create」-「Post-Processing Profile」を選択することで、
「Post Processing Stack」用の設定が作成されます。
Projectウィンドウで「Post-Processing Profile」を選択すると、Inspectorウィンドウに設定が一覧されます。
ここですべての設定を指定します。

「Post-Processing Profile」は独立した設定ファイルになっており、
ここの設定を指定しただけではイメージエフェクトとしては反映されません。

Main Cameraを選択し、Inspectorウィンドウの一番下で「Add Component」ボタンを押します。
ここで、「Effects」 – 「Post-Processing Behaviour」を選択。

Projectウィンドウ上の「Post-Processing Profile」をドラッグし、Main Cameraで追加した「Post-Processing Behaviour」の「Profile」にドロップします。

これで、「Post-Processing Profile」での設定がMain Cameraを通して即座に反映されます。
「Post-Processing Profile」の「Color Grading」で「Post Exposure(EV)」の値を変化させると以下のように露出が調整されます。

全体的に明るくなりました。
「Post Processing Stack」の設定はまだまだあるのですが、今回はまだ露出を上げての確認のみになります。
全体的に白飛びしています。次にこの部分を調整します。

マテリアルのMetallic/Smoothnessでの反射が白い (Reflection Probe)

露出の調整で、背景である外の景色が白くなるのは正しい動きになります。
ただ、室内の壁や床が全体的に白くなってしまってます。
これは、光が回り込んでいるというわけではなく、リアルタイムでは反射(Reflection)の挙動によるものです。
具体的には、外の空模様(Skybox)が室内にもSkyboxの反射として反映されてしまってます。
Lightingウィンドウの「Environment Reflections」の情報が室内でも反映されている状態です。

ここの「Inteisity Multiplier」の値を下げると室内の白飛びも収まるのですが、そうすると室外で間接照明が効いていないような色合いになってしまいます。

これは、外はSkyboxの反射を反映、室内は室内用の反射を反映、とすることで解決することになります。
リアルタイムでの反射/映り込み表現は、球体に対して映り込み用のテクスチャとして「環境マップ」を作成し、それを映り込むマテリアルに反映する、という2段階で行われます。
Unityやリアルタイムでは、「環境マップ」は「キューブマップ」という形で処理されます。

シーン全体ではSkyboxを使用、個々の場所での小さな映り込みは「Reflection Probe」という仕組みを使用します。
室内シーンの場合は、室内に「Reflection Probe」を配置することになります。

「Reflection Probe」はHierarchyウィンドウの「Create」をクリックし、ポップアップメニューより「Light」-「Reflection Probe」を選択します。
以下の画像の場合は、3つの「Reflection Probe」を配置しています。

手前の室内に2つ、外に1つ配置しました。
影響範囲については、「Reflection Probe」を選択したときのInspectorウィンドウの「Box Size」で変更できます。
配置を行うと、すぐに反射球として「Reflection Probe」を中心としたシーンのキャプチャが行われます。
「Reflection Probe」の反射に反映される形状は「Static」なものだけであるのに注意してください。

室内では、以下のように変化しました。
左が「Reflection Probe」なし、右がありです。

「Post Processing Stack」で「Color Grading」の「Post Exposure(EV)」を3.8としています。
右側の壁が少し白いですね。
これは、右は部屋があるのですがそこの「Reflection Probe」を置いていないのが原因の1つになります。
以下のように、奥の部屋にも2つの「Reflection Probe」を配置しました。

白い丸のアイコンが「Reflection Probe」となります。
これで、以下のようになりました。

これで、室内の間接照明の回り込みもそれらしくなりました。

また、各「Reflection Probe」で輝度差が激しい場合(今回のように窓から強い光が入る場合など)で明るさの調整がうまくいかないときは、
「Reflection Probe」のInspectorウィンドウを表示し、「Intensity」を調整することも有効な手段になりそうです。

今回はPost Processing Stackは露出しか使いませんでしたが、
次回にそれ以外のエフェクトも使用して、最終の絵に仕上げていきます。

カテゴリー: Unityに形状を渡す