HoloLens のカメラ映像を使って Spatial Mapping にテクスチャをつける
こんにちは、たるこすです。
HoloLens の Spatial Mapping (空間マッピング) で作られるメッシュには色情報がありません。 そこで、今回は HoloLens のカメラ映像を使って Spatial Mapping にテクスチャをつけてみます。
うまくテクスチャがつけば、現実空間から見える映像と HoloLens によって見える映像が一致するはずです。これだけでは面白くないですが、テクスチャの色を変えたりモザイクにするなどの加工をすれば面白い映像を作ることができます。
ただし、今回作成したものでは現在のカメラ映像しか使っておらず、過去の映像を保存しておいて空間全体に色をつけるということはできていません。 空間全体にテクスチャをつけるものについては、以下のリポジトリのものを使って出来ましたが、そのままだと描画が重かったので変更が必要そうです。
他にも、twitter や youtube で動画を投稿されている方が何名かいらっしゃるので、ブログ等で手法を共有していただけることを期待しています。
Unity アプリケーションの作成
Unity で新しいプロジェクトを作成します。
HoloToolkit をインポートしたら、HoloLens 用のプロジェクト設定を行います。また、Capabilities の設定で Webcam, Spatial Perception にチェックを入れておきます。
シーンに存在する Camera を削除し、HoloToolkit に含まれる以下のプレハブを追加します。
- HoloLensCamera
- InputManager
- SpatialMapping
また、空の GameObject を作成し、SpatialMappingReprojection という名前に変更します。
次に、以下の 2 つのスクリプトを作成します。
SpatialMappingReproject.cs
SpatialMappingReproject.cs では WebCamTexture を作成します。WebCamTexture ではリアルタイムにカメラ映像がテクスチャに反映されます。また、Spatial Mapping でメッシュが作成された際にメッシュに MeshReproject を付け加える処理も行っています。
MeshReproject.cs
MeshReproject では、メッシュの各頂点に uv 座標を設定します。uv 座標とはその点がテクスチャのどの座標に対応するかを表すものです。
Projection Perspective は Unity の Camera オブジェクトで、本来は HoloLens のカメラの外部パラメータ(カメラ位置)や内部パラメータ(焦点距離など)を反映させたものを設定します。しかし、HoloLens のカメラの座標やパラメータの取得がうまくいかず、今回は HoloLensCamera で代用しました。あとで出てくるサンプル映像で、現実の映像と HoloLens の映像がずれているのはこのためです。
カメラがたくさんでてきてややこしいですが、HoloLens についている物理的なカメラと、Unity のオブジェクトを 2D 画面に描画するための Unity 内のカメラ(HoloLensCamera)があるので注意してください。
マテリアル、シェーダーの作成
マテリアル、シェーダーによって、テクスチャがどのようにメッシュの色に反映されるかが決まります。
Asset で右クリックし、 Create > Shader > Image Effect Shader と選択して Shader を作成します。ここでは ImageProcessingShader という名前にしました。
作成した Shader を開くと、以下のようになっています。
まず、一行目の Hidden/ImageProcessingShader
を Custom/ImageProcessingShader
に変更します。
42~48 行目の frag 関数は以下のようになっており、デフォルトで色を反転するように設定されています。
fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); // just invert the colors col = 1 - col; return col; }
col = 1 - col
の行をコメントアウトすれば、テクスチャの色がそのまま表示されます。
まずは、デフォルトのまま進めてみます。
次に、Asset で右クリックし、 Create > Material からマテリアルを作成します。ここでは ReprojectionMaterial という名前にしました。
インスペクターで Shader を先ほど作成した Custom/ImageProcessingShader に変更します。
最後に、シーンにある SpatialMappingReprojection(空の GameObject)に Spatial Mapping Reproject をアタッチし、インスペクターで以下のように設定します。
以上で完了です。
実行
プロジェクトをビルドし HoloLens で実行すると、以下のように色が反転して表示されます。
モザイクをかけてみる
シェーダーを変更することでモザイクをかけてみます。
先ほど作成したシェーダーの 46行目 col = 1 - col
をコメントアウトし、以下の行を追加します。
float _Range = 64; col = tex2D(_MainTex, floor(i.uv * _Range) / _Range);
実行すると、以下のようになりました。
他にも、いろいろと処理を変えてみたり、特定の色だけに別のテクスチャを張り付けたりしても面白いかもしれません。良ければ試してみてください。