【UE4】VRの観客視点にCineCameraを使う

# きっかけ
VRネタの動画を撮影した際、キャラクタが可愛く映らなくて気になったので調べました。


# やりたいこと
CineCameraで調整したキレイな絵を、VRの観客視点で利用したい！
「SceneCaptureComponent2Dで同じ絵を作る」という内容です。

↓この動画を撮る時に使いました。（HMDを被っている人には 一人称視点の絵が出ています）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Questハンドトラッキング豪華版。<br>CineCameraと同じ絵がSpectatorScreenに出るようにした。<br>ギミックはPinchで操作。<br>改めて触ってみると楽しいなこれ。<a href="https://twitter.com/hashtag/VRM4U?src=hash&amp;ref_src=twsrc%5Etfw">#VRM4U</a> <a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://t.co/6akyar53tL">pic.twitter.com/6akyar53tL</a></p>&mdash; はるべえ haru (@ruyo_h) <a href="https://twitter.com/ruyo_h/status/1275060521511710720?ref_src=twsrc%5Etfw">June 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


注意：
この記事の内容はUE4.25.1で確認しています。
UE4.20ではキレイにキャプチャできませんでした。古いバージョンの方はご注意ください。

キャラクタモデルはNecoMaidさんをお借りしました。
https://booth.pm/ja/items/2147201

# 何が問題なのか
CineCamera と SceneCaptureComponent2D でパラメータ保持の方法が異なります。
前者は実際のカメラのレンズやフィルムサイズといった分類で保持するのに対し、
後者はまとめてポストプロセスデータとして保持しています。

そのため、パラメータを一部コピーしてやる必要があります。

# 設定まとめ

初期値から以下の項目のみ変更すればOKです。
描画負荷が高いため、一度完全な絵を作った後、個別にShowFlagを制御していくと良いでしょう。

- SceneCaptureComponent2Dの設定
  - SceneCaptureのShowFlagを ひとまず全てONにする
  - CaptureSourceを FinalColor(LDR) にする
  - 画角と被写界深度をCineCameraパラメータからコピーする（後述）

- RenderTargetの設定
  - 用途に応じてRenderTargetのTargetGammaを`2.2`にする。
  - 確認はゲーム画面で行う。テクスチャビューワでは見た目が異なる。


# CineCameraから画角と被写界深度設定をコピーする

図のようなノードでSceneCaptureComponent2Dに画角・被写界深度を設定します。
固定カメラであればBeginPlayで1度だけ、動的にフォーカス変更などする場合はTickに繋ぎます。
位置・姿勢を反映するため、コンポーネントをCineCameraにAttachしておきます。

|CineCameraから画角・被写界深度をコピーする|
|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/33e27e11-3851-fb3f-4c1c-39133dcccf4a.png)|

なおパラメータの対応関係を知りたい方は
エンジンソースコード CineCameraComponent.cpp の UCineCameraComponent::UpdateCameraLens() を参照ください。


他の設定項目として、CaptureSourceは`FinalColor(LDR)`に、観客視点であればRenderTargetのフォーマットは`RTF RGBA8`で十分でしょう。

|FinalColor(LDR)に設定|RTF RGBA8|
|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/1bebc1ca-ac7b-5c74-d57a-fc12a7a9616c.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/61566996-bcef-8b87-0396-afb2e61df65a.png)|

これでCineCameraと同じ絵をキャプチャできるようになりました！

|左：CineCameraの絵、右：キャプチャしたテクスチャ|
|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/7709ce0e-0e78-7f5e-b730-484bea094747.png)|

めでたしめでたし。
…と言いたいところなのですが、本当に厳密には、テクスチャビューワでの見た目がほんの少し暗いです。
後段の観客視点として表示すると正しい明るさになっています。のでプレビューだけの問題ぽい…？
詳しい方がいたら教えて下さい…

ともあれ、被写界深度や画角・各種ポストフィルタも適用されたテクスチャを取得できました。

# CineCameraの絵をVR観客視点に表示する

前段のキャプチャ結果をSpectatorScreenに設定します。
[こちらのスレッド情報のとおり、](https://answers.unrealengine.com/questions/702919/vr-spectator-texture-mode-doesnt-show-texture-as-d.html)RenderTargetのTargetGammaを2.2にします。
これでゲーム内では正しく表示されます。テクスチャビューワでの見た目は明るくなりますが気にせずOKです。

余談ですがSpectatorScreen設定はPlayInから戻っても引き継がれます。動作が紛らわしいのでEndPlayで初期値にもどしています。

|観客視点に切り替え＆テクスチャ設定|TargetGammaを2.2に設定|
|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/21d7bd72-56a5-66e9-7380-e234c7db9b5b.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/51999634-f42e-86c3-759f-4e8ea7f7bc23.png)|

これでCineCameraの映像を観客視点として表示できるようになりました！

|左：VRPreviewの観客視点、右：利用しているテクスチャ（プレビューは明るくなっている）|
|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36233/29f439a7-2915-fd9f-bd4b-ac679eec9f29.png)|

めでたしめでたし。


# おわりに

VRの観客視点は派手に盛っていきましょう。撮影が主目的であるなら、負荷軽減のためにHMD側の解像度を落とすもアリです。(ScreenPercentageで制御)
その一方で、VR視点(HMDで見る側)を盛ると不快感に繋がりやすいです。使い所にご注意ください。