RICOH THETA SのUnity上でライブビューパノラマ展開まとめ(メモ)

1.概要

前回のまとめ以降、ようやく触る時間と機材が出来たのでUnity上でTHETA SのHDMI Liveviewを追試しました。

イメージとしては凹みさんの

tips.hecomi.com

です。

  • THETA Sの取得できる画像、動画フォーマット一覧
  • HDMIキャプチャ方式のハードウェア紹介
  • Unity上でのHDMIキャプチャ経由の動画読み込み方法
  • Unity上での Dual Fish Eye → Equirectangular変換

みたいな内容です。

2.THETA Sの取得できる画像、動画フォーマット一覧

こんなイメージです。 f:id:izm_11:20151105014235j:plain 今回はHDMI Dual FishEyeを使います。

非リアルタイム

  • 静止画 5376 x 2688 Equirectangular
  • 動画 1920 x960 Equirectangular

リアルタイム

  • Dual Fish Eye (HDMI 1920 x 1080 インタレース60FPS)
  • Dual Fish Eye (USB2.0 UVC 1280 x 720 30FPS)
  • Equirectangular (スティッチ済みライブビュー、THETA API 640x320 MJPEG ストリーム)

3.HDMIキャプチャ方式のハードウェア紹介

HDMIからのキャプチャボードは色々な種類があります。最近だとスプラトゥーンの録画などでも皆さま買われてますが、あれも使えます。 OSから見た時に

  1. UVC(Webカメラ)として見える物
  2. キャプチャボード(direct showフィルタ)で見える物

という2種類の物が今回は使えます。 市場に出ているのは殆どすべてが2.です。

a.UVC-HDMIキャプチャボード Febon198(今回の秘密兵器!)

以下の2個をセットで買いましょう!

Febon198 http://www.amazon.co.jp/dp/B014QQXKVO/armneon-22/www.amazon.co.jp

HDMI Signal Converter

www.banggood.com

Febon198は OSからはUSB3.0の1080Pで60FPSなWebカメラとして見える、Febon198内の遅延は50-80ms程度(*1)、というトンデモないスペックの一品です。

デメリットは

などです。

Febon198はプログレッシブ信号しか受け付けないので、THETA含むデジカメからのインタレースな1080iなHDMI信号を読ませるには

HDMI Signal ConverterみたいにHDMI信号をなんでも1080Pに変換してくれるオモチャボードを通しましょう。

PCモニタ出力やXBOXの出力は1080Pなので、そういうのをキャプチャするだけならオモチャボードは不要なのですが、デジカメからの信号はインタレースが多いようです。ご注意ください。

セットで買わないと、こんな風に寝込む羽目になります。

b. 定番:BlackMagic Intensity Shuttle

ご存じ定番のBlackMagic!
なんでも読めるし、SDKも公式配布でフレームごとガバっと持ってこれて最高です。

http://www.amazon.co.jp/dp/B007ZDHDRS/armneon-22/www.amazon.co.jp

これを使えば大体のHDMI信号は読めます。ド定番!最高!!

b. その他キャプチャボード

遅延が大きいハズレもあったりする印象。2万円程度?

TL見てて動いたという話があるのはGC550など

http://www.amazon.co.jp/dp/B00ZOXYQ26/armneon-22/www.amazon.co.jp

4.Unity上でのHDMIキャプチャ経由の動画読み込み方法

a. UVCキャプチャボード

Unity標準のWebCamTextureを開いて再生するだけです! こんな感じのスクリプトを、適当にUnityのPlaneにアタッチします。 Thetaの再生用 · GitHub

b. DirectShowフィルタキャプチャボード

ここが結構大変な印象です。

BlackMagic系や、一般的なキャプチャボードなら AVPro Live Camera

https://www.assetstore.unity3d.com/jp/#!/content/3683 を使えば大丈夫だと思います。トライアル版で必ず事前に動作は確認してください。

尚、このアセットですが 200ドル と、比較的お高いです

(だからこそFebon 198を今回お勧めしてます。こっちは読むのタダですからね!) (他に安価な手段があるかもしれません。情報お待ちしてます!)

5.Unity上での Dual Fish Eye → Equirectangular変換

凹みさんの方法(前述)と

