現実環境マッピング

Unity上のCGモデルに現実の景色をリアルタイムに反射させたい。というわけでまず、Webカメラでパノラマを撮る用意をします。そのへんに転がっていた2台の PlayStation Eye にケータイ用魚眼コンバージョンレンズ KSW-3 を装着。背中合わせにすればほぼ360°のパノラマ映像になります。

PSEyes

KSW-3はなぜかPS Eyeにぴったりはまる


Fisheye

魚眼映像。じつは画角170°なので2つ合わせても360°にならない。今回の用途には画角185°の後継KSW-4のほうが適しているが、ほかの用途も考え3にした

この映像をUnityに取り込みます。が、ここで問題が。PC用PS Eyeドライバ/SDKである CL-Eye の現最新版に、複数のPS Eyeを同時に扱う(異なるカメラとして区別する)ためのDLLが含まれておらず、Unityにプラグインできません。いろいろあがいてみたのですが結局自前でDLLを作ることに。加えて、C#におけるビットマップ転送(というかfixedメモリ操作)に必要なunsafe宣言がUnity上では許されないらしく、あいだに挟んでこれを回避するためのDLLも別途作らなければなりませんでした。

なんとか2つの魚眼映像を取り込めたら、合わせてキューブマップに変換します。ちゃんと計算すればスマートなのでしょうが難しそうなので、いったん球体にマッピングし、それを内側から6方向のカメラで取り込むことにしました。

魚眼から球へのマッピングは、2つの魚眼映像をそれぞれ半球状に押し出す(平面から半球へ射影する)だけ。具体的には、コードで生成した半球メッシュのX・Y座標(を正規化したもの)をそのまま魚眼テクスチャのUV座標とします。根拠なく直感的にやってみただけですが、見た目問題なさそうです。

FisheyeSphere

半球になった片側の魚眼映像。カメラが置かれる内側をポリゴンの表とする

そして球の中央に画角90°のカメラを置き、前後左右上下をテクスチャにレンダリングした結果がこれ。

FisheyeCube

画角やカメラ間距離のせいで今回は死角が大きすぎるが、録画すればちょっとしたパノラマ動画コンテンツも作れる

実際にはCameraクラスのRenderToCubemapメソッドでキューブマップを一括生成できます。それを反射シェーダに適用すればできあがり。まわりの様子がヌルヌル反映されてきもちいい。

Environment Mapping

反射像をよく見ると2つの半球の境目がわかる。わずかに重ねてクロスフェードさせると目立たなくなる