========================================================================
※ 2019/04/25 追記
現在はSequencer(シーケンサー)というツールに置き換わっているのでMatinee(マチネ)は非推奨です。
Sequencerについては、公式ドキュメントを参照ください。
========================================================================
先月、ボーンデジタル様主催のセミナー(https://www.borndigital.co.jp/seminar/4163.html)で、ご紹介した360°動画の作り方をまとめます。
下記の動画がサンプルになります。
SceneCaptureCubeを使用して、シーンをキャプチャし、Matinee/Sequencerから連番画像として出力します。
その連番画像を動画ファイルに変換し、Youtubeへアップします。
※補足事項
UE4の4.11バージョンから”StereoPanoramicMovieCapture”というプラグインが入っており、それを有効化することで360°用の連番画像を出力することも可能です。

ただし、現状ではアルファ版ということでGUI等もなく、コンソールコマンドから制御する必要があります。
また、実際に使ってみるとエラーにより上手くキャプチャできず途中で止まってしまうなど、動作が不安定であったため今回は使用を見送りました。
360°のテクスチャをキャプチャするためBluePrintを作成して、そのコンポーネントとしてSceneCaptureComponentCubeを追加します。

次に、キャプチャ画像のレンダリングのためにCubeRenderTargetというアセットが必要になります。
下記画像を参考にコンテンツブラウザより作成して下さい。

なお、CubeRenderTargetの解像度設定はアスペクト比[2:1]固定となっており、Size X 値が縦の長さになります。
下図のように2048に設定した場合はレンダリングされる解像度が4096 x 2048pxになります。

BluePrintへ戻ります。SceneCaptureComponentCubeを選択した状態で、Texture Targetに先程のCubeRenderTargetを設定します。

また、連番出力には直接使用しませんが、プレビュー用にCameraコンポーネントを追加しています。
では、次にキャプチャした結果を連番画像として出力したいのですが、いくつか問題があります。
・SceneCaptureCubeからキャプチャしたCubeRenderTargetはそのままでは連番出力できない。
・CubeRenderTargetはHDRなためトーンマッピングなどポストプロセスが無効の状態で出力される。
・SceneCaptureCubeからRotationの変更ができず、CubeRenderTargetにはワールド座標で-Y方向に正対した画像がレンダリングされる。
これらの問題を解決するために、新たに画像レンダリング用のBluePrintを作成します。

内容としてはシンプルで、キャプチャ画像をマテリアルとして設定し平面に貼り付けてしまい、レンダリングするカメラの表示範囲をその平面と一致させるというものです。
そして、Matinee/Sequencerからそのカメラ画像をレンダリングする、という流れになります。
では、中身を見ていきましょう。

まず、CubeRenderTargetのアスペクト比[2:1]と等しい平面と展開されたUVを持つStaticMeshコンポーネントを追加します。
このメッシュに後ほどCubeRenderTargetをテクスチャとして使用したマテリアルを割り当てます。
次に、レンダリング用のCameraコンポーネントを追加します。
Camera Settings項で”Projection Mode”を”OrthoGraphic”に変更し、画角の影響を受けないようにします。
“Ortho Width”を先程のStaticMeshコンポーネントの幅と同じ値にして、”Constrain Aspect Ration”設定をオンにすることで、CubeRenderTargetと出力する画像を一致させることができます。
なお、マテリアルでCubeRenderTargetを使用する際の注意点ですが、下図のようにテクスチャをそのまま接続するとエラーが出ます。

そこで、Customノードを使用してUV値を加工します。

CustomノードにInputsをひとつ追加し”Input Name”を”UV”とします。
そして”Code”には
|
float2 Angles = float2(2 * PI * (UV.x + 0.5f), PI * UV.y); float s = sin(Angles.y); float3 Direction = float3(s * sin(Angles.x), cos(Angles.y), -s * cos(Angles.x)); return Direction.xzy; |
と入力します。
※カスタムノードのコードとワークフローについては以下のフォーラムの記事を参考にさせて頂きました。
これで、”TextureCoordinate”ノードからUVをCustomノードのUVインプットへ接続することで、エラーが出なくなります。
さらには、Customノードに接続されたUV値を加算することで”CubeRenderTarget”を各UV方向にオフセットできますので、”SceneCaptureCube”の方向を回転させるように扱えます。

そこで、冒頭のキャプチャ用BluePrintのYaw値と紐付けるため”TextureRotation”というParameterを作りました。
このParameterをキャプチャ用BluePrintからDynamic Material Instanceを作って更新するようにすれば、プレビュー結果を簡単に確認できるようになります。

冒頭キャプチャ用BluePrintのEvent GraphでTickにより取得したYawの値を格納する変数”CaptureCameraYaw”を用意します。

一方で連番レンダリング用のBluePrintにオブジェクト変数を作り、キャプチャ用BluePrintを参照します。

これで準備が整いました!
では、レンダリング用のBluePrintにあるCameraを指定して、Matinee/Sequencerから連番画像として出力します。
今回は、Matineeを使用しました。

CubeRenderTargetで設定してある解像度と同じ4096×2048のPNG形式で連番出力しました。
その後、出力された連番画像を編集ソフトやコンポジットソフトで動画に変換します。
最後にYoutubeのガイド(https://support.google.com/youtube/answer/6178631?hl=ja)にあるように動画ファイルにメタデータをつけます。
メタデータを含んだ動画ファイルをYoutubeへアップすると、自動的に360°動画としてエンコードされます。
ちなみに、先週のブログ(https://historia.co.jp/archives/4602)でもお伝えした「ネコぱらいぶ☆」(特設ページ )の360°動画も同様の方法で作成しています。
ご参考になれば幸いです。