Stereoarts(Noraさん )の方法があります。 Stereoarts Homepage (Theta Shader Pack)

今回は後者のNoraさんのTheta Shader Packを試しました。

手順を念のため録画しました。一発撮りです。

www.youtube.com

Theta shader Packと、このスクリプトで作業しました。(部屋が散らかっていてお恥ずかしい) Thetaの再生用 · GitHub

Unity上でビルドしたexeを動作確認用に置いておきます。 Febon 198か、USB接続のLiveviewモードなら、再生できると思います。 https://copy.com/L6wAq9dYdIOrIHp1

6.今後やりたいこと

生放送時のパノラマ配信インフラがどこかにないかなあと気になってます。ちゃんとした法人契約じゃなくても、個人でちょろっと試せる場があると嬉しいです。

補足

HDMIキャプチャボード越しの遅延チェック

*1:本家スペック表による。 Theta→Febon198→Unityの遅延はこんな感じで測ると260-300ms程度です。どうやらThetaの絵を読み込んでHDMIから出すまでは、100ms以上のタイムラグがあるようです。

THETA SのUSBライブビューモードの認識手順

USBケーブルをPCとつながずに 写真動画切り替えボタンを押しながら電源を入れる→LiveviewモードになってからPCにUSBケーブルを刺す

という順番です。意外と忘れがちです。

ライブビュー経由で見る時の画質劣化

Dual Fish Eyeの時の実効解像度から考えて

  • HDMI経由で130万画素相当
  • USB経由で50万画素相当

くらいまで欠落してます。1920x960のスティッチ済み動画と比べるとHDMI経由でも3-4割くらい落ちてる雰囲気です。

RICOH THETA S 発売したので、個人用メモ

概要

ついに念願の動画も取得できる安価で安心な全球カメラが出ました!

TL上ではハックが進んで有益情報も多いですが、twitter上の内容で散逸してしまうと勿体ないので、メモとして記載します。

Unity上で見る方法

tips.hecomi.com

USBキャプチャ(720P 15FPS)

UnityのWebCamTextureからそのまま読めたと思います。
後は上記凹みtipsさんの記事を確認すれば大丈夫そうです。

HDMIキャプチャ(1080P 30FPS)

まずハマりがちなのが、「Modeボタンを押しながら電源ONでLiveモード(HDMIパススルー)」を選んでやること。

BlackMagicのIntensityとかのキャプチャボードで良いやつを買って Blackmagic Design: Intensity

AVPro Live Camera(200ドル) https://www.assetstore.unity3d.com/jp/#!/content/3683

を買うと言うのが一番楽なようです。少しお高いですが、安心感があります。

この時の遅延は最小で200ms位?

また、directshow互換で絵を持ってくることが出来るキャプチャボードもあるので、

www.amazon.co.jp

これもwindows上だと何とかしやすそうです(2万円程度) ただ、WebcamTextureでは読めないはずなので、上記AVPro Live Cameraが必要?

個人的に安くて気になるのがUVC互換のUSB3.0-HDMIキャプチャボード

FEBON: FEBON198 USB3.0 UVC HDMI Grabber Card User Manual

www.youtube.com

このキャプチャスティックが額面通りの性能なら、OSからはUVC対応のwebカメラとして認識されるので、UnityからそのままWebCamTextureとして取得できる気がします。

USB,HDMI併用時の3脚固定方法

スマートな方法だとこれが良さそう?

これを買って上のプラ部分を外す感じで www.amazon.co.jp

「いかにも使えそう」な、これは各端子と微妙に干渉するので不適

www.amazon.co.jp

360度配信向け機材

適当なスマホ+Cerevo LiveShell + THETA Sが今のところ良さそう。

ケース

純正ケースがギッチギチで凄く機動性を損ないます。
(一日差し込んで伸ばすと大丈夫という意見もあり)

最高にお勧めのケースは現在絶賛売り切れ中みたいです

www.amazon.co.jp

その他tips

Blenderのスフィアマップ適用

パノラマ合成

長時間HDMIパススルーで使うには、USB給電にして1A以上出るモバイルブースターに繋ぐのも必要ですが、    その前に本体を満充電にしておく。そうしないと、充電の熱で10分くらいで映像が止まったりする…
(逆に、満充電にしてUSB給電モードで使うと30分は連続で動きました)

