From 429f8e5336bec5bd4f4deaf1921971c32416b8c2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 4 May 2026 16:43:41 +0200 Subject: [PATCH] Add highlight to Motion Vectors Debug view for better content optimizing --- Content/Shaders/MotionBlur.flax | 4 ++-- Source/Engine/Renderer/MotionBlurPass.cpp | 23 +++++++++++++++++++++++ Source/Engine/Renderer/Renderer.cpp | 3 --- Source/Shaders/MotionBlur.shader | 20 ++++++++++++++++++-- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/Content/Shaders/MotionBlur.flax b/Content/Shaders/MotionBlur.flax index c89597a39..2e978818a 100644 --- a/Content/Shaders/MotionBlur.flax +++ b/Content/Shaders/MotionBlur.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed42ed126bad47e824e8ac214afc4f6c6be841500b6a9cd845fa8eaf37295c45 -size 9513 +oid sha256:a029dd95886dbb390749163f3c1d1e5cdf6786ee6b65f0e647d231f5c3555ccb +size 10184 diff --git a/Source/Engine/Renderer/MotionBlurPass.cpp b/Source/Engine/Renderer/MotionBlurPass.cpp index d0c09debc..910ced532 100644 --- a/Source/Engine/Renderer/MotionBlurPass.cpp +++ b/Source/Engine/Renderer/MotionBlurPass.cpp @@ -236,20 +236,43 @@ void MotionBlurPass::RenderMotionVectors(RenderContext& renderContext) void MotionBlurPass::RenderDebug(RenderContext& renderContext, GPUTextureView* frame) { + auto outputView = renderContext.Task->GetOutputView(); + auto outputViewport = renderContext.Task->GetOutputViewport(); auto context = GPUDevice::Instance->GetMainContext(); const auto motionVectors = renderContext.Buffers->MotionVectors; + context->ResetRenderTarget(); if (!motionVectors || !motionVectors->IsAllocated() || checkIfSkipPass()) { + context->SetRenderTarget(outputView); + context->SetViewportAndScissors(outputViewport); context->Draw(frame); return; } + // Draw depth of objects that draw motion vectors for better debugging content when optimizing this pass + auto desc = GPUTextureDescription::New2D(motionVectors->Width(), motionVectors->Height(), PixelFormat::D16_UNorm, GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil); + auto motionObjectsDepth = RenderTargetPool::Get(desc); + { + PROFILE_GPU_CPU("Motion Vectors Depth"); + context->SetRenderTarget(motionObjectsDepth->View(), nullptr); + context->SetViewportAndScissors((float)desc.Width, (float)desc.Height); + context->ClearDepth(motionObjectsDepth->View()); + renderContext.View.Pass = DrawPass::Depth; + renderContext.List->ExecuteDrawCalls(renderContext, DrawCallsListType::MotionVectors); + context->ResetRenderTarget(); + } + PROFILE_GPU_CPU("Motion Vectors Debug"); context->BindSR(0, frame); context->BindSR(1, renderContext.Buffers->MotionVectors->View()); + context->BindSR(2, motionObjectsDepth->View()); context->SetState(_psMotionVectorsDebug); + context->SetRenderTarget(outputView); + context->SetViewportAndScissors(outputViewport); context->DrawFullscreenTriangle(); context->ResetSR(); + + RenderTargetPool::Release(motionObjectsDepth); } void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& frame, GPUTexture*& tmp) diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index a1f531ac1..0a859d161 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -789,9 +789,6 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont // Debug motion vectors if (renderContext.View.Mode == ViewMode::MotionVectors) { - context->ResetRenderTarget(); - context->SetRenderTarget(task->GetOutputView()); - context->SetViewportAndScissors(outputViewport); MotionBlurPass::Instance()->RenderDebug(renderContext, frameBuffer->View()); RenderTargetPool::Release(tempBuffer); RenderTargetPool::Release(frameBuffer); diff --git a/Source/Shaders/MotionBlur.shader b/Source/Shaders/MotionBlur.shader index 1b33210d0..e190cdd74 100644 --- a/Source/Shaders/MotionBlur.shader +++ b/Source/Shaders/MotionBlur.shader @@ -71,10 +71,26 @@ float4 MotionVectorToColor(float2 v) META_PS(true, FEATURE_LEVEL_ES2) float4 PS_MotionVectorsDebug(Quad_VS2PS input) : SV_Target { - float4 c = SAMPLE_RT(Input0, input.TexCoord); + float4 color = SAMPLE_RT(Input0, input.TexCoord); + + // Grey-out background pixels (that don't draw dedicated motion vectors) + float motionObjectsDepth = SAMPLE_RT_DEPTH(Input2, input.TexCoord); +#if REVERSE_Z + bool isBackground = motionObjectsDepth <= 0; +#else + bool isBackground = motionObjectsDepth >= 1; +#endif + uint2 checkerboardCoord = (uint2(input.Position.xy) >> 3) & 0x1; + float checkerboard = checkerboardCoord.x == checkerboardCoord.y ? 1.0f : 0.0f; + float3 backgroundColor = Luminance(color.rgb).xxx * (0.4f + 0.1f * checkerboard); + color.rgb = select(isBackground, backgroundColor, max(color.rgb, 0.2f)); + + // Debug color based on the pixel motion float2 v = SAMPLE_RT(Input1, input.TexCoord).xy * 20.0f; float4 vC = MotionVectorToColor(v); - return float4(lerp(c.rgb, vC.rgb, vC.a * 0.6f), c.a); + color.rgb = lerp(color.rgb, vC.rgb, vC.a * 0.6f); + + return color; } // Returns the longer velocity vector