Unity+Oculus+MMD とりあえず書き留めておく場所

Unity+Oculus+MMD VRでキャラクターと遊ぶ

8. Unityの照明効果②(PointLight・SpotLight・AreaLight)

今回は、前回説明しきれなかった残りのLightについて説明していきます。

Lightの追加

Hierarchy上で右クリック→「Light」から、4種類の照明を簡単にSceneに追加することが出来ます。

f:id:emifuwa:20171127104532j:plain

まず、「Point Light」をSceneに追加してみましょう。

新しくオブジェクトを追加した時、もしかすると、位置が「0.0.0」のところに行かないかもしれません。

そうしたら、とりあえずTransformコンポーネントでPositionの値を全部ゼロにしてください。

 

説明の前に、光がわかりやすいように、世界を暗くしておきましょう。

あらかじめ「DirectinalLight」のTransformコンポーネントのRotation(角度)を-150にし、更にIntensityを0にして真っ暗にしてください。

f:id:emifuwa:20171130153121j:plain

そして、PointLightの位置を「0.0.0」にすると、こんな感じです。

f:id:emifuwa:20171130153431j:plain

Point Light

この状態のままではPointLightがどんなものかわかりにくいので、いったん視点をロングに引きます。マウスのスクロールホイールで少しズームアウトしてみましょう。

f:id:emifuwa:20171201222546j:plain

イエローのラインで出来た球形が見えます。

PointLightは、この球形の中心点から全方向に広がる光です。例えるなら、電球に近いです。

球の中心点から半径の距離「Range」になります。

光はRangeの中(球の中)のオブジェクトすべてを照らし、光の強さは距離が離れると減衰します(DirectinalLightは減衰しません)。

現時点ではPointLightがまったく目立っていない状態ですが、

PointLightの位置をあげてみたり(PositionのYの値をあげる)、Rangeの値を上げてみたり(光の到達範囲が広がる)すると、この照明の特性がわかってくるかと思います。

f:id:emifuwa:20171201223303j:plain

暗い場所をふわっと明るくしたり、焚き火の炎の明るさを表現する時など、このライトを仕込んでおけば自然な明るさが表現できるでしょう。

設定するのは、Position(位置)・Range(到達範囲)・Intensity(光の強さ)あたりが重要になります。

f:id:emifuwa:20171201225045j:plain

 Spot Light

次はSpotLightです。

とりあえずモデルと同じ位置にSpotLightを出現させたいので、まずモデルを選択。

選択した状態のまま、右クリックでSpotLightを選択します。

f:id:emifuwa:20171201230150j:plain

そうすると、SpotLightがモデルの「子」オブジェクトとして追加され、「親」であるモデルと同じ位置に出現します。

f:id:emifuwa:20171201230320j:plain

ずっとくっつけておきたければそのまま。

分離させたければ、Spotlightを下の方にドラッグすれば、「親」から外れます。

f:id:emifuwa:20171201230544j:plain

とりあえずここでは「親」から外して、一つの独立したオブジェクトとして扱います。

オブジェクトの親子関係については、この記事の一番下で説明します。

※ところで、このように別のオブジェクトを親として設定した場合、位置だけでなく大きさも親のサイズを受け継ぎます。ここではモデルの大きさを1.2にしていたため、ライトもScaleが1.2となっていますが、ライトは大きさが変わっても光量などに影響はありません。

 

この状態(0.0.0)だと地面に埋まっていてわかりにくいので、PositionYを1.5にしましょう。

イエローのラインが円錐形に伸びているのがわかります。

f:id:emifuwa:20171201231838j:plain

Spotlightは名前のまま、円錐形に放射される光がスポットを照らします。

Rangeで光が届く範囲の距離を、SpotAngleで光が届く範囲の広さを指定します。そして、このライトも減衰します。

人工的な光を表現するのに向いています。ステージライト、懐中電灯、車のライトなどに良く使用されます。

f:id:emifuwa:20171201233023j:plain

PositionのZも移動し、モデルを後ろから照らしました。Angleをかなり広げ、照射角度を広くしています。

SpotLightはPosition(位置)・Rotation(角度)・Range・SpotAngle・Intensityの設定がメインになるでしょう。

気を付けることと言えば、Rangeの長さです。

例えばいわゆるステージのスポットライト的に床を照らしたい場合、Rangeの長さを床ぴったりに合わせてしまうと、Spotlightは距離が離れるほど光が減衰するので、底辺の部分では減衰して床に光が映らなくなってしまいます。

照らしたい部分は、壁や床を通過するようにRangeを設定しましょう。

Area Light

AreaLightは、今まで紹介してきた3つの照明とは少し違います。

基本的に長方形の形をしていて、「片面が光る板」のようにオブジェクトを照らします。

f:id:emifuwa:20171202202621j:plain

ですが、照らす対象は、静的(Static)なオブジェクトだけです。

例えば、大きな部屋の中で絶対に動かない家具や小物などをStaticに設定し、このライトを置いて焼き付けることによって、あまりデータを重くせずに、他のライトよりも繊細でニュアンスのある影を落とすことが出来ます。

その代わり、配置に悩んでStatic設定した小物を動かすたびに焼き付け直す必要があります。Bakeは空間が広く大きいほど時間がかかりますので注意。

