Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

Cardboardで360度立体視動画ビューワーを作る(4)

はじめに

過去3回に渡り、メーカーフェアー出展向けということで、360度立体視動画ビューワーを開発しました。前回は、Theta2台で撮影した360度映像をOculus CV1で再生する、というものを開発しました。これにより、Thetaから取り込んだ右目・左目用の360度動画をそれぞれ右目・左目にリアルタイム表示できるため「まるで自分がThetaの設置場所にいるような」感覚を作り出せます。
ただし、メーカーフェアー向けの出展物として考えると、Oculus1台だと見に来られたお客様の一部にしかVR体験をしてもらえませんし、また当初考えていた「Thetaをミニスタジアム内で動かす」ことにより作られた映像は思ったよりオモシロイものではありませんでした。
このような背景から出展物のコンセプトであった「Theta2台で撮影した映像をリアルタイムで閲覧」の「リアルタイム」をあきらめ、その代わりにVR(ある種ARっぽいですが)の特徴を活かし、CGとTheta撮影映像を合成して、自分だけのオモシロVR映像を作成し、その場で見れる・家族や友達に見せびらかせる、というものにしました。結果としてこのコンセプト変更はとてもうまく行き、メーカーフェアー期間中は、たくさんの子どもたちが当ブースでオモシロVRムービーを撮影、閲覧して楽しんでいってくれました。
以下では、本コンセプト変更により開発した「Theta映像とCGを重畳したムービークリップの作成と録画」について書いてみようと思います。
f:id:tuti107:20160530024145j:plain

Theta二台から立体視用Equirectangular映像をつくる

前回ご紹介したTheta Shader Packを利用して、上下にEquirectangular形式のTheta映像を並べてみます。なお、後ろ側については、視差が逆転してしまう、展示においても撮影者(=私)が映っているだけで価値が低いとの理由から、全面180度分のみを利用します。
f:id:tuti107:20160530030235p:plain
まずはCameraの設定ですが、以下のとおりとします。
f:id:tuti107:20160530030354p:plain
ポイントはProjectionをOrthographicとしている点です。こうすることで、Z座標を大きくしても表示の前後関係には影響しますが、遠近法で小さく表示されることはありません。今回は2つのQuad縦に並べて表示するだけであり、表示物に遠近感をつける必要がないため、このような設定としています。
左右Theta映像を映すQuadについては、以下のとおりです。表示位置とカメラ映像のインデックス(CamIndex)以外は同じ内容です。
f:id:tuti107:20160530030841p:plain

f:id:tuti107:20160530030848p:plain
ここまでは、前回とほぼ同様(Theta映像の貼り付け対象がSphere→Quad)です。なお、上記の通り360度全体ではなく、全面180度のみの利用にしておりますので、MaterialはThetaEquiRectangular(Forward)に変更しました。

CGと重畳する

