UE5.6と5.7のDeferred Renderingを用いたVRプロジェクトでHMDの画像がぼやける現象(残像が残ったようになる)が発生したので対応しました。その内容をメモしておきます。
再現環境
UnrealEngine 5.6.1
UnrealEngine 5.7.1
再現方法
デフォルトのぼやけ
UE5.6.1では以下の順でHMDの画像がぼやけます。
- VR Templateで新しいプロジェクトを作成する
- Project Settinsで[Rendering] > [Foward Shading]のチェックを外し、[Rendering] > [Anti-aliasing Method]をTAAにしてプロジェクトを再起動する
- VR Previewを実行する
SceneCaptureComponent2Dを使った場合のぼやけ
上記の対応を実施したUE5.6.1やUE5.7.1では以下の手順でHMDの画像がぼやけます。
- VR Templateで新しいプロジェクトを作成する
- Project Settinsで[Rendering] > [Foward Shading]のチェックを外し、[Rendering] > [Anti-aliasing Method]をTAAにしてプロジェクトを再起動する
- TextureTargetを指定したSceneCaptureCompoent2Dを追加したActorを生成しマップに配置する。もしくは、マップに配置してあるBP_VRSpectatorのSceneCaptureComponent2DのCaptureEveryFrameをチェックする
- VR Previewを実行する
対応方法
デフォルトのぼやけ
以下のフォーラムからリンクされたUE5.7に当てられたパッチをUE5.6.1に当てると解消できました。
SceneCaptureComponent2Dを使った場合のぼやけ
ひとまずSceneCaptureComponent2Dを継承した以下のようなクラスを作成して利用することで回避しています。
上記のパッチをのせてもらっていたフォーラムで報告し、UnrealEngineのバグ報告もしています。
StableVRSceneCaptureComponent2D.cpp
void UStableVRSceneCaptureComponent2D::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
// Tick中のみ bCaptureEveryFrame の動作を奪取し、終了時に元へ戻す
// DeferredRenderingの際にSceneCaptureのbCaptureEveryFrameがオンになるとHMDの画像がぼやけるための対策
const bool OriginalCaptureEveryFrame = bCaptureEveryFrame;
bool bLocalCustomCaptureEveryFrame = false;
if (bCaptureEveryFrame)
{
// エンジンの自動キャプチャは一時的に停止し、こちらで制御
bCaptureEveryFrame = false;
bLocalCustomCaptureEveryFrame = true;
}
// bCaptureOnMovement が外部でオンにされても、毎Tickで常にオフに戻す
// この挙動をシミュレートするべきだが、現状は利用していないため無視するのみ
if (bCaptureOnMovement)
{
bCaptureOnMovement = false;
}
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// 外部が毎フレームキャプチャを意図している場合、こちらでキャプチャを実行
if (bLocalCustomCaptureEveryFrame && TextureTarget != nullptr)
{
CaptureScene();
}
// Tick終了時に bCaptureEveryFrame を元の値へ復元して、外部からの操作感を維持
bCaptureEveryFrame = OriginalCaptureEveryFrame;
}
おまけ - VRを利用しているクラッシュする
HMDの画像がぼやける現象とは直接関係ないですがたまにVRを利用しているとクラッシュする問題があり以下のパッチを当てています。