この記事ではUnityでのグローバルイルミネーション(GI)の基礎知識と、それを用いた間接照明のような表現をSTYLYの空間に反映させる方法をご紹介します。
注意事項
本記事のテクニックによる効果は残念ながら、Webブラウザ上(STYLY Studio、STYLY Gallery)では正しく反映されません。
VRでの場合のみそのまま反映されますので、その点を考慮してご活用ください。
また、今回はSTYLYにシーンごとアップロードする必要があります。
使用したUnityのバージョンは2019.3.6f1です。
STYLYと互換性のあるUnityバージョンはこちらからご確認ください。
https://document.styly.cc/doc/docs/en/creator/creator_plugin_intro/#%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8Bunity%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
サンプル
本記事で作成するサンプルシーンは以下から体験できます。
グローバルイルミネーション(GI)とは?
グローバルイルミネーション(以下、GI)とは、CGで光を表現する際に人間が現実を目で見たときのように自然な表現をする技法です。
日本語にすると「大域照明」、つまり局所的な直接光の表現だけでなく、反射光や環境光などの間接光も含めて大域的(グローバル)に照明効果を表現すると言う意味です。
Unityでのライトの基礎知識と使い方に関しては下記の記事をご参照ください。
閉じられた部屋を作る
GIの効果をわかりやすくするため、今回はコーネルボックスにならい、赤と緑の壁のある閉じられた部屋を作ります。
コーネルボックスとは、CGの照明効果が現実同等に描画されるかを検証するためにコーネル大学研究者が発案した有名なモデルです。
MainCameraをSTYLYのYour Positionに合わせる
空間の作成に入る前に、STYLYにシーンをアップロードする前提のため、MainCameraをSTYLYのYour Positionと同じPositionにします。
奥行き(Z座標)を-5、高さ(Y座標)は適当ですが1.5にしました。
Planeを配置する
それではここから部屋を作ります。
今回は床、壁、屋根をすべてUnity基本オブジェクトのPlaneで作ります。
Planeは裏面のメッシュはないため、閉じられた空間にして壁の外の視点から見てもSceneビューなどで確認しやすいからです。
Planeを六面に配置して部屋にします。
壁と天井のScale値はすべて1、壁は高さ(この場合Z座標)を半分の0.5にしました。
自分の場合、各PlaneのTransformは下記表の通りとなりました。
Plane(床) |
Position |
0 | 0 | 0 |
Rotation | 0 | 0 | 0 | |
Scale | 1 | 1 | 1 | |
Plane (1) | Position | 0 | 2.5 | 5 |
Rotation | -90 | 0 | 0 | |
Scale | 1 | 1 | 0.5 | |
Plane (2) | Position | -5 | 2.5 | 0 |
Rotation | -90 | 0 | -90 | |
Scale | 1 | 1 | 0.5 | |
Plane (3) | Position | 5 | 2.5 | 0 |
Rotation | -90 | 0 | 90 | |
Scale | 1 | 1 | 0.5 | |
Plane (4) | Position | 0 | 2.5 | -5 |
Rotation | -90 | 0 | 180 | |
Scale | 1 | 1 | 0.5 | |
Plane (5)(天井) | Position | 0 | 5 | 0 |
Rotation | 180 | 0 | 0 | |
Scale | 1 | 1 | 1 |
壁に色をつける
壁のマテリアルを作成して適用していきますが、まず色の違いをわかりやすくするために一度Lightingウィンドウから「Generate Lighting」します。
Lightingウィンドウは、ファイルメニューの Window > Rendering > Lighting Settingsで開きます。
Lightingウィンドウ下にある、Generate Lightingのボタンを押してください。
もしグレーアウトして押せない場合は、隣の「Auto Generate」のチェックを外すと押すことができるようになります。
Lightingウィンドウはよく使うので、Inspectorの右にでもレイアウトしましょう。
では、マテリアルを作っていきます。
まずは赤。ProjectビューのCreateメニューからMaterialを選び、「Red」と名付けます。
ShaderはStandardのまま使います。Albedoカラーを(R:240、G:0、B:0)にします。
同じく「Green」というマテリアルを作り、Albedoカラーを(R:0、G:240、B:0)にします。
これらを左右の壁に各々適用します。(ProjectビューからマテリアルをHierarchyビューの適用したいGameObjectにドラッグ&ドロップします)
また、その他の壁、床、天井に関しては白にしたいのですが、真っ白ではなく(R:240、G:240、B:240)のマテリアル「White」を作りました。
すべてのPlaneにマテリアルを適用すると以下のようになりました。
RGB値の「240」というのは、Unityが提供しているマテリアルチャートを参照しています。
これはGI効果をより自然に近い表現にするために必要だということです。
シーンを保存します。シーン名は何でもよいですがここでは「GI_Sample」としました。
ここで部屋の中がDirectional Lightのおかげで明るいままですので、Directional Lightを削除しましょう。
Directional Lightを削除すると部屋の中は真っ暗になるかと思いきや真っ暗にはなりません。
これは、実はすでにGIの効果が有効になっており、部屋の中が照らされているからです。
ではこの照明の設定はどこにあるのでしょうか。
Lightingに関する環境設定をする
ここで使用するのが先ほど登場したLightingウィンドウです。
UnityにおけるシーンのLightingのセッティングは、Lightingウィンドウにある程度まとまっています。
さてLightingウィンドウを見ると、まず一番上の所、タブのようなもので「Scene」が選択された状態となっているかと思います。(他に「Realtime Lightmaps」「Baked Lightmaps」というものが並んでいます。)
下記2つの値を共にゼロにします。
- Environment > Environment Lighting > Intensity Multiplier
- Environment > Environment Reflections > Intensity Multiplier
そうすると部屋の中は真っ暗になりました。
Environment Lighting、Environment Reflectionsは、共に環境光に関する設定項目群であり、Intensity Multiplierでは明るさの度合いを設定できます。
これがデフォルトでは1となっており、閉じた部屋であろうが環境光で照らされた状態となり、シーン内にひとつもライトがなくても明るかったのです。
また、各々Sourceという項目があり、デフォルトでは共に「Skybox」となっています。
これは環境光の計算のもととなるものがSkyboxに設定されていることを示します。
真っ暗なままだと作業がしにくいため一旦、Intensity Multiplierの値をもとの1に戻しましょう。
発光するオブジェクトを置く
今回は光源として発光する(Emissive)オブジェクトを使いたいと思います。
まずはCubeを置き、「Emissive」という名のマテリアルを作成して適用します。
これをEmissiveオブジェクトとするには、適用するマテリアルのEmissionを有効にし、Emission > Color > Intensityの値を0以上に設定するだけです。とりあえず1に設定しました。
ただこれだけだと、まわりのオブジェクトに光の影響を与えません。
影響を与えるにはCube自身、そして影響を受けさせたいGameObject(ここでは周りのPlane)の「Contribute Global Illumination」のチェックをONにする必要があります。
Mesh Renderer > Lighting > Contribute Global IlluminationのチェックをONにして下さい。
これでやっと発光しているように見えるようになりましたので、薄くして天井に配置しました。
ここでCubeを移動したり、Contribute Global Illuminationをオン/オフしたりするごとに右下に進捗メーターが表示され、なんらかの処理が走ったあとにLighting効果が適用されているようです。
(※ちなみにEmissiveオブジェクトは正確にはLightではありませんが、Light同様にGIの効果を得られますし、Lightとは違いEmissiveオブジェクトそのものが発光する効果を得られるので、蛍光灯やネオンを表現するのに便利です。)
ライティングの事前計算を手動で実行する
ここでまたLightingウィンドウに戻ります。
一番下に「Auto Generate」という項目にチェックが入っています。
これをオフにすると、「Generate Lighting」というボタンが有効になりました。
この状態で先程のように、EmissiveにしたCubeを移動したり、Contibute Global Illuminationをオン/オフしたりしてもシーンのライティングに変化はありません。
代わりに、「Generate Lighting」ボタンを押すと処理が実行され、編集した内容によりライティングが変更されるようになりました。
また、この処理の実行後にProjectビューに「設定しているシーン名」のフォルダと、その中にファイル2つが作成されていました。
この処理はライティングの事前計算と呼ばれるもので、シーンに紐づく事前計算結果データがシーンと同名のフォルダの中に作成されます。
このデータはUnity、もしくはSTYLYの実行時に描画に使用されます。
また、LightingウィンドウのMixed Lighting >Baked Global Illuminationのチェックはオフにします。
そしてGenerate Lightingボタンを押してライティングの事前計算を実行します。(以下、単に「Generate Lightingします」と言います。)
もし光がうまく生成されないようであれば、Emissiveマテリアルの Emission > Global Illumination を Realtime に変更して下さい。
「Auto Generate」、つまり自動生成を無効にしたのでライティングに関わる変更をしてシーンに反映させたい場合には、都度Generateする必要があります。
なぜ今回手動生成にしたかというと、どの変更がライティングの効果に影響を与えるかわかりやすくするためです。
Baked Global Illuminationに関しては今回詳しく説明しませんが、STYLYへのアップロード時に確実に反映させるためオフにしました。
プリミティブを部屋に置く
このままだと蛍光灯のようなものがむき出しで間接照明にはなりませんので、ランプシェードのようなものをCubeで作り、Emissiveオブジェクトの下に置きます。
また、シーンを明るくするためにEmissiveマテリアルのIntensityを2.5に変更します。
あとは床に適当にCubeなどのプリミティブを配置します。
追加したプリミティブはもちろん「Contribute Global Illumination」をオンにし、Whiteマテリアルを適用しました。
また、Whiteマテリアルの「Smoothness」を0にします。これは物体表面からの光をよく拡散させるためです。
そしてGenerate Lightingした結果が下の画像です。
プリミティブの表面が向かって左に面している側は赤に、右のほうは緑にうっすら色づいています。
これはEmissiveオブジェクトからの光が壁に当たって反射し、プリミティブの表面に届いたものが反映されているからです。
GIの効果のひとつとなります。
もちろんテクスチャのあるマテリアルであっても同様に反映されます。
赤と緑の壁側にもEmissiveオブジェクトを配置し、テクスチャの乗せたSphereもEmissiveにしてみました。
もう少し暗がりにしたかったので、Emissionの明るさの値をすべて1.5に下げました。
また、前述した環境光の明るさの設定値2つをゼロにしました。
- Environment > Environment Lighting > Intensity Multiplier
- Environment > Environment Reflections > Intensity Multiplier
これでいい感じに暗くなったのですが、肝心の間接照明(Emissiveオブジェクト)部分から漏れ出る光が薄くなってしまっています。
ここで、LightingウィンドウのLight Mapping Settings > Indirect Resolution をデフォルトの2から、4に変更します。
Indirect Resolutionは間接光の解像度を表します。
そしてGenerate Lightingします。
すると、壁側のEmissiveオブジェクトの光が明るくなりました。
全体的に明るくなりすぎたので、Light Mapping Settings > Indirect Intensityで間接光の明るさを調整します。
この場合、0.7にしました。
明るさはいいのですが、壁に当たる光の表現の解像度が粗いのが気になりました。
かといって、Indirect Resolutionを上げすぎてしまうとGenerate Lightingに時間がかかってしまい、作業効率が悪くなってしまいます。
実行時のパフォーマンスにも影響を与えそうなので、壁際はPoint Lightに変更してみます。
STYLYの仕様上、Point Lightの「Render Mode」を「Important」に設定しないとライトが機能しないため、そのように設定します。
また、Point Lightからの影を描画するため、Point Lightの「Shadow Type」を「Hard Shadows」に変更します。
この状態でGenerate Lightingしてみましょう。
Point Lightは球状のため光の形状が変わってしまいましたが、粗さはなくなりました。
影もちゃんと描画されています。
また、Indirect Resolutionを2に戻してみても粗さが気にならない程度になりました。
補足
Unity公式のチュートリアルを参照すると、Indirect Resolutionが4というのはかなり高い値のようです。
屋内の間接光表現が複雑になる空間でも2~3がちょうどよいと書いてありました。
Precomputed Realtime GI (Global Illumination)
※このチュートリアルでいう「Realtime Resolution」が「
今回使用したのが上記Precomputed Realtime GIであり、Generate Lightingして事前計算を行いはするものの、それをもとに実行時(リアルタイム)に間接光も含めた光の計算を行う、というものです。
Precomputed Realtime GIを使う場合には「
STYLYにアップロードする
では、できあがった空間をSTYLYにアップロードしましょう。
今回はUnityシーンごとアップロードします。
STYLYにUnityシーンをアップロードする方法はこちらを御覧ください。
Generate Lightingして作成されたLightingの事前計算結果データも含めてアップロードされます。
アップロード後、シーンが明るくなりすぎてしまうため、STYLYシーン内にデフォルトでついているDirectional Lightは削除してしまいましょう。
Webブラウザ上(STYLY Studio、STYLY Gallery)で見ても反映されませんが、STYLYアプリでVRゴーグルをかけて見ると、Unityで見たままの光が反映されているかと思います。
ただし、PCディスプレイでの見た目よりもVRゴーグルで見たときのほうが明るい気がしました。
これは見るVRゴーグルによっても違いが出るかもしれません。
まとめ
今回はUnityのGI、そしてEmissionとPoint Lightを使って間接照明のような表現をしてみました。
UnityのLighting表現に関しては、設定箇所や学ばないといけないことも多岐にわたり、奥が深すぎてまだまだご紹介しきれないのですが、GIを意識してうまく使うことにより、より自然な表現や心地よい空間を作ることができるのではないかと思います。
今回は動かない物体のみで構成された静的な空間でしたが今後、動く物体やライト自体に変化のある空間に関しても書いてみたいと思います。
皆さんもぜひ色々と試してみてください。
参考にした情報
今回以下の記事を主に参考にさせて頂きました。