次は、上記Theta映像の透過処理と、背景CGの作成です。まず、Theta映像の透過については、上記Materialに設定されているシェーダー用コード「ThetaRealtimeEquirectangular.shader」を一部修正し、緑色は透過とするようにします(いわゆるグリーンバックのクロマキー処理です)。なお、本ソースコードについては私の著作物ではありませんので、改修をした部分のみ、下記に記載します。

	SubShader
	{
		//Tags{ "RenderType" = "Overlay" "Queue" = "Overlay" "ForceNoShadowCasting" = "True" }
		Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" "ForceNoShadowCasting" = "True" }

		//ZTest Always
		Cull Off
		//ZWrite Off
		ZWrite On
		Blend SrcAlpha OneMinusSrcAlpha

まずは、描画順序の設定です。元々(コメント部)を非コメント部の内容に変更することで、背面にあるオブジェクトとTheta映像を映すQuadが重畳表示されます。詳細についてはシェーダ用コードの解説サイトをご参照いただければと思いますが、ざっくり、上記とすることでQuadの背面にあるオブジェクトも描画され、さらにQuadと重ねあわせた(透過部には背面のオブジェクトが表示)形式になります。
次に、frag(v2f i)関数の末尾に以下のクロマキー処理を追加します。

	half maxCol = col.r > col.g ? col.r : col.g > col.b ? col.g : col.b;
	half rateR = col.r / maxCol;
	half rateG = col.g / maxCol;
	half rateB = col.b / maxCol;
	if (rateG >= 0.9 && rateR < 0.8) {
	  col.a = 0.0;
	}

ピクセルの色が緑の場合は、アルファを0にして非表示とする、それだけの処理です。緑の判定は若干意味不明かもしれませんが、環境光等を考慮していろいろ試行錯誤した結果、このような条件となりました(最適、とは思っていません。。)。
次に背景CGについてです。背景CGについては「普通に」Unityシーン内にオブジェクトを設置し、Skyboxを設定して作成するのですが、最後にこのシーンを360度EquiRectangular形式に展開する必要があります。今回はDomeMaster Texture Generator for Unity利用しました。これを利用することで、シーン内に配置したオブジェクト群からFisheyeまたはEquirectangular映像を生成することができます。まずは上記をダウンロードし、DomeMaster.csと、Equirectangular.shaderをプロジェクトに取り込んでください。その後、適当なMaterialを作成し、シェーダーをEquirectanglarとしてください(私はER.matとしました)。
このマテリアルをはりつけたQuadを以下のとおり2つ生成します。
f:id:tuti107:20160530062639p:plain

f:id:tuti107:20160530062646p:plain
差異はY座標だけです。
つぎに実際に重畳する風景を作成します。私は、Moon Environmentというアセットを使いました。有料($30)ですが、リアルな月面風景を実現できるので、(そのような用途がある方に限りますが)おすすめです。
この風景は、適当に作成したEmpty Object配下に生成し、最後にレイヤーを設定してください。この背景が、以下で説明する背景のEquirectangular化以外のカメラに写り込まないようにするためです。
f:id:tuti107:20160530063431p:plain
またこの背景は、原点から遠い場所に設置するほうがよいです。実行時には特に影響はありませんが、エディット時にこの背景が原点付近にあると結構邪魔です。
最後に、背景をEquirectangular化するためのスクリプトを設置します。背景の中心に適当なカメラを設置し、Add Component→Dome Masterでスクリプトを追加します。さらに、カメラのCulling Maskを上記作成した背景のレイヤーと一致させます。これだけで、上記で設置した2つのQuadにEquirectangular形式の背景が描画されるようになります。
f:id:tuti107:20160530064313p:plain
これは、PCのディスプレイ右下に緑色長方形のものをおいて撮影したものです。その部分が透過され背景の月面が見えています。
なお、上記では背景は単一カメラで生成したものを両眼用に設置しているため、立体表示されません。上記のDome Masterを配置したカメラを2つ置くことで立体視対応もできますが、いろいろと複雑な改造が必要となってしまうため、ここでは触れません。

録画する

上記で生成したTheta映像とCGを重畳したものをMP4形式にエンコードします。本エンコードにはffmpegを利用しました。このffmpegにはNVidia GPUを利用したエンコード(nvenc)のオプションがあり、一般的には非常に高負荷な処理であるMP4エンコードを高速実施することが可能となります。第二回でMAC+OBSでエンコードの負荷が高すぎて全然フレームレートが出ない件についてふれましたが、nvencを利用すればこのような心配は不要です。ただし、nvencオプションはデフォルトのWindows用バイナリでは無効化されており、有効化するためにはffmpegをビルドする必要があります。
ffmpegのビルド(Windows版)は、こちらを利用すれば、そこそこの手間でビルドが可能です。ただ、VirtualBoxをインストールしたり、そこにUbuntuをインストールしたり、それでビルドをしてもエラーが多発したり、とそれなりに敷居が高いです。
nvenc対応のffmpegのビルドができたら、次に以下のスクリプトを用意します。

gist4b9ea7a85dc70d8b1d0eff515a7168c8
このスクリプトを適当なGameObjectに貼り付け、以下の通りインスペクタより設定します。
f:id:tuti107:20160531064738p:plain
突貫で開発した、ということもあり、まずffmpegを起動し、毎フレーム、インスペクタにてDisp Cameraに指定されたカメラの内容をjpeg化して標準出力でffmpegへパイプ渡し、MP4へエンコードする、という手順をとっています。速度性能はいまいちであり、nvencでがんばった分を差し引いても、当方のPC環境で20fpsがやっと、という感じです。この辺りは今後もう少し見なおしていいきたいと考えています。
なお、video Dirは、エンコードしたMP4動画を配置するディレクトリを指定します。ファイル名は生成時間で自動生成しています。

まとめ

これまで4回に渡り、メーカーフェア出展に向けた360度立体視動画ビューワ(+レコードアプリ)を開発してきました。開発期間が短く、かなり突貫実装となってしまいましたが、それでもたくさんの方(特にキッズ)に使ってもらい、喜んでもらえたというのは、開発者冥利につきます。
本件は、今後もブラッシュアップを続け、できればメーカーフェア東京にも出展したい、と考えております。本ブログを見ている方とメーカーフェア東京で出会えたら、非常に嬉しいです!

メイカーフェアー終了しました!

5月20日~22日、シリコンバレーのサンマテオにて開催されたメイカーフェアーに、VRシステムを出展しました。
本システム、THETA Sを2機使用して左右両眼用の360度立体視動画を撮影、本撮影映像のバックに「月面」「ハロウィーン風」等の背景を重畳して「オモシロVR映像」を生成、また作ったその場でGoogle Cardboardを利用して視聴できる、というものです。三日間でなんと214名の方(主にキッズ)が撮影し、その3-4倍の方に視聴して頂きました!お客様が休む間もなくひっきりなしに訪れる状況、ほんとうに疲れましたが、たくさんの方に楽しんでいただけて本当によかったです。
f:id:tuti107:20160524120838j:plain
今日から通常モードということで、まずは本開発技術について、ブログで書いていこうかと思います。

SVVRで見つけた興味深い技術たち

現在、5月21日に開催のメイカーフェアーに向けて睡眠時間を削りながら開発の毎日です。このような状況なので、開発ブログは少しお休みして、先月末に開催されたSVVRで見つけた興味深い技術をご紹介したいと思います。

VORTX

VORTXは、WhirlwindVRという会社が開発しているデバイスです。このデバイスは、VRコンテンツと連動して、強い・弱い/温風・冷風を発生させます。デモでは、自軍の城へ攻め込んでくるモンスターを撃退するというCGムービーに合わせて、例えばドラゴンが炎を吐いたら温風が、近くで爆発が起きたら強い風がくる、という感じで、風を利用してVRの臨場感を高めていました。端末がタワーPC並にでかく、ご家庭では一体どこに設置したものやらという感じではありますが、面白い端末だと思いました。
f:id:tuti107:20160513141243j:plain
なお数ヶ月中にSDKを公開する、とのことでした。

Cardboardで360度立体視動画ビューワーを作る(3)

はじめに

前回は、左右両眼用のThetaSのビデオ(RICOH THETA UVC BlendeによりEquirectangular形式に変換されたもの)を縦につなぎあわせ、OBSでHLS形式のライブストリーミングを生成、nginxで配信、Cardboard側で閲覧する、というシステムを作りました。しかし、一応動いたものの、遅延が激しく・フレームレートも出ない、との状況であり、実用には程遠い状況です。
今回は「リアルタイム性」を重視し、一度Cardboardを離れて、Oculus Riftで、左右両眼用ThetaSを利用した360度立体視を行ってみます。

UnityをOculus Riftに対応させる

現状Oculus Riftに対応しているUnityは、バージョン5.3.4p1及び、5.4βです。今回は5.3.4p1をインストールしました。5.3.4p1はこちらから入手できます。
次に、Oculus開発者サイトより、OVRPlugin for Unity 5をダウンロードします。ダウンロード後、C:\Program Files\Unity\Editor\Data\VR\oculusの内容を全削除した後、OVRPlugin_Unity5_1.3.0.zipを解凍したもので置き換えます。

Theta SのFish Eye形式動画をEquirectanguler形式に変換

前回記載した通り、RICOH THETA UVC Blenderを利用すれば、Equirectanguler形式で直接動画を取得できるため、変換処理等は不要となります。ところが、当方環境の問題なのか、Windows版の制限なのか、Theta Sを2台接続(両方ともTHETA UVC Registerで登録)した場合、いずれか一方のみのRICOH THETA UVC Blenderしか利用できません。再接続、再登録を何度か試みましたがうまくいかず。このため、Theta Shader Packを利用して、Unity側にて形式変換をすることにしました。
上記サイトよりThetaShaderPack_20150926.zipをダウンロード・展開し、適当なフォルダへ格納してください。次に、Assetsを右クリック→Import Package→Custom Packageを選び、ここで展開したThetaShaderPack.unitypackageをインポートします。
次にWebカメラの映像をテクスチャとして利用すべく、簡単なスクリプトを用意します(こちらを参考にしました)。

gistc83f1ae3dfa5c5c3f19f7ac346e3d48c
合わせて前回ご紹介したsphere100.fbxを用意します。Assets内の適当なフォルダに放り込んだ上で、2つこれをHierarchyへドラッグ&ドロップ、それぞれの名前をSphere100_L, Sphere100_Rとします。
インスペクタにて、それぞれ以下のように設定します。なお、camIndexはそれぞれ、左右用ThetaのFisheye形式UVCを指定してください(当方の環境では0及び1でした)。
f:id:tuti107:20160504123929p:plainf:id:tuti107:20160504123940p:plain
マテリアルには、上記インポートしたTheta Shader Packに含まれるThetaRealtimeEquirectanguler (Both).matを指定ください。
また、LayerをぞれぞれLEFT、RIGHTとしてください。
次に、左右両眼用のカメラを作成し、それぞれSphere100_L, Sphere100_Rのみ見えるよう設定します。Hierarchyにて右クリック→Cameraを二度実施し、作成したカメラをそれぞれCameraL,CameraRとしてください。CameraLは左目用なので、Culling MaskからRIGHTを外してください。またTarget EyeはLeftとしてください。同様に、CameraRはCulling MaskからLEFTを外し、Target EyeをRightとしてください。
最後に、File→Build Setting→Player Setting→Other Settingにて、Virtual Reality Supportedをオンとします。OculusはUnityにてネイティブでサポートされているため、CardboardのときのようなSDKのインポートや各種設定は不要、これだけでOculusで利用可能となります。
f:id:tuti107:20160504131534p:plain

まとめ

今回はOculusを使って、左右両眼用Thetaの入力画像をUnityで形式変換し表示するアプリを作成しました。またVirtual Reality Supportedをオンとして、本アプリをVR対応としました。前回のように、ストリーミング変換やライブ配信をやっていないこともあり、Thetaで撮影した映像をリアルタイムで楽しむことが可能です。またCardboardと比較して高画質・首の動きにすいつくようなヘッドポジショニングであり、非常に心地よいです。
ちなみに、詳細説明は省略しますが、前回同様Equirectanguler形式の左右映像を縦に並べ、OBSでエンコードし、nginxへアップロード・配信するアプリも作成してみました。前回のMACの場合のようにコマ落ちは発生しませんでした(NVidiaのH.264エンコーダのおかげかと思います。さすがGeForce970)。ただし相変わらず20秒程度の遅延は発生します。リアルタイムは難しいようです。

Oculusのインストールにはまる

待ちに待ったOculusがようやくきました。合わせて購入したOculusPC(ASUS G11CD)、起動するとOculus Downloadのアイコンが。
f:id:tuti107:20160501141241p:plain
Oculus Readyの認証をとっているPCということもあり、コンシュマー向け製品として簡単にインストールできるようになっているのだろう、とこの段階では思っておりました。まさかセットアップに6時間以上かかることになるとは。

Restart Computer

上記のアイコンからインストール用のアプリをダウンロード、すると800MB程度のデータのダウンロードが始まります。そして、ダウンロードが完了すると、以下が表示されます。
f:id:tuti107:20160501141521p:plain
エラーが発生した、という事実しかわかりません。とにかくリブートしろとのことなので、Windowsを再起動、その後再挑戦。また800MBのデータダウンロードがはじまります(キャッシュしてくれればいいのに)。そして、上記と同じエラーが表示されます。
何度か再起動→再挑戦を繰り返すも、結果は変わらず。インターネットでの情報さがしを始めました。
まだ発売して間もないこともあり、あまり情報がない状況なのですが、このページを発見。まずは、GeForceのドライバを最新にせよ、と。忘れてました。。ドライバを更新し、再挑戦。しかし同じエラー。
先ほどのページを読み進めると、
f:id:tuti107:20160501142643p:plain
レジストリをいじれ、とのこと。これコンシュマー用ですよね?
しかし上記の説明の通りにレジストリのプロパティーを表示しても「Reorder」というボタンが発見できません。だめならレジストリーキーを消してみて、との記述もあるため、削除して再挑戦を試みたものの、結果は同じ。毎回800MBのデータダウンロードが入るため、ここまでですでに4時間経過、もう諦めようかと考えていたところで重要な情報が。上記のページ内から参照されているこちらに、エラーログが「%LOCALAPPDATA%\Oculus\OculusSetup.log」に保存されており、そのエラー次第でいろいろ対策が必要な旨の記載がありました。さっそくログを調べてみると私の場合は
C:\Program Files\Oculus\Support\oculus-librarian\OVRLibrarian.exe exited with code 7 (failure).
でした。残念ならが本ページ内には対策の記載なし。そこで、上記エラーをキーワードとして調べてみると、こちらのページが見つかりました。なにやら、ウィンドウズの再インストールで治った等の不安を掻き立てる書き込みがある中、ウィルススキャンソフトをアンインストールすると解決した、との記載が。そこで、マカフィーセキュリティセンターをアンインストールし、再挑戦。ようやく問題解決!その後はすんなりインストールができました!

絶縁シールが引き抜けない

これでようやく、と思っていたところで最後の罠が。ソフトのインストール後、ハードウェアの設定を順次行うのですが、
f:id:tuti107:20160501145225j:plain
このコントローラの電池の絶縁シールが異様に固く、ペンチで引っ張っても引き抜けず、しまいには破けてしまい引き抜きが不可能になってしまいました。仕方なく絶縁シールが出ている口の部分にマイナスドライバーを入れて背面をこじ開けて、絶縁シールを引き抜きました(それでも固く、引き抜いたら電池も一緒に吹っ飛んでいきました)。僕のものだけ、たまたまなのでしょうか?

苦闘6時間

セットアップが終わる頃にはもう夜中の2時。アプリケーションを試す気力もなく、セットアップだけで終了、そのまま就寝しました。
まだ商品出始め、ということで、トラブルシューティングのノウハウもインターネット上に充分溜まっていない状況です。僕の上記のエラー以外にも、いろいろパターンがあるようです。今後Oculusを購入し、インストールする方は、ログから問題を特定し最短でトラブルシューティングを行うよう、ご留意頂ければ、と思います。

Lucid Cam

今日は地元で開催されたVRステレオカメラのミートアップに参加しました。このカメラLucidCamは、180度撮影可能なカメラを2機搭載しており、ステレオ4K動画(秒60フレーム)を撮影可能です。単純比較はできませんが、同価格帯の他社機よりハイスペックかと思います。
f:id:tuti107:20160427143255j:plain
左右カメラで撮影された映像は4KFisheye動画を横に並べた形式で保存され、専用のスマホ側アプリにて立体視360度動画として視聴可能です(ただし、本カメラは前方180度しか撮影できないので、後ろ180度は前方180度のコピーのようでした)。デモ映像の映像品質や立体感はなかなかのものでした。
本ミートアップでは、左右撮影映像のキャリブレーション技術について、詳細説明がありました。キャリブレーションが必要な歪みは3パターン(魚眼レンズによる歪み・センサー傾きによる歪み・左右カメラずれ)で、それらの検出方法と対処方法の概要について触れられました。
f:id:tuti107:20160427145224j:plain
値段は$399で、今年の12月に出荷予定とのことです。
気になる点は、ホームページにはビデオは2Kと書いてあるのですが、説明ではビデオ4K静止画8Kと言っていたはずなんだよなぁ・・(英語自信なし)