今回は、Sequencerで特定のCameraCutに対してTextureStreamingを事前に動作させる方法についてお伺いします。
元々は、CameraCutが切り替わった際、テクスチャのミップマップの切り替えを抑止するため、
UE4のシーケンサーをもっともっと使いこなそう!
を元にPreRollの機能を使うことにしました。
しかし、対象のカメラカットはアニメーションでカメラの動きを指定しているためか、PreRollを有効にしていてもスライドのようにテクスチャのミップマップの切り替えは改善しませんでした。
カメラをアニメーションで動かしているので、該当カットにあるCameraComponentのTransform>Locationは原点(0,0,0)にあります。
そのため、FCameraCutPreRollExecutionToken::Execute()でIStreamingManager::Get().AddViewSlaveLocation()に渡される位置情報(Location)も、(0,0,0)になっていました。
その結果、再生されるカメラ位置での事前読み込みがされず、テクスチャのミップマップの切り替えが改善しなかったようです。
また関係があるかは不明ですが、上記のカメラアニメーションは、別のスケルタルメッシュのボーンにアタッチしてアニメーションを再生しています。
そのため、カメラにはアニメーションデータはありません。
CameraComponentのTransformを手打ちすれば、改善されるのは分かっています。
しかし、アニメーションデータで出力しているものを手打ちするのは現実的に不可能なので、他に改善できる方法は無いでしょうか。
その後調査した結果、CameraComponentのTransformを削除すれば、アニメーションからの位置情報が取得されることが分かりました。
しかし、PreRollの時間中は一つ前のCameraCutのアニメーションが動いているせいか、IStreamingManager::Get().AddViewSlaveLocation()に渡される位置情報(Location)は、一つ前のCameraCutの位置情報となっています。
その結果、ミップマップの切り替えに関しては改善できていません。
弊社で用意しているデータ構造の問題もありそうですが、ここまでの情報で何か改善できる方法があれば教えていただけないでしょうか。
お手数をおかけしますが、よろしくお願いいたします。
1 Like
お世話になっております。
コードを確認した所、たしかに FCameraCutPreRollExecutionToken::Execute()
における IStreamingManager::Get().AddViewSlaveLocation()
の引数には CameraCutトラックのCameraBindingIDに指定されたActorの座標が渡されるため、PreRoll時点でそのActorが動いている場合はご報告頂いたような問題が発生する可能性があります。
LevelSequenceの構造やカメラの動かし方により細かい部分は変わる可能性はあると思いますが、本問題を解決する方法として以下の方法が考えられます。
-
IStreamingManager::Get().AddViewSlaveLocation()
を直接呼ぶ
-
FMovieSceneCameraCutSectionTemplate
の CutTransform
を活用する
前者はエンジン改造が不要なシンプルな方法です。また、Event Trackから呼び出すようにすれば対応がSequencer上で完結するというメリットもあります。しかし、 AddViewSlaveLocation
を呼ぶようのトラックの追加や AddViewSlaveLocation
に渡す座標の調整が必要になります。自動化できる部分はあるかとは思うのですが、もし全Level Sequenceにその対応を入れる必要がある場合はあまり現実的ではないかもしれません。
後者に関しては、 UMovieSceneCameraCutSection::GenerateTemplate()
における実装を改造することになります。この関数内では以下の処理が行われています。
- CameraBindingIDに指定されたActorが そのCameraCutトラックを持つLevelSequence に追加(Bind)されているか確認(MasterScequenceにBindされているCameraを指定している場合はここで弾かれます)
- 追加されている場合、そのActorがTransformトラックを持つか確認
- もし持っている場合、そのTransformトラックのキーのデータ( FTransform )を
FMovieSceneCameraCutSectionTemplate
の CutTransform にわたす
そして、CutTransformに値が入っている場合はそのLocationが IStreamingManager::Get().AddViewSlaveLocation()
に渡されることになります。
既存のLevel Sequenceに出来るだけ変更を加えたくない場合は、上記の部分の実装を変更することなるかと思います。実際にどのように変更するのかに関しましては、はじめに申し上げた通り LevelSequenceの構造やカメラの動かし方によって変わってくるかと思います。
まずは上記の情報を元に今後の対応についてご検討いただけますと幸いです。その過程でご不明な点などありましたらご質問いただけますと幸いです。
よろしくお願いいたします。
ご回答ありがとうございました。
実務上は、スケジュールの都合と、影響するCameraCut/Textureが少なかったこともあって、問題になるTextureにNeverStreamフラグを付けることで回避することになりました。
後学のために、教えていただいたそれぞれの方法も試してみましたが、どちらでもうまくいきそうでした。
ただ、やはりどこから必要な座標を取得するかが問題になります。
この問題については今後の課題として残りますが、教えていただいた方法で手掛かりはつかめました。
回避策を教えていただき、ありがとうございました。