2015/8現在のOculusRift+UnityのノートPC対応 開発動作環境構築

概要

OculusRift CV1(コンシューマ向け)の発表も近づいてきたので、OculusVR社は自社OculusSDKやOculusRuntimeを積極的にアップデートしています。

また、最新版の各種ゲームエンジンでは組み込みでOculusRift対応を進めています。(UE4は前から、Unityは5.1から)

そんなタイミングですが、最新のOculusSDK0.7以降では動作未保証になってしまったOptimusノートPC+Unity5.1でOculusRiftDK2の動作環境を作ってみようと思います。 色々検討した結果、今回はExtendModeなら最低でも動きそうな0.5.0.1環境にします。

プログラマ向けの手順をこれから書いていくので、分かる人は読み飛ばして「最後にまとめ」だけ読んで頂ければと思います。

(主婦ゆに本の、Unity5対応版も購入者は手に入れられるはずなので、ご検討ください)

このエントリに書かれていない事

  • 最新のUnity5.1以降で導入されたUnityネイティブのVR support
  • OculusRuntime 0.7対応

準備する物(もしくは、動作環境)

UnityとOculusRuntime0.5.0.1はインストールしておいてください。 下の2個はダウンロードだけしておいてください。

環境構築

一発撮りで申し訳ないですが、Unity上での操作手順を動画で撮ってみました。 8分程度です。

www.youtube.com

上の動画で作った動作確認用exe

OculusRuntime 0.5で動作確認済みです。
このexeの価値は、Optimus環境でOculusConfigUtilityの机と椅子のデモ(Show demo scene)が、クラッシュする事が多いので、 Optimus機の方は、机と椅子のデモ代わりの普通の動作確認にお使いください。

https://copy.com/Y22DH1oo7bXSSvuB

最後にまとめ

  • Optimusノートで動かす可能性があるコンテンツは、現時点でSDK0.5.0.1で作るしかないので、その環境を作る
  • Unity5.1以降であっても、VR Supportを使わなければ、普通に OculusUnityIntegration.unitypackage をインポートできる
  • 0.5.0.1対応のOculusUnityIntegrationをUnity5.1で使う場合は、パッケージをインポート→自動のUnity5向け変換をした後に、Assets/OVR以下のスクリプト内で #if UNITY_5_0 という定義があるので、そこを UNITY_5_0 || UNITY_5_1 などに書き換える必要がある
  • Optimus機の場合は DirectToRift.exeを右クリックして、グラフィックプロセッサと共に実行→高パフォーマンス で起動する必要がある

UnityでまともなMovieTextureを作りたい

この記事は、調べものをした途中の過程を記録する物で、成果物がある訳ではありません。

概要

Unity上での動画再生は、歴史的な経緯によりデスクトップ版ではQuickTime Playerを用いた再生を行っています。
つまり、大雑把に言うと*.movファイルをムービーテクスチャとして使用できます。
しかしQuickTime Playerはイマドキの主流であるGPUデコードには消極的で、CPUデコードを行っています(調査不足の可能性有り、何らかの最適なエンコードを行えば可能?)

その為、例えば4k2kの60FPS動画を再生すると、いまどきのCPUが1コアフル占有してコマが落ちる、と言う状況です。

多くの場合は、動画解像度を下げたり、30FPSにすることで対処出来ますが、例えばOculusRift DK2(75Hz)で全周動画を再生する、と言うシチュエーションでは、非常に困ります。

これを何とかする為の定番の方法と、現在調査中の方法をまとめます。

定番の手法

UE4+Windowsの例

Windows Media Foundationを用いた動画のGPUデコードが実装されています。

Unity+モバイル端末の例

例えばAndroidならSoCに動画のGPUデコード機能が入っており、android.mediaplayerクラスを利用することで再生が行えます。
Unity用のandroidのネイティブプラグインを書いて、このmediaplayerクラスの再生中のバッファをGLのテクスチャにバインドする。という事を行えば、Exsonys7xxx番代やSnapdragon810などで4k2kの動画がコマ落ちなくUnity上で再生出来ます。
こういった処理は、UnityのアセットであるEasyMovieTexture(30ドル)を買うと、ネイティブプラグイン部分のソースコードも同梱されているので改造し放題です。

