お世話になっております。
ご指摘について再度ケースを立てて頂きありがとうございます。本件まず DebugDrawSphere の Depth Priority を World -> Foreground に変更しておくと正しい位置に表示することが可能である、という回避策を共有しておきたいと思います。これについては、World だと シーンの深度バッファ(UpscaledSceneDepth)と深度テストを行うため、投影行列とViewRectの不一致が座標変換に影響し位置のずれが発生します。Foregroundだと専用の深度バッファを使用し深度テストを常に通過するため、投影行列の不一致の影響を受けにくいです。ただし、根本的な問題(投影行列とViewRectの不一致)は残っています。
根本的な修正について、DebugView->GetShaderParameters()が返すFViewUniformShaderParametersのTranslatedWorldToClip行列を使用していますが、bConstrainAspectRatioが有効な場合、この行列はConstrainedViewRectに基づいて計算されていますが、OutputViewport.RectがUnscaledViewRectを使用していることで不一致が発生していました。CreateCompositePrimitiveViewでViewRectを変更し、ViewMatricesを再初期化することで FViewUniformShaderParametersが正しく更新され、Worldでも正しく表示されるはずです。ただしウィンドウの最大化等を行うとまだズレがあるので、追加での変更が必要なように思います。取り急ぎお知らせいたします。
static FDebugPrimitivesDrawingContext InitializeDebugPrimitiveTextures(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
const FCompositePrimitiveInputs& Inputs,
const FScreenPassRenderTarget& Output)
{
// Setup view
// Use View.ViewRect instead of Output.ViewRect to match the projection matrix.
// When bConstrainAspectRatio is enabled, View.ViewRect corresponds to ConstrainedViewRect,
// which is what the projection matrix was calculated based on.
// Output.ViewRect may use UnscaledViewRect, which would cause a mismatch.
// 修正前:
// const FIntRect ViewRect = Output.ViewRect;
// 修正後:
const FIntRect ViewRect = View.ViewRect;
static bool DrawDebugPDE(
FRDGBuilder& GraphBuilder,
FDebugPrimitivesDrawingContext& Context,
const FScreenPassTextureViewport& OutputViewport)
{
if (!Context.DebugView->DebugSimpleElementCollector.HasAnyPrimitives())
{
return false;
}
// 修正前:
// なし
// 修正後:
const FIntRect DebugViewRect = Context.DebugView->ViewRect;
// Draw SDPG_World elements, depth tested with SceneColor
if (Context.DebugView->DebugSimpleElementCollector.HasPrimitives(SDPG_World))
{
FDebugPrimitivesPassParameters* PassParameters = GraphBuilder.AllocParameters<FDebugPrimitivesPassParameters>();
PassParameters->View = Context.DebugView->GetShaderParameters();
PassParameters->RenderTargets[0] = FRenderTargetBinding(Context.SceneColor.Texture, ERenderTargetLoadAction::ELoad);
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(Context.UpscaledSceneDepth, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, FExclusiveDepthStencil::DepthWrite_StencilWrite);
GraphBuilder.AddPass(
RDG_EVENT_NAME("DrawDebugPrimitives(SDPG_World)"),
PassParameters,
ERDGPassFlags::Raster,
// 修正前:
// [PassParameters, DebugView=Context.DebugView, OutputViewport](FRDGAsyncTask, FRHICommandList& RHICmdList)
// 修正後:
[PassParameters, DebugView=Context.DebugView, DebugViewRect](FRDGAsyncTask, FRHICommandList& RHICmdList)
{
// 修正前:
// RHICmdList.SetViewport(OutputViewport.Rect.Min.X, OutputViewport.Rect.Min.Y, 0.0f, OutputViewport.Rect.Max.X, OutputViewport.Rect.Max.Y, 1.0f);
// 修正後:
RHICmdList.SetViewport(DebugViewRect.Min.X, DebugViewRect.Min.Y, 0.0f, DebugViewRect.Max.X, DebugViewRect.Max.Y, 1.0f);