見出し画像

Unity Look Dev講座 ライトシャドウ編

※ こちらの記事は2018年6月2日にVRアカデミー様で講演させていただいた内容のブログ版になります。

はじめに

今回と次回の2回で、Unity の機能を用いたルックデヴ( Look Development )… かんたんに言うと「画作り」のテクニックを紹介しようと思います。

今回はライトとシャドウ編です。
(ちなみに、本稿は Unity 2018.1.4 を使用しています。)

プロジェクトを作ったときに最初から Directional Light が置いてあるけど、それ以外になにがあるんだろう?

なんか色々と Light の種類あるみたいだけどどう違うの?

という方々向けの記事となります。
光あるところに影は生まれるのでこの2つは一緒に扱っていきます。

Forward と Deferred についてのおさらい

本題に入る前に、まずはざっくりと「Forwardレンダリング」と「Deferredレンダリング」についておさらいしておきましょう。

Forwardレンダリング
ライトごとにレンダリングを行います。
ライトが複数ある場合は、ライトの数だけレンダリングを繰り返します。(Unity では遠距離のライトなどは簡略化されてまとめて計算されるようになっています。)

大まかな特徴として…
・ライトが増えるほど重くなる
・VRAM の消費量が少ない
・モバイル、ローエンド向け

Deferredレンダリング
ライティングやテクスチャなどはいったん後回し(Deferred)にして、とりあえずオブジェクトをレンダリングします。その過程でライティングなどに必要なデータを G-Buffer に書き出して最後に描画を反映させます。

大まかな特徴として…
・ライトをたくさん置ける
・G-Buffer に沢山の情報が残っているのでポストプロダクション※がしやすい(Deferred でしかできないポストプロダクションがある)
・VRAM の消費量が多い
・半透明処理がつらい
・ハイエンド向け

※ ポストプロダクション … 撮影完了後の全ての作業のこと。編集はもちろんのこと、音編集や色調整、納品形態への書き出しなども含みます。以降、「ポスプロ」と略します。

今回重要なのは「Forward と Deferred でライトの扱いに差があるよー」という部分だけなのでこまかい説明は割愛しますが、詳しく知りたい方はこちらの記事がおすすめです。

今回は下記理由により、Forward 設定でライトとシャドウを解説していきます。

・モバイルで動かす予定
・ライトの数が少ない(2つだけ)
・Deferred でしか使えないポスプロを使う予定がない

ライティングのおはなし

それでは本題のライティングの話です。
Unity でライティングを行う方法は大きく分けて3つあります。

1.Light オブジェクトによるライティング
2.Light Probe によるライティング
3.HDR 撮影の全天球画像をつかったイメージベースドライティング

それでは、それぞれの細かい話と上記の派生形の話をしていきます。

4つのライティング方法を把握する

プロジェクト生成の初期状態から置いてある Directional Light を初めとする基本的なライティング方法です。使える Light は全4種類あります。

Directional Light
デフォルトで存在するライトです。
太陽などのはるか遠くにある巨大な光源をシミュレーションするもので、空間のどの場所でも等しく平行に光が降り注ぎます。また減衰などもしません。
Unity で一番基本となるライトです。

画像1

Point Light
一点を中心に全方向へ光を照射するライトです。
中心から距離の二乗に反比例して減衰していきます。
たとえば、ろうそくの光や電球などの光を表現したいときに使います。
全方位に光を照射するので地味に計算が重いです。。

画像2

Spot Light
設定した方向のみに光を照射するライトです。
中心から円錐型に光が広がります。
懐中電灯や文字通りスポットライトなど指向性があるライトを作る時に使います。

画像3

Area Light
点ではなく、長方形の平面から照射するライトです。
豆電球や蛍光灯のように、点ではなく面で光っている物体を再現するためのライトです。
写実的な光を表現できる上に、やわらかな影が出てとても重宝するライトです。

しかしこのライトは計算が重く、リアルタイムに計算ができないため Baked Light (※ 後述) という扱いになっています。