うーん、Androidって凄い…

Unity+Windowsの例

http://www.renderheads.com/portfolio/UnityAVProWindowsMedia/ というアセットを使うことで、GPUデコード機能付きの再生が行えます。また、このアセットは外部の動画ファイルの動的読み込みにも対応しているため、Unity製の動画プレーヤーを作るような用途にも使えます。素晴らしい!

ただし、このアセットが200ドルします。うーん…お高い… そして全然Unity標準のMovieTextureと作法が異なるので、例えばAndroidWindows両対応みたいな事をする時に、結構大変そうです。

今回の提案手法

NVIDIAのCUDA実装の動画のGPUデコードを利用して、直接DX11のテクスチャバッファに動画の絵を毎フレーム書き込むネイティブプラグインを作成したいです。

これは、上記UnityAVProの機能限定(そしてNVIDIA GPU限定)版になる代わりに、再生負荷が低く出来る予感がします。

OpenCV 3.0.0rc1 のソースやサンプルを見てみると (@dandelion1124 さん 超助かりました!教えてくれてありがとうございます) BUILD_opencv_cudacodecとWITH_NVCUVIDをONにしてOpenCVをビルドして

Cudaを使った動画再生 https://github.com/Itseez/opencv/blob/master/samples/gpu/video_reader.cpp DX11テクスチャへの書き込み https://github.com/Itseez/opencv/blob/master/samples/directx/d3d11_interop.cpp を組み合わせたネイティブプラグインを作成して

Unity側で TextureのGetNativeTexturePtrをプラグインに受け渡してやる http://docs.unity3d.com/ScriptReference/Texture.GetNativeTexturePtr.html

という感じで 、望む物が出来そうな気がします。

OpenCVを使っているのは、単純に全部入りで楽そうだなあ、と思っただけなので、CUDAとDX11を生で叩いても同じ事が出来ると思います。(ウーン、UnityがOpenGLモードだと、もっと簡単な気がします。OpenCVやCudaとOpenGL仲良いですしね。でもOculusRiftのSDKはDirectX11ネイティブ対応なので、今回はDX11ですねえ)

残念ながら直近でまとまった時間が取れ無さそうなので、ここまで調べた時点で力尽きてしまいました。

しかし、UnityのMovieTextureは、大いに改善の余地がありそうなので、例えばCUDAじゃなくてOpenCLを使って汎用的な動画のGPUデコードなどが出来るアセットとかが50ドルくらいで売ってたら、人気になりそうですね。

どなたか、作りませんか!と提案してこの記事は終わります。

追記:MP4デコーダをCUDAのSDK提供のまま使って、アセット作って売るぞ!と言う場合は、一度NVIDIAの人にお伺いを立てたほうが良さそうです。うーん、知財周りは大変・・・

Gear VR向けの全周動画コンテンツの作成と宣伝

概要

Oculus VR社とSamusung社の協業によって、Gear VRと言うOculus社の品質を満たす高性能なスマホスロットインHMDシステムが発売されています。
最近は日本のキャリアでも該当機種を扱う(Galaxy s6シリーズ)為、国内での入手性も良いです。

この Gear VR向けコンテンツを、実写パノラマ動画で作っています。そのまま流すだけならmediaplayerで行けますが、選択肢で分岐したりループ制御やエフェクトがあるコンテンツを作る場合はUnity等のゲームエンジンを用いるのが良いと思います。

参考までに、このエントリでは僕が今お手伝いしているチーム(コンテンツ)のワークフローについて説明します。今後同じような事をする方の参考になれば嬉しいです。

環境

  • GoPro 6台マウント
  • Autopano Video Pro
  • VFX(After Effects,Nuke)
  • Unity5.0.0p2
  • OculusMobileSDK5.0.1
  • EasyMovieTexture 1.30

太字で書いた物はUnityアセットです。Unityではモバイル向け環境でのMovieTextureをサポートしていません。
その為にAndroid上でUnityを使って全周動画を球のメッシュに張り付けて再生する、と言うコンテンツの場合は太字で書いたEasyMovieTextureの助けを借りる必要があります。

この辺りの作成手順やソフトウェアについてはユニティの中の人の @warapuri さんが詳しいです。

www.slideshare.net

ワークフロー上の問題