上の画像でStaticとして設定しているのは、床、それに球と正方形のみです。モデルはStaticでないので、照らされていません。

また、今までのライトは全てリアルタイムで処理出来ましたが、このライトはBake(焼き付け)が必要になります。

 

オブジェクトをAreaLightに照らされるようにするには、オブジェクトを選択し、Inspectorタブの上部右上にある「Static」にチェックを入れます。

すると、下の方にある「Mesh Renderer」コンポーネント「Lightmap Static」にも、自動的にチェックが入ります。

Lightmap(ライトマップ)とは、反射光や影を焼き付けたテクスチャのことです。

f:id:emifuwa:20171202205155j:plain

「Cast Shadows」はとりあえず「On」にし、Receive Shadowsにチェックを入れます。「On」以外の項目は、実際に試してみた方が結果がわかりやすいかと思います。

次は、AreaLight自体の設定です。

重要なのはPositionRotation(Scaleは反映されません)、照らす平面の大きさは「Width」「Height」で設定します。光の強さはIntensityです。

f:id:emifuwa:20171202210546j:plain

ライトの角度を変えてみると、こんな感じになりました。

f:id:emifuwa:20171202210921j:plain

え、でもじゃあこのAreaLightを、動くオブジェクト(静的でない)であるモデルに適用するにはどうしたらいいの?ってなりますよね。

StaticでないオブジェクトにAreaLightを適用する…ことは出来ないのですが、「適用してるっぽく見せる」には、ここでは詳しく説明しませんが、「Light Probe」というものを設置する必要があります。

f:id:emifuwa:20171203112255j:plain

とりあえずLightProbeを置いてみました。

モデルにもAreaLightの光が反映されているのがわかります。

docs.unity3d.com

更に、Sceneに鏡面で出来たような、周囲のものが映り込むオブジェクトを置く場合、ちゃんと映り込みを反映させるには「ReflectionProbe」が必要になります。

いやいやそこまで精密な画作り必要ないんで…という場合は、この2つは無視して構わないでしょう。

 

これらの照明を様々に組み合わせて、Sceneを美しく彩ることができます。

ただし、無尽蔵に増やしていくと、もちろん重くなりますので注意が必要です。

照明の照らし方ひとつで、モデルの美しさ、場面の説得力が大きく変わってきます。

とりあえず照明についての説明はこれだけにしますが、もっと色々やってみたい場合は、突っ込んで調べてみることをおすすめします。

Unityの親子関係・グループ化

オブジェクトをSceneに追加する時、必ず「0.0.0」の地点に現れるわけではなく、変な場所に配置されてしまうことが(よく)あります。

そんな時は、「いったんSceneに既に存在するオブジェクトの『子』にしてしまう」と、親になったオブジェクトと同じ場所に配置されます。

f:id:emifuwa:20171130143059j:plain

D&DでHierarchyにオブジェクトを持っていく場合は「既存オブジェクトの名称の上に新しいオブジェクトを重ねるようにドロップする」ことで「子」になります。

右クリックでLightやCameraを新しく配置したい時などは、「既存オブジェクトを選択した上で右クリックしオブジェクトを追加する」ことで「子」になります。

例えば、モデルの位置の真上にスポットライトを配置したい!という時…

モデル選択→その状態のまま右クリック→SpotLight追加…とすれば、モデルと同じ位置にSpotLightが配置され、あとは位置を上の方に動かせばいいだけ…という風になります。

f:id:emifuwa:20171130143403j:plain

いったん「子」にしたあと、Hierarchy上でD&Dしてしまえば、オブジェクトの位置はそのまま、親子関係は外れます。

f:id:emifuwa:20171130150832j:plain

親子関係になると、「親」を動かせば「子」も一緒に動いてしまうので、不要な場合は親子関係を外しましょう。

「この車にこのモデルを乗せたい!」時などは、車を親にし、モデルを子にしたりします。

これに似た関係としては「グループ化」というものもあります。

グループ化は「部屋+家具」のように、たくさんのオブジェクトをまとめておきたい時などに便利です。

部屋に配置する家具オブジェクトや小物オブジェクトがたくさんある場合、Hierarchyがそれらの名前でいっぱいになって、ほかのオブジェクトを視認するのが大変になってしまいます。

そんな時、Hierarchy上で右クリック「Create Empty」とすると「Game Object」という空っぽのオブジェクトが出来ます。

この中にひとまとめにしておきたいものを全部入れておくと、必要ない時は中身を表示せずに一つのオブジェクトとして置いておけます。

必要な時は、ツリーを開いてそれぞれのオブジェクトを編集すれば良いのです。

例えば、SkyBoxはMMDにおけるxファイル形式のスカイドームのように、回転させることが出来ません。あっちに出ている月をモデルに背負わせた構図にしたい!という時などに困ってしまいます。

なので、空を回転させるのではなく、モデルやステージなどを回転させてしまった方が楽です。

GameObjectにモデルやステージを全部配置したものを入れ、GameObjectを回転させてしまえば、簡単に目当ての場所にステージやモデル一式を配置することが出来ます。

 

親子子は親を基準に移動・回転・拡大縮小する。親が動けば子も動く。

グループ化オブジェクト同士が並列。他のオブジェクトが移動しても一緒に移動はしない。

 

これらの関係を上手く使って、Sceneを構築していきましょう。