画像4

Baked Light
Unity には Light を Bake(事前計算)するという方法があります。
Bake する手順は…

まず、Light の Mode を Mixed か Baked に変更します。

画像5

そして Bake したいオブジェクトを Static にします。

画像6

以上の方法で自動で Light が Bake されます。

ですが、このままだと Scene を少しいじるだけで何回も Bake が走ってしまって作業がとても重くなってしまうので、Editor の「 Lighting 」タブの設定にある「 Auto Generate 」を OFF にしておきましょう。
これでその横にある「 Generate Lighting 」を押すまでは勝手に Bake されなようになります。

画像7

注意点としては Static にしないと焼けないので動くキャラクターなどには適用できないという点です。
あと、まれにあるのが Scene 内部で部屋のモデルなどがあった時に全て Static にしてしまうと時計の針など動くように設定していたものがすべて動かなくなるので後々見つけて「あっ」となる事があります。。気を付けましょう(自戒)

また、 Bake した後にオブジェクトを動かしてそのまま Generate Lighting を押さないとこんな感じで影が残っちゃったりするので注意しましょう。
(見ればすぐに気づけるので、押さずに放置してしまう事はあまりないかもしれませんが…。)

画像8

Global Illumination(GI)
間接光、間接照明のシミュレーションができる機能です。
フォトリアルな表現では必須機能です。

プリレンダCG界ではかなり前からの必須機能ですが計算負荷が重いためリアルタイムでは厳しい……。というわけで Baked GI という事前計算で GI が表現できるシステムが出来ました。(簡略化して実行するリアルタイム GI というものもあります。)

使い方は GI の設定を ON にして「 Generate Lighting 」で Bake するだけです。(Bake なので Static のオブジェクトしか演算できないことに注意してください。)

画像9

うまく行くと下画像のように赤いオブジェクトの色が別のオブジェクトに影響を及ぼす事ができるようになります。

画像10

Light Probe
ここまで紹介してきた Baked Light 、 GI の影響を動くキャラクターなどに反映させたい!という時に使う機能です。

Light と GI を Bake した Static なフィールドでキャラが浮かないようにするには、 Light Probe を使ってキャラにも GI がかかるようにする必要があります。

機能としては、 Probe(探針)を任意の場所に置いてそこの光の情報をベイクする。リアルタイムで動くオブジェクトは自身の近傍の LightProbe の光を描画する。といった機能になります。

使い方はまず、 Hierarchy で右クリック→ Create → Light → Light Probe Group で Probe を作成します。

画像11

すると Scene 画面に黄色い Probe が数個置かれていると思います。この Probe がある位置の光の色、強度を記録してリアルタイムに動くオブジェクトに反映させることができます。

Probe の数は Inspector で増やしたり減らしたりできますし、 Probe 自体を Scene 画面で選択すれば移動もできますので、キャラクターがよく歩く場所は密度を高めに、遠くは少なめにといった事や光が複雑に混じり合うところは多めになど自由に調整できます。

Probe の数が増えれば増えるほど Bake 時間が伸びてきたり実行時の処理負荷にもなるので使うデバイスに応じて Probe 量は調整していきましょう。

Light Probe も Bake の必要があるので配置が終わったら「 Generate Lighting 」を押しましょう。

画像12

以上を設定した結果が下記画像です。
黄色で囲まれた丸い Sphere は Static オブジェクトではないですが LightProbe を使う事で回りの Static オブジェクトの赤色が反射するようになりました。

画像13

Image Based Lighting(IBL)
全天球の HDR 画像をベースに、色や明るさなどからライティングを行う方法です。
実写全天球画像を使えば、現実のライティングがある程度再現できるのでフォトリアルな物を作る場合はあると便利です。金属物の反射画像にも使えます。

しかし、影は出ない
↑重要

使い方は
まず全天球の Material を作ります。

画像14

作った Material を Lighting タブの Skybox Material に突っ込みます。

画像15

以上。簡単です。
Skybox の回転調整をしたい場合は Material の Rotation を弄れば天球を回転できます。

最近はこれを設定したあとに Light オブジェクトとかで微調整していく流れが好みです。

シャドウのおはなし

続いて影の話です。
基本的には Light の設定をしていればもう勝手に影は出来ているはずなので、ここではその影についての情報を補足していきます。

説明用に下の画像の和室を使って説明していきます。

画像16

影の解像度を知る

ライトの説明で多種のライトオブジェクトを紹介しましたが、実はライトごとに影の解像度が決まっています。

比率にすると以下のとおりです。

画像17

出典:【 Unity 】リアルタイムな影がカクカクになる問題の対処

なぜ比率なのかというと、Quality Settings や Light の設定で解像度を変更できるため、ここでは同じ品質設定だった場合はこの比率で解像度が違うということです。

上記特徴から各々のライトを使うべき場所が見えてきます。

Directional Light
広い範囲を照らすためのライト。
大きい範囲を照らす専用にして複数はあまり設置しない。(ゲームの舞台が別の星で太陽が二個あるとかなら複数設置しちゃっていいと思います。)

Spot Light
Map の明るい場所を表現する場合などに使用するライト。

Point Light
Map のディティールを調整するためのライト。
影響範囲を広くすると、あからさまに影が劣化するので影響範囲は極力狭くすることがポイントです。

影の解像度を意識してライトを設置してみる

用意した和室の外には庭園があります。
木々が風でゆらめくのでライトとシャドウはベイクせずにリアルタイム主体で調整します。

まず Image Based Lighting(IBL) を設定します。画像は先ほどの IBL の説明で使用した、青空の画像を使ってます。
そして Directional Light をまず設置するのですが、用意した IBL 画像には太陽が書かれていないので、適当にいい感じの角度でライトを配置します。

画像18

つづいて、外には木々の緑があるので、その光の反射を再現するために緑色の Point Light を設置します。
つまり擬似的な Global Illumination 再現ライトです。

なぜ GI をベイクしないのかって?
ベイクする時間短縮と疑似再現でも問題なさそうなのと Light Probe を置くのがめんどうだからです…。

実際問題、GI を無理に Bake しても品質が向上しないのであればこういう逃げ方はありだと思います。

画像19

障子は基本的にある程度光を透過します。

擬似的に太陽光が透過してるように見せるため、障子のマテリアルの Emission の数字を1以上にして発光させることで、太陽光の透過を表現します。
そして、不透明度を若干下げてやることで障子同士の重なりを見せたり、木々の影のような物を見せたりもできます。

画像20

ちなみに Emission を1以上にあげても Static で Bake しないとそれっぽく光らないという点には注意が必要です。
リアルタイムで光ってるように見せたい場合は Image Effect などで Bloom を設定し光を表現してあげる必要があります。

Image Effect(ポストプロセスエフェクト)については次回解説します。

影の解像度を調整する

最後にちょっと影の解像度上げたいなーという欲がでたので、欲を満たす作業をします。

下記画像くらい上げたいです。

画像21

まず Directional Light の Shadow Resolution 設定を「 Very High Resolution 」にします。(複数人で開発するプロジェクトで無断でこんなことしたら仲間から絶対に怒られるのでちゃんと許可を得てやりましょう。)

あとは Strength で影を少し薄くする(完全な好み)

画像22

とりあえず欲望は満たされたので、今回はこんな設定で終了します。

おわりに

以上がライトとシャドウの入門内容でした。
Unity の Light と Shadow 関連の設定は非常に多く、まだまだここに書いていないことがたくさんあります。

高品質なゲームを作るようになると、最適化のために Unity の Shadow は使わずに自分で Shadow 描画部分を作ったりする人もいます。
現実のカメラでも光と影は奥がとても深い(というか沼)ですが、Unity でもしっかりと沼は用意されているので、みなさんぜひ沼に浸かって楽しみましょう!

この記事が気に入ったらサポートをしてみませんか?