チームの簡単なワークフロー図は以下の通りです。僕はUnityチームとして参加しています。 f:id:izm_11:20150502140959j:plain 今回は、Gear VR上で出来るだけ高解像度の動画素材を使いたいので 2880x1440 (30FPS)のH264(5.0 High Profile)のmp4を使う、と言う事になりました。

この解像度とプロファイルのmp4は、UnityEditor上でプレビューが出来ませんでした。また、EasyMovieTextureを使ったシーンでは、 該当アセット内のスクリプトのプラットフォーム分岐 #if UNITY_EDITIOR の中身が空っぽだったので、上図で言う赤い矢印の、UnityEditor上でのプレビュー確認が出来ません。

毎回Gear VRにビルドして転送して確認すると言う、人道的ではない開発を行う羽目になるのは嫌なので、ちょっとした工夫をして楽をします。

エディタ拡張による改善

バッチエンコードエンジン

Unityのエディタ拡張で、ffmpegのプロジェクト専用フロントエンドを作成しました。 f:id:izm_11:20150502011659j:plain こんな感じのGUIで、吐き出すのは一番UnityEditor上で負荷が低く、再インポートが速い theora(*.ogv)形式です。

EasyMovieTextureの書き換え

動画ファイルを扱うスクリプトの、空っぽだったUnityEditor上の処理を一通り書きました。
また、再生予定のファイルが例の巨大なmp4ファイルだった場合、自動的にパスを検索してエディタプレビュー用にバッチエンコードしたtheora形式の動画ファイルに動的に差し替える処理を追加しました。

この時、Movietextureを動的に読み込むために、theora形式の動画ファイルは /Assets/Resources以下に配置する必要があります。

また、HMD上でのプレビューについてはUnity 5.1以降だとVR previewが実装されるようです。
現状では拙作の OculusRiftDK2ExtendPreviewなどを併用することで、再生ボタンでDK2の見え方確認が出来ます。

neon-izm/OculusRiftDK2ExtendPreview · GitHub

f:id:izm_11:20150502231340j:plain

ビルドスクリプトの追加

/Assets/Resources以下と、/Assets/StreamingAssets以下のファイルは、Android向けに書き出すときに、基本的に全て転送されます。今回の様に大量の動画ファイルを含むプロジェクトでは、転送時間が最悪になります。
よって、こんな感じのPostProcessBuild.csをAssets/Editor以下に置きます。

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditor.Callbacks;


public class PostProcessBuild : MonoBehaviour {

    [PostProcessScene]
    public static void OnPostprocessScene()
    {
        if (EditorApplication.isPlayingOrWillChangePlaymode)
            return;
        
        // Move assets from Resources
        UnityEngine.Debug.Log(AssetDatabase.MoveAsset("Assets/Resources/TmpMovie", "Assets/TmpMovie"));
        AssetDatabase.Refresh();
    }

    [PostProcessBuildAttribute(1)]
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
        UnityEngine.Debug.Log(AssetDatabase.MoveAsset("Assets/TmpMovie","Assets/Resources/TmpMovie" ));
        AssetDatabase.Refresh();
    }
}
  • シーンビルド開始時に、theoraファイルが置いてあるフォルダを、別フォルダに移動する
  • ビルド中は/Assets/Resources 以下のサイズが少ないので速くビルドが完了する
  • ビルド後に、元の位置にファイルを戻す

という処理をしています。

ワークフロー改善の結果

Unityエディタ上で音やエフェクトの処理を確認した後に、Android向けに実機ビルドをする、と言う普通のゲームでは当たり前の手順が確立出来ました。
もし今回の様なコンテンツを、こういう工夫無しで作ろうと思うと結構大変だと思うので、同じようなコンテンツを作成したい方は、これらの点に留意しておくと快適だと思います。

最後に

僕がお手伝いしているチームGATE-Dは、現在OculusMobileVR Jamに参加しています。

vrjam.challengepost.com

また、MoguraVRさんに、コンテスト参加チーム紹介ページの一番上で、取り上げて頂きました。
ありがとうございます!

www.moguravr.com

5/11にコンテンツ提出締切と言うことで、チームは若干炎上していますが、鋭意頑張っております。

是非公開されたら、体験して頂けたら嬉しいです!以上宣伝でした。