本記事は2018年6月2日に VR アカデミーで講演した内容のブログ版になります。
はじめに
今回と次回の2回にわたって、最新の Unity の機能を用いた画作りのテクニックを紹介します。
今回はライトとシャドウ編です。(本稿は Unity2018.1.4 を使用しています。)
「プロジェクトを作ったときに特になにもしなくても Directional Light が置いてあるがそれ以外になにがあるのだろうか。」
「なんか色々と light の種類あるけどどう違うの?」
っていう方々向けの記事となります。
光あるところに影は生まれるのでこの2つは一緒に扱っていきます。
Forward と Deferred
本題に入る前にまずザックリと Forward レンダリングと Deferred レンダリングについて復習しましょう。
Forward
ライト毎にレンダリングを行います。ライトが複数有る場合はライトの数だけレンダリングを繰り返します。(Unity では遠距離のライトなどは簡略化されて纏めて計算される)
- ライトが増えるほど重くなる
- VRAM の消費量が少ない
- モバイル、ローエンド向け
Deferred
ライティングやテクスチャなどは一旦後回し(Deferred)してとりあえずオブジェクトをレンダリングします。その過程でライティングなどに必要なデータを G-Buffer に書き出して最後に描画を反映させます。
- ライトをたくさん置ける
- G-Buffer に沢山の情報が残っているのでポスプロがしやすい(Deferred でしか出来ないポスプロがある)
- VRAM の消費量が多い
- 半透明処理がつらい
- ハイエンド向け
今回重要なのは Forward と Deferred でライトの扱いに差があるよーという部分だけなので細かい説明は割愛しますが、細かい部分知りたい方は下記の記事がおすすめです。
「いけにえと雪のセツナ」グラフィック解説(第3回・シェーダ編)
【 Unity 】 Forward レンダリングと Deferred レンダリングの違いを軽くまとめてみた
今回は下記理由により Forward 設定でライトとシャドウを解説していきます。
- モバイルで動かす予定
- ライトの数が少ない(2つだけ)
- Deferred でしか使えないポスプロを使う予定がない
ライティング
それでは本題のライティングの話です。
Unity でライティングを行う方法は大きく分けて3つあります。
- Light オブジェクトによるライティング
- Light Probe によるライティング
- HDR 撮影の全天球画像をつかったイメージベースドライティング
それでは各々細かい話と上記の派生形の話をしていきます。
Light オブジェクトによるライティング
プロジェクト生成初期状態から置いてある Directional Light を初めとする基本的なライティング方法です。使える light は全4種類あります。
Directional Light
デフォルトで存在するライトです。太陽などのはるか遠くにある巨大な光源をシミュレーションするもので、空間のどの場所でも等しく平行に光が降り注ぎます。また減衰などもしません。 Unity での一番基本となるライトです。
Point Light
一点を中心に全方向へ光を照射するライトです。中心から距離の二乗に反比例して減衰していきます。ろうそくの光や電球などの光で使用します。全方位に光を照射するので地味に計算が重い。
Spot Light
設定した方向のみに光を照射するライトです。中心から円錐型に光が広がります。懐中電灯や文字通りスポットライトなど指向性があるライトを作る時に使います。
Area Light
点ではなく長方形の平面から照射するライトです。現実世界では厳密には点光源が存在しません。実際の光源は表面積を持っています。豆電球ならその表面積分の光源であり、蝋燭や蛍光灯も点ではなく面で光っています。それを再現できるライト。写実的な光を表現できる上に柔らかな影が出てとても良いライトです。
しかしこのライトは計算が重くリアルタイムに計算ができないため Baked Light という扱いになっています。
Baked Light
Unity には Light を Bake(事前計算)するという方法があります。焼く手順は
まず Light の Mode を Mixed か Baked に変更します。
そして Bake したいオブジェクトを Static にします。
以上の方法で自動で Light が Bake されます。
ですがこのままだと Scene を少し弄るだけで何回も Bake が走ってしまって作業がとても重くなってしまうので Editor の「 Lighting 」タブの設定にある「 Auto Generate 」の OFF にしておきましょう。これでその横にある「 Generate Lighting 」を押すまでは勝手に Bake されなようになります。
注意点としては Static にしないと焼けないので動くキャラクターなどには適用できないという点です。あとは希にあるのが Scene 内部で部屋のモデルなどがあった時に全て Static にしてしまうと時計の針など動くように設定していたものが全て動かなくなるので後々見つけて「あっ」って事があります。
また、 Bake した後にオブジェクトを動かしてそのまま Generate Lighting を押さないとこんな感じで影が残っちゃったりするので注意しましょう。(見ればすぐにわかる問題なので、押さないで放置してしまう事はあまり無いとは思いますが)
Global Illumination(GI)
間接光、間接照明のシミュレーションができる機能です。フォトリアルな表現では必須機能です。
プリレンダ CG 界ではかなり前からの必須機能ですが計算負荷が重いためリアルタイムでは厳しい……。というわけで Baked GI という事前計算で GI が表現できるシステムが出来ました。(簡略化して実行するリアルタイム GI というものもある)
使い方は GI の設定を ON にして「 Generate Lighting 」で Bake するだけです。(Bake なので Static のオブジェクトしか演算できない)
うまく行くと下画像のように赤いオブジェクトの色が別のオブジェクトに影響を及ぼす事ができるようになります。
Light Probe
ここまで紹介してきた Baked Light 、 GI の影響を動くキャラクターなどに反映させたい!という時に使う機能です。
Light と GI を Bake した Static なフィールドでキャラが浮かないようにするには、 Light Probe を使ってキャラにも GI が掛かるようにする必要があります。
機能としては、 Probe(探針)を任意の場所に置いてそこの光の情報をベイクする。リアルタイムで動くオブジェクトは自身の近傍の LightProbe の光を描画する。といった機能になります。
使い方はまず、 Hierarchy で右クリック→ Create → Light → Light Probe Group で Probe を作成します。
すると Scene 画面に黄色い Probe が数個置かれていると思います。この Probe がある位置の光の色、強度を記録してリアルタイムに動くオブジェクトに反映させることができます。
Probe の数は Inspector で増やしたり減らしたりできますし、 Probe 自体を Scene 画面で選択すれば移動もできますので、キャラクターがよく歩く場所は密度を高めに、遠くは少なめにといった事や光が複雑に混じり合うところは多めになど自由に調整できます。
Probe の数が増えれば増えるほど Bake 時間が伸びてきたり実行時の処理負荷にもなるので使うデバイスに応じて Probe 量は調整していきましょう。
Light Probe も Bake の必要があるので配置が終わったら「 Generate Lighting 」を押しましょう。
以上を設定した結果が下記画像です。黄色で囲まれた丸い Sphere は Static オブジェクトではないですが LightProbe を使う事で回りの Static オブジェクトの赤色が反射するようになりました。
Image Based Lighting(IBL)
全天球の HDR 画像をベースに、色や明るさなどからライティングを行う方法です。実写全天球画像を使えば、現実のライティングがある程度再現できるのでフォトリアルな物を作る場合はあると便利です。あと金属物の反射画像にも使えます。
しかし影は出ない
↑重要
使い方は
まず全天球の Material を作ります。
作った Material を Lighting タブの Skybox Material に突っ込みます。
以上。簡単です。 Skybox の回転調整をしたい場合は Material の Rotation を弄れば天球を回転できます。
最近はこれを設定したあとに Light オブジェクトとかで微調整していく流れが好みです。
シャドウ
続いて影の話です。基本的には Light の設定をしていればもう勝手に影は出来ている筈なのでここではその影についての情報を補足していきます。
説明用に下の画像の和室を使って説明していきます。
影の解像度の話
ライトの説明で多種のライトオブジェクトを紹介しましたが、実はライトごとに影の解像度が決まっています。
比率にすると以下のとおりです。
ライトの種類 | 解像度 |
---|---|
Directional Light | 2(1.9) |
Spot Light | 1 |
Point Light | 0.5 |
出典:【 Unity 】リアルタイムな影がカクカクになる問題の対処
なぜ比率なのかというと Quality Settings や Light の設定で解像度を変更できるため、ここでは同じ品質設定だった場合はこの比率で解像度が違うということです。
上記特徴から各々のライトを使うべき場所が見えてきます。
Directional Light
広い範囲を照らすためのライト、大きい範囲を照らす専用にして複数はあまり設置しない。(ゲームの舞台が別の星で太陽が二個あるとかなら複数設置しちゃっていいと思う)
Spot Light
Map の明るい場所を表現する場合などに使用するライト。
Point Light
Map のディティールを調整するためのライト。影響範囲を広くするとあからさまに影が劣化するので影響範囲は極力狭くする。
影の解像度を意識してライトを設置
用意した和室の外には庭園があります。
木々が風でゆらめくのでライトとシャドウはベイクせずにリアルタイム主体で調整します。
まず IBL を設定します。使った画像は IBL の説明のときに使った青空の画像を使ってます。
そして Directional Light をまず設置するのですが、用意した IBL 画像には太陽が書かれていない……
仕方ないので適当に良い感じの角度でライトを配置します。
続いて外には木々の緑があるのでその光の反射を再現するために緑色の Point Light を設置します。
つまり擬似的な Global Illumination 再現ライトです。なぜ GI をベイクしないのかって?
ベイクする時間短縮と疑似再現でも問題なさそうなのと Light Probe を置くのがめんど(以下略
実際問題 GI を無理に Bake しても品質が向上しないのであればこういう逃げ方はありだと思います。
障子は基本的にある程度光を透過します。(少なくともうちの実家にあるものは)
擬似的に太陽光が透過してるように見せるため、障子のマテリアルの Emission の数字を1以上にして発光させることで太陽光の透過を表現します。また、不透明度を若干下げてやることで障子同士の重なりを見せたり、木々の影のような物を見せたりもできます。
ちなみに Emission を1以上にあげても Static で Bake しないとそれっぽく光らないという点には注意が必要です。リアルタイムで光ってるように見せたい場合は Image Effect などで Bloom を設定し光を表現する必要があります。
Image Effect(ポストプロセスエフェクト)については次回解説します。
影の解像度を調整
最後にちょっと影の解像度上げたいなーと欲がでたので欲を満たす作業をします。
下記画像くらい上げたいです。
まず Directional Light の Shadow Resolution 設定を「 Very High Resolution 」にします。(複数人で開発するプロジェクトで無断でこんなことしたら仲間から絶対に怒られるのでちゃんと許可を得てやりましょう)
あとは Strength で影を少し薄くする(完全な好み)
とりあえず欲望は満たされたので今回はこんな設定で終了します。
おわりに
以上がライトとシャドウの入門内容です。 Unity の Light と Shadow 関連の設定は非常に多くまだまだここに書いていないことが山程あります。
また高品質なゲームをを作るようになると最適化のために Unity の Shadow は使わずに自分で Shadow 描画部分を作ったりする人もいます。現実のカメラでも光と影は奥がとても深い(てか沼)ですが Unity でもしっかりと沼は用意されているので皆さんぜひ沼に浸かって楽しみましょう。
それではまた次回 アディオス!