お世話になっております。
現在、パーシスタントレベル切り替わりのタイミングで、テクスチャストリーミングのロードが間に合わず、ビルド済みのシャドウマップテクスチャがフェード明けに低い解像度で数秒間表示される問題が発生しております。
こちらの現象ですが、Shippingのみ確認しておりTestビルドでは発生していないことにより調査が難航しております。
一方で、レベル切り替わりのタイミングだけであることから、多少のロードによるブロックは許容と考えるため、表題の通りフェード中にテクスチャのストリームを待ち、ストリームが完了したタイミングでフェードを明けさせるという対応で解決したいと考えています。
こちらについて調査したところ、以下のコードに座標を渡すことによってその座標周囲のテクスチャのストリームを優先させることが確認できました。
IStreamingManager::Get().AddViewLocation(const FVector& Location, float BoostFactor = 1.0f, bool bOverrideLocation = false, float Duration = 0.0f);
また、エンジンコードを確認する限り、処理をブロックされますが以下のコードでストリームのリクエストを待つことができると考えました。
IStreamingManager:BlockTillAllRequestsFinished(float TimeLimit = 0.0f, bool bLogResults = false)
これらの情報から、AddViewLocationでフェードが明けたときに表示される座標を登録し、BlockTillAllRequestsFinishedでストリーム対象となったテクスチャのストリームを待つことで上記、ストリームが遅延する問題が解消されると考えたのですが、こちらを適用しても解決には至りませんでした。
そのため、テクスチャのストリームを待ち、フェードが明けるタイミングには適切なMipのテクスチャが読み込まれた状態になるように実装を行いたいのですが、そのような方法が可能かお答えいただけると助かります。
以上となります、非常に漠然とした質問で申し訳ありませんが、ご確認よろしくお願いいたします。
[Attachment Removed]
BlockTillAllRequestsFinishedが呼び出された時に必要なテクスチャのリクエストがまだ行われていない可能性がありそうです。
IStreamingManager::Get().UpdateResourceStreaming(0.0f,true/*bProcessEverything*/);を呼び出してストリーミングシステムを更新し必要なリクエストを発行させて問題が解決するかご確認いただいてもよろしいでしょうか?
またBlockTillAllRequestsFinishedを呼び出す際にTimeLimitを0.0f以外にしていただくと、関数の戻り値でインフライトでリクエストされているアセット数を取得できます。
こちらを読み込み待ち開始前に呼び出していただき、適切なリクエストが発行されているかどうかを確認することも状況を把握する用途で有用です。
[Attachment Removed]
ご回答ありがとうございます。
こちらを確認させていただきましたが、シッピングビルドでは症状改善に至りませんでした。
BlockTillAllRequestsFinishedを確認させていただきましたが、何らかの数値自体は帰ってきているため、リクエスト自体は発行されているようです。
この件に関しては、ベイク済みのシャドウマップが低Mipで表示されており目立つことから、最低限そちらを回避できればと思っております。このため、シャドウマップのテクスチャを特定し、そのテクスチャが完全に読み込まれるまで待つ処理を実装するというアプローチではどのような実装を行えばよいかお答えいただくことは可能でしょうか。
お手数をおかけいたしますが、ご確認よろしくお願いいたします。
[Attachment Removed]
AddViewLocation後にUpdateResourceStreamingを行いそのあとに BlockTillAllRequestsFinished を利用してロードの完了を待っておられるということでよろしいでしょうか?
またシッピングビルドと言及されていることからDevelopmentやTestビルドでは正しくストリーミング待ちが機能していたりしますか?
タイムリミットを設定してBlockTillAllRequestsFinishedを呼び出した時に数値が返されるという状態はストリーミングが処理中であることを示します。もしこれが0になるまで待機できていないのであれば、レベルの開始後にストリーミングが間に合わなかったアセットが段階的に読み込まれてしまうため0になるまで待機するコードが必要です。
もしこのような処理を経てストリーミングが完了したのに関わらず、レベルを開始するとその後でシャドウマップが新たにリクエストされてしまうのであれば、StreamingPoolがあふれていたりShadowmapStreamingFactorなどのブースト値が低くなっている可能性もありそうですが、なにかお気づきの点はございますか?
シャドウマップはUShadowMapTexture2Dクラスで管理されているので(ライトマップはULightMapTexture2D)、
TObjectIterator<UShadowMapTexture2D>などで列挙することが可能です。
これらのオブジェクトに対して選択的に GetStreamableResourceState() を通じて読み出し待ち処理を行うことは可能です。ただし行っていること自体はFRenderAssetStreamingManager::BlockTillAllRequestsFinished内の処理と同じなので、ひとまず正しくストリーミングのリクエストと待機が行われているか確認いただくことをお勧めいたします。
[Attachment Removed]
情報ありがとうございます。
大変申し訳ありませんがこちらの実装に不備があり、r.Streaming.MaxTempMemoryAllowedを変更していた値がシッピングのみ変わっていなかったようです。
いただいた内容を加えて実装したところ、無事テクスチャストリーミングが完了した状態まで待つことが確認できました。
ご対応ありがとうございました。
[Attachment Removed]