UnityのRhinocerosモデルに Reflection Probe で鏡面反射をつける

鏡面反射をビルの窓に加えるためにはどうしたら良いかという事をここ数日考えていました。ReflectionProbesというなんだかよく分からない物を使えばできるという記事はいくつも見つかりましたが、原理が腑に落ちるまで時間を要しました。ここにReflectionProbesを使った実験結果を記しておきます。

まず、参考にした記事を以下にいくつか挙げておきます。少なくとも初期のインプットとして頭に入れて置くべきだと思います。

ユニティ公式:リフレクションプローブ (Reflection Probe)

ユニティ公式:リフレクションプローブの使用

電脳ノート:リフレクションプローブ

結果から言うと、大体思ったような反射が得られるようになりました。下記の絵のようにビルに周囲のビルの映り込みが入るようになりました。

ReflectionProbesを理解する上で、小さい規模での実験がとても役だったので、まずはその話をします。第一にやるべきなのは、鏡面反射する鏡面マテリアルのsmoothnessとmetallicの値は1もしくはそれに近い値にします。1でやるのが一番安全側です。

これが1から遠ざかっていくとせっかくの反射が消えてしまうので、そもそも実験になりません。私はこの設定に注意を払っていなかったので数時間を無駄にしました。

次に、ReflectionProbesのバウンディングボックスの大きさは映り込みが入るオブジェクトを十分にカバーできるサイズにする必要があります。バウンディングボックス外のオブジェクトにはReflectionProbeで作成したマップは適応されません。このボックスは映り込むオブジェクトの範囲ではありません。写り込むのはCullingMaskのチェックが入っているレイヤーに存在するオブジェクト全部だと思います。(CullingMaskについては後述)

例えばビルの窓にオブジェクトを映したい場合、ビルをバウンディングボックスが包有する必要があるという事です。

すると、今まで映らなかった映り込みがやっと写るようになりました。ただし、下の画像のように映り込みのスケールや角度がおかしいという事に気付きました。色々ReflectionProbeの位置を変えてみたのですが、なかなかピンポイントでココという場所が見つかりませんでした。

そこで参考になったのが下の記事で、写したい面に対して面対象にReflectionProbeを置いてあげるという事でした。個人的には下の図が一番わかり易いと考えていて、ReflectionProbeから見た風景がカメラへの反射と一致するのが面対象の場所という事になります。

おもちゃラボ:Reflection Probeで鏡面反射する床を作る

これによって、下記の絵のように、カメラに対して正しい反射が得られるようになりました。

これを応用してビルの窓に映り込みを映す事を考えました。ビルの各面に対して、それぞれ面対象の位置にReflectionProbeを置いてあげました。両側のReflectionProbeからのマップがブレンドされて表示される設定にしています。

ガラス面をインスペクター上で確認するとReflectionProbeが検出されているのが分かります。それぞれのImportanceが1として設定されているので半々のブレンド率になっているという事が確認できます。

ガラス面に移り込むビルの手前のビルが映り込まないように、ReflectionProbeのCullingMaskを使用しています。CullingMaskでは、レイヤーを指定してチェックが入っていないレイヤーを非表示にすることが出来ます。手前側のビルが邪魔をしないように、Probeに対して手前側の、オレンジに選択されたビル群を、レイヤーに指定して、チェックを外し、映らないように工夫しています。

これで、上手く映り込みがガラス面に反映されるようになりました。(映り込みを充分な解像度にするためにReflectionProbeのResolutionを調整しています。)

Rhinocerosモデルのunityへの取り込みについて詳しく知りたい方は下の記事もご参考下さい。

おすすめの記事