テクスチャのMipmapを画面に描画させずに強制的にロードする方法になります。
間違ってたらごめんなさい、指摘ください。
検証UE4: 4.25.3
要C++
#はじめに
- MipとTextureStreamについてはこちらを参照してください
- SceneCaptureを使った適正なMipロード方法、もしくはActor単位での強制的なMipロードについてはこちらをご参照ください
(いつも引用すみません) このような感じで低解像度Mipが出る前に、Mipロードを済ませておいてから表示させる的な事ができます。Texture Streamingを考慮するようにしたバージョン。できてるけど、表示された瞬間から読み込むから最初数フレームはボケちゃう。 #UE4 pic.twitter.com/bks4OEYkl6
— スミオ(SUMIO) (@tempkinder) February 17, 2019
もしActor単位で良ければ、前述参考リンクのPaperSloth's diaryさんのような形で実装できます。(BP実装)
全テクスチャのロード待つと遅くなるので一部テクスチャだけロード完了してから表示したい、
マテリアルのテクスチャを差し替えて使うのでそこだけ先にロードしておきたい、的な時に今回のは使えるかと思います。
#テクスチャのMipを強制的にロードする
// 操作したいテクスチャ
UTexture2D* Texture = GetNanka();
if (IsValid(Texture))
{
// 強制的なMipロードを有効化する秒数
const float Seconds = 100000.0f;
Texture->SetForceMipLevelsToBeResident(Seconds);
Texture->bForceMiplevelsToBeResident = true;
}
UTexture2Dの親クラス、UStreamableRenderAssetに操作があります。
Secondsで指定した秒数の間、強制的なMipロードが入ります。
#設定を解除する
// 操作したいテクスチャ
UTexture2D* Texture = GetNanka();
if (IsValid(Texture))
{
Texture->SetForceMipLevelsToBeResident(0);
Texture->bForceMiplevelsToBeResident = false;
}
設定解除しても即時メモリから破棄はされません。
この辺りはTextureStreamingのCacheに積まれた時と同じ挙動になります。
#テクスチャのMipのロードの完了を取得する
// 操作したいテクスチャ
UTexture2D* Texture = GetNanka();
bool Finish = true;
if (IsValid(Texture))
{
// 同数なら終わってる
Finish = (Texture->GetNumResidentMips() == Texture->GetNumMipsForStreaming());
}
bForceMiplevelsToBeResident を設定して即時ロード完了とはなりません。
TextureStreamingを使用してロードしますので、完了までには時間がかかる場合があります。
GetNumResidentMips は現在TextureStreamingで読み込めてる数、
GetNumMipsForStreaming はTextureStreamingで使用できるMip数
となります。
ロードが完了すると同数になります。
#ほか
- 強制的にMipをすべて読み込む為、Textureの使用メモリが増えます。
- 例えば画面表示的に1024サイズで良くても、4096までのMipが存在していれば全部読み込みます。
- 現在この機能で「指定Mip以上だけ読み込む」的なのは無い筈です(あったら教えて下さい。。。)
- エディターで確認する場合は、PIEですとキャッシュが残ったままになる事もありますのでStandaloneで確認するのをお勧めします。
ForceMiplevelsToBeResident の中でも優先的にロードさせる
あまり確証ないですが ForceMiplevelsToBeResident の設定後に下記Fast設定すれば優先されそうな感じがしました。
(細かい挙動までは追っかけてないです)
// 操作したいテクスチャ
UTexture2D* Texture = GetNanka();
if (IsValid(Texture))
{
IStreamingManager::Get().GetTextureStreamingManager().FastForceFullyResident(Texture);
}