diff --git a/Content/Shaders/MotionBlur.flax b/Content/Shaders/MotionBlur.flax index 5da5d5bff..2f93589f0 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:46132e260d5f8b92e81760685903ea8fcfb2e13cca234076046b838a7f904b43 -size 13051 +oid sha256:1bb224fc630264fcfa58c6d8ce27759e44d3f989a53655dc35959e594890d146 +size 1838 diff --git a/Content/Shaders/TAA.flax b/Content/Shaders/TAA.flax index 8f4291616..17564fda3 100644 --- a/Content/Shaders/TAA.flax +++ b/Content/Shaders/TAA.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee25f1de47f9d513463871c90af63fb9895118813dd6d4f96b367b2c6685258e -size 5120 +oid sha256:83d415b15679c8203b8db16d9b7ef99a74aa8e07ba2753109d6d3e4eeba2cece +size 712 diff --git a/Source/Engine/Renderer/AntiAliasing/TAA.cpp b/Source/Engine/Renderer/AntiAliasing/TAA.cpp index d8d0f3e75..3c479f74e 100644 --- a/Source/Engine/Renderer/AntiAliasing/TAA.cpp +++ b/Source/Engine/Renderer/AntiAliasing/TAA.cpp @@ -12,7 +12,7 @@ bool TAA::Init() { // Create pipeline state - _psTAA.CreatePipelineStates(); + //_psTAA.CreatePipelineStates(); // Load shader _shader = Content::LoadAsyncInternal(TEXT("Shaders/TAA")); @@ -34,22 +34,6 @@ bool TAA::setupResources() } const auto shader = _shader->GetShader(); - // Validate shader constant buffer size - if (shader->GetCB(0)->GetSize() != sizeof(Data)) - { - REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - return true; - } - - // Create pipeline state - GPUPipelineState::Description psDesc; - if (!_psTAA.IsValid()) - { - psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; - if (_psTAA.Create(psDesc, shader, "PS")) - return true; - } - return false; } @@ -58,10 +42,7 @@ void TAA::Dispose() // Base RendererPass::Dispose(); - // Delete pipeline state - _psTAA.Delete(); - - // Release asset + _psTAA = nullptr; _shader.Unlink(); } @@ -75,7 +56,7 @@ void TAA::Render(RenderContext& renderContext, GPUTexture* input, GPUTextureView auto context = GPUDevice::Instance->GetMainContext(); // Ensure to have valid data - if (checkIfSkipPass()) + //if (checkIfSkipPass()) { // Resources are missing. Do not perform rendering, just copy source frame. context->SetRenderTarget(output); @@ -119,32 +100,5 @@ void TAA::Render(RenderContext& renderContext, GPUTexture* input, GPUTextureView blendStrength = 0.0f; } - // Bind input - Data data; - data.ScreenSize = renderContext.View.ScreenSize; - data.TaaJitterStrength.X = renderContext.View.TemporalAAJitter.X; - data.TaaJitterStrength.Y = renderContext.View.TemporalAAJitter.Y; - data.TaaJitterStrength.Z = data.TaaJitterStrength.X / tempDesc.Width; - data.TaaJitterStrength.W = data.TaaJitterStrength.Y / tempDesc.Height; - data.FinalBlendParameters.X = settings.TAA_StationaryBlending * blendStrength; - data.FinalBlendParameters.Y = settings.TAA_MotionBlending * blendStrength; - data.FinalBlendParameters.Z = 100.0f * 60.0f; - data.FinalBlendParameters.W = settings.TAA_Sharpness; - const auto cb = _shader->GetShader()->GetCB(0); - context->UpdateCB(cb, &data); - context->BindCB(0, cb); - context->BindSR(0, input); - context->BindSR(1, inputHistory); - context->BindSR(2, renderContext.Buffers->MotionVectors); - context->BindSR(3, renderContext.Buffers->DepthBuffer); - - // Render - GPUTextureView* rts[] = { output, outputHistory->View() }; - context->SetRenderTarget(nullptr, ToSpan(rts, ARRAY_COUNT(rts))); - context->SetState(_psTAA.Get(renderContext.View.IsOrthographicProjection() ? 1 : 0)); - context->DrawFullscreenTriangle(); - - // Swap the history - RenderTargetPool::Release(inputHistory); - renderContext.Buffers->TemporalAA = outputHistory; + // ... } diff --git a/Source/Engine/Renderer/AntiAliasing/TAA.h b/Source/Engine/Renderer/AntiAliasing/TAA.h index 79fd0722c..074a64424 100644 --- a/Source/Engine/Renderer/AntiAliasing/TAA.h +++ b/Source/Engine/Renderer/AntiAliasing/TAA.h @@ -12,15 +12,8 @@ class TAA : public RendererPass { private: - PACK_STRUCT(struct Data - { - Vector4 ScreenSize; - Vector4 TaaJitterStrength; - Vector4 FinalBlendParameters; - }); - AssetReference _shader; - GPUPipelineStatePermutationsPs<2> _psTAA; + GPUPipelineState* _psTAA; public: @@ -44,7 +37,7 @@ private: #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj) { - _psTAA.Release(); + _psTAA = nullptr; invalidateResources(); } #endif diff --git a/Source/Engine/Renderer/MotionBlurPass.cpp b/Source/Engine/Renderer/MotionBlurPass.cpp index 3d437e408..e6264ead6 100644 --- a/Source/Engine/Renderer/MotionBlurPass.cpp +++ b/Source/Engine/Renderer/MotionBlurPass.cpp @@ -11,19 +11,16 @@ #include "Engine/Graphics/RenderTargetPool.h" #include "Engine/Graphics/RenderBuffers.h" +PACK_STRUCT(struct Data { + GBufferData GBuffer; + Matrix CurrentVP; + Matrix PreviousVP; + Vector4 TemporalAAJitter; + }); + MotionBlurPass::MotionBlurPass() : _motionVectorsFormat(PixelFormat::Unknown) , _velocityFormat(PixelFormat::Unknown) - , _psCameraMotionVectors(nullptr) - , _psMotionVectorsDebug(nullptr) - , _psMotionVectorsDebugArrow(nullptr) - , _psVelocitySetup(nullptr) - , _psTileMax1(nullptr) - , _psTileMax2(nullptr) - , _psTileMax4(nullptr) - , _psTileMaxV(nullptr) - , _psNeighborMax(nullptr) - , _psReconstruction(nullptr) { } @@ -36,15 +33,6 @@ bool MotionBlurPass::Init() { // Create pipeline state _psCameraMotionVectors = GPUDevice::Instance->CreatePipelineState(); - _psMotionVectorsDebug = GPUDevice::Instance->CreatePipelineState(); - _psMotionVectorsDebugArrow = GPUDevice::Instance->CreatePipelineState(); - _psVelocitySetup = GPUDevice::Instance->CreatePipelineState(); - _psTileMax1 = GPUDevice::Instance->CreatePipelineState(); - _psTileMax2 = GPUDevice::Instance->CreatePipelineState(); - _psTileMax4 = GPUDevice::Instance->CreatePipelineState(); - _psTileMaxV = GPUDevice::Instance->CreatePipelineState(); - _psNeighborMax = GPUDevice::Instance->CreatePipelineState(); - _psReconstruction = GPUDevice::Instance->CreatePipelineState(); // Load shader _shader = Content::LoadAsyncInternal(TEXT("Shaders/MotionBlur")); @@ -98,62 +86,6 @@ bool MotionBlurPass::setupResources() if (_psCameraMotionVectors->Init(psDesc)) return true; } - if (!_psVelocitySetup->IsValid()) - { - psDesc.PS = shader->GetPS("PS_VelocitySetup"); - if (_psVelocitySetup->Init(psDesc)) - return true; - } - if (!_psTileMax1->IsValid()) - { - psDesc.PS = shader->GetPS("PS_TileMax1"); - if (_psTileMax1->Init(psDesc)) - return true; - } - if (!_psTileMax2->IsValid()) - { - psDesc.PS = shader->GetPS("PS_TileMax2"); - if (_psTileMax2->Init(psDesc)) - return true; - } - if (!_psTileMax4->IsValid()) - { - psDesc.PS = shader->GetPS("PS_TileMax4"); - if (_psTileMax4->Init(psDesc)) - return true; - } - if (!_psTileMaxV->IsValid()) - { - psDesc.PS = shader->GetPS("PS_TileMaxV"); - if (_psTileMaxV->Init(psDesc)) - return true; - } - if (!_psNeighborMax->IsValid()) - { - psDesc.PS = shader->GetPS("PS_NeighborMax"); - if (_psNeighborMax->Init(psDesc)) - return true; - } - if (!_psReconstruction->IsValid()) - { - psDesc.PS = shader->GetPS("PS_Reconstruction"); - if (_psReconstruction->Init(psDesc)) - return true; - } - if (!_psMotionVectorsDebug->IsValid()) - { - psDesc.PS = shader->GetPS("PS_MotionVectorsDebug"); - if (_psMotionVectorsDebug->Init(psDesc)) - return true; - } - if (!_psMotionVectorsDebugArrow->IsValid()) - { - psDesc.PrimitiveTopologyType = PrimitiveTopologyType::Line; - psDesc.VS = shader->GetVS("VS_DebugArrow"); - psDesc.PS = shader->GetPS("PS_DebugArrow"); - if (_psMotionVectorsDebugArrow->Init(psDesc)) - return true; - } return false; } @@ -165,15 +97,6 @@ void MotionBlurPass::Dispose() // Delete pipeline state SAFE_DELETE_GPU_RESOURCE(_psCameraMotionVectors); - SAFE_DELETE_GPU_RESOURCE(_psMotionVectorsDebug); - SAFE_DELETE_GPU_RESOURCE(_psMotionVectorsDebugArrow); - SAFE_DELETE_GPU_RESOURCE(_psVelocitySetup); - SAFE_DELETE_GPU_RESOURCE(_psTileMax1); - SAFE_DELETE_GPU_RESOURCE(_psTileMax2); - SAFE_DELETE_GPU_RESOURCE(_psTileMax4); - SAFE_DELETE_GPU_RESOURCE(_psTileMaxV); - SAFE_DELETE_GPU_RESOURCE(_psNeighborMax); - SAFE_DELETE_GPU_RESOURCE(_psReconstruction); // Release asset _shader.Unlink(); @@ -275,39 +198,13 @@ void MotionBlurPass::RenderDebug(RenderContext& renderContext, GPUTextureView* f { auto context = GPUDevice::Instance->GetMainContext(); const auto motionVectors = renderContext.Buffers->MotionVectors; - if (!motionVectors->IsAllocated() || setupResources()) + //if (!motionVectors->IsAllocated() || setupResources()) { context->Draw(frame); return; } - PROFILE_GPU_CPU("Motion Vectors Debug"); - - // Bind input - Data data; - GBufferPass::SetInputs(renderContext.View, data.GBuffer); - const float rows = 16.0f; - const float cols = rows * renderContext.Buffers->GetWidth() / renderContext.Buffers->GetHeight(); - data.DebugBlend = 0.7f; - data.DebugAmplitude = 2.0f; - data.DebugRowCount = static_cast(rows); - data.DebugColumnCount = static_cast(cols); - auto cb = _shader->GetShader()->GetCB(0); - context->UpdateCB(cb, &data); - context->BindCB(0, cb); - context->BindSR(0, frame); - context->BindSR(1, renderContext.Buffers->MotionVectors); - - // Draw motion gradient - context->SetState(_psMotionVectorsDebug); - context->DrawFullscreenTriangle(); - - // Draw arrows - context->SetState(_psMotionVectorsDebugArrow); - context->Draw(0, static_cast(cols * rows * 6)); - - // Cleanup - context->ResetSR(); + // .. } void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GPUTexture*& output) @@ -335,128 +232,5 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP return; } - // Need to have valid motion vectors created and rendered before - ASSERT(motionVectors->IsAllocated()); - - PROFILE_GPU_CPU("Motion Blur"); - - // Calculate the maximum blur radius in pixels - const float maxBlurRadius = 5.0f; - const int32 maxBlurPixels = static_cast(maxBlurRadius * motionVectorsHeight / 100.0f); - - // Calculate the TileMax size (it should be a multiple of 8 and larger than maxBlur) - const int32 tileSize = ((maxBlurPixels - 1) / 8 + 1) * 8; - - // Bind input - Data data; - GBufferPass::SetInputs(renderContext.View, data.GBuffer); - Matrix::Transpose(renderContext.View.ViewProjection(), data.CurrentVP); - Matrix::Transpose(renderContext.View.PrevViewProjection, data.PreviousVP); - data.TemporalAAJitter = renderContext.View.TemporalAAJitter; - data.VelocityScale = settings.Scale; - data.MaxBlurRadius = static_cast(maxBlurPixels); - data.RcpMaxBlurRadius = 1.0f / maxBlurPixels; - data.TileMaxOffs = Vector2::One * (tileSize / 8.0f - 1.0f) * -0.5f; - data.TileMaxLoop = static_cast(tileSize / 8.0f); - data.LoopCount = Math::Clamp(settings.SampleCount / 2.0f, 1.0f, 64.0f); - const float invWidth = 1.0f / motionVectorsWidth; - const float invHeight = 1.0f / motionVectorsHeight; - data.TexelSize1 = Vector2(invWidth, invHeight); - data.TexelSize2 = Vector2(invWidth * 2.0f, invHeight * 2.0f); - data.TexelSize4 = Vector2(invWidth * 4.0f, invHeight * 4.0f); - data.TexelSizeV = Vector2(invWidth * 8.0f, invHeight * 8.0f); - data.TexelSizeNM = Vector2(invWidth * tileSize, invHeight * tileSize); - data.MotionVectorsTexelSize = Vector2(1.0f / motionVectorsWidth, invHeight * tileSize); - auto cb = _shader->GetShader()->GetCB(0); - context->UpdateCB(cb, &data); - context->BindCB(0, cb); - context->BindSR(0, renderContext.Buffers->DepthBuffer); - auto rtDesc = GPUTextureDescription::New2D(motionVectorsWidth, motionVectorsHeight, _velocityFormat); - - // Pass 1 - Velocity/depth packing - auto vBuffer = RenderTargetPool::Get(rtDesc); - context->SetRenderTarget(*vBuffer); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, motionVectors->View()); - context->BindSR(1, renderContext.Buffers->DepthBuffer->View()); - context->SetState(_psVelocitySetup); - context->DrawFullscreenTriangle(); - context->UnBindSR(1); - - // Pass 2 - First TileMax filter (1/2 downsize) - rtDesc.Format = _motionVectorsFormat; - rtDesc.Width = motionVectorsWidth / 2; - rtDesc.Height = motionVectorsHeight / 2; - auto tile2 = RenderTargetPool::Get(rtDesc); - context->ResetRenderTarget(); - context->SetRenderTarget(tile2->View()); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, vBuffer->View()); - context->SetState(_psTileMax1); - context->DrawFullscreenTriangle(); - - // Pass 3 - Second TileMax filter (1/4 downsize) - rtDesc.Width = motionVectorsWidth / 4; - rtDesc.Height = motionVectorsHeight / 4; - auto tile4 = RenderTargetPool::Get(rtDesc); - context->ResetRenderTarget(); - context->SetRenderTarget(tile4->View()); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, tile2->View()); - context->SetState(_psTileMax2); - context->DrawFullscreenTriangle(); - RenderTargetPool::Release(tile2); - - // Pass 4 - Third TileMax filter (1/8 downsize) - rtDesc.Width = motionVectorsWidth / 8; - rtDesc.Height = motionVectorsHeight / 8; - auto tile8 = RenderTargetPool::Get(rtDesc); - context->ResetRenderTarget(); - context->SetRenderTarget(tile8->View()); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, tile4->View()); - context->SetState(_psTileMax4); - context->DrawFullscreenTriangle(); - RenderTargetPool::Release(tile4); - - // Pass 5 - Fourth TileMax filter (reduce to tileSize) - rtDesc.Width = motionVectorsWidth / tileSize; - rtDesc.Height = motionVectorsHeight / tileSize; - auto tile = RenderTargetPool::Get(rtDesc); - context->ResetRenderTarget(); - context->SetRenderTarget(tile->View()); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, tile8->View()); - context->SetState(_psTileMaxV); - context->DrawFullscreenTriangle(); - RenderTargetPool::Release(tile8); - - // Pass 6 - NeighborMax filter - rtDesc.Width = motionVectorsWidth / tileSize; - rtDesc.Height = motionVectorsHeight / tileSize; - auto neighborMax = RenderTargetPool::Get(rtDesc); - context->ResetRenderTarget(); - context->SetRenderTarget(neighborMax->View()); - context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height); - context->BindSR(0, tile->View()); - context->SetState(_psNeighborMax); - context->DrawFullscreenTriangle(); - RenderTargetPool::Release(tile); - - // Pass 7 - Reconstruction pass - context->ResetRenderTarget(); - context->SetRenderTarget(*output); - context->SetViewportAndScissors((float)screenWidth, (float)screenHeight); - context->BindSR(0, input->View()); - context->BindSR(1, vBuffer->View()); - context->BindSR(2, neighborMax->View()); - context->SetState(_psReconstruction); - context->DrawFullscreenTriangle(); - - // Cleanup - context->ResetSR(); - context->ResetRenderTarget(); - RenderTargetPool::Release(vBuffer); - RenderTargetPool::Release(neighborMax); - Swap(output, input); + // .. } diff --git a/Source/Engine/Renderer/MotionBlurPass.h b/Source/Engine/Renderer/MotionBlurPass.h index e4447e5a8..d27003f13 100644 --- a/Source/Engine/Renderer/MotionBlurPass.h +++ b/Source/Engine/Renderer/MotionBlurPass.h @@ -10,43 +10,11 @@ class MotionBlurPass : public RendererPass { private: - PACK_STRUCT(struct Data { - GBufferData GBuffer; - Matrix CurrentVP; - Matrix PreviousVP; - Vector4 TemporalAAJitter; - Vector2 TileMaxOffs; - float VelocityScale; - int32 TileMaxLoop; - float MaxBlurRadius; - float RcpMaxBlurRadius; - Vector2 TexelSize1; - Vector2 TexelSize2; - Vector2 TexelSize4; - Vector2 TexelSizeV; - Vector2 TexelSizeNM; - float LoopCount; - float Dummy0; - Vector2 MotionVectorsTexelSize; - float DebugBlend; - float DebugAmplitude; - int32 DebugColumnCount; - int32 DebugRowCount; - }); PixelFormat _motionVectorsFormat; PixelFormat _velocityFormat; AssetReference _shader; - GPUPipelineState* _psCameraMotionVectors; - GPUPipelineState* _psMotionVectorsDebug; - GPUPipelineState* _psMotionVectorsDebugArrow; - GPUPipelineState* _psVelocitySetup; - GPUPipelineState* _psTileMax1; - GPUPipelineState* _psTileMax2; - GPUPipelineState* _psTileMax4; - GPUPipelineState* _psTileMaxV; - GPUPipelineState* _psNeighborMax; - GPUPipelineState* _psReconstruction; + GPUPipelineState* _psCameraMotionVectors = nullptr; public: @@ -84,15 +52,6 @@ private: void OnShaderReloading(Asset* obj) { _psCameraMotionVectors->ReleaseGPU(); - _psMotionVectorsDebug->ReleaseGPU(); - _psMotionVectorsDebugArrow->ReleaseGPU(); - _psVelocitySetup->ReleaseGPU(); - _psTileMax1->ReleaseGPU(); - _psTileMax2->ReleaseGPU(); - _psTileMax4->ReleaseGPU(); - _psTileMaxV->ReleaseGPU(); - _psNeighborMax->ReleaseGPU(); - _psReconstruction->ReleaseGPU(); invalidateResources(); } #endif diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index b46d624d5..c19be8dc3 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -306,6 +306,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext) #endif renderContext.List->Settings.AntiAliasing.Mode = aaMode; + // Prepare renderContext.View.Prepare(renderContext); renderContext.Buffers->Prepare(); @@ -484,7 +485,8 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext) context->ResetRenderTarget(); context->SetRenderTarget(task->GetOutputView()); context->SetViewportAndScissors((float)renderContext.Buffers->GetWidth(), (float)renderContext.Buffers->GetHeight()); - MotionBlurPass::Instance()->RenderDebug(renderContext, frameBuffer->View()); + context->Clear(frameBuffer->View(), Color::Black); + //MotionBlurPass::Instance()->RenderDebug(renderContext, frameBuffer->View()); return; } diff --git a/Source/Shaders/MotionBlur.shader b/Source/Shaders/MotionBlur.shader index e4199d4a3..53054c799 100644 --- a/Source/Shaders/MotionBlur.shader +++ b/Source/Shaders/MotionBlur.shader @@ -14,27 +14,6 @@ float4x4 CurrentVP; float4x4 PreviousVP; float4 TemporalAAJitter; -// Motion Blur -float2 TileMaxOffs; -float VelocityScale; -int TileMaxLoop; -float MaxBlurRadius; -float RcpMaxBlurRadius; -float2 TexelSize1; -float2 TexelSize2; -float2 TexelSize4; -float2 TexelSizeV; -float2 TexelSizeNM; -float LoopCount; -float Dummy0; -float2 MotionVectorsTexelSize; - -// Motion Vectors Debug Parameters -float DebugBlend; -float DebugAmplitude; -int DebugColumnCount; -int DebugRowCount; - META_CB_END DECLARE_GBUFFERDATA_ACCESS(GBuffer) @@ -43,106 +22,6 @@ Texture2D Input0 : register(t0); Texture2D Input1 : register(t1); Texture2D Input2 : register(t2); -// Calculates the color for the a motion vector debugging -float4 VectorToColor(float2 motionVector) -{ - float phi = atan2(motionVector.x, motionVector.y); - float hue = (phi / PI + 1) * 0.5; - - float r = abs(hue * 6 - 3) - 1; - float g = 2 - abs(hue * 6 - 2); - float b = 2 - abs(hue * 6 - 4); - float a = length(motionVector); - - return saturate(float4(r, g, b, a)); -} - -// Pixel shader for motion vectors debug view -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_MotionVectorsDebug(Quad_VS2PS input) : SV_Target -{ - float4 color = SAMPLE_RT(Input0, input.TexCoord); - float2 motionVector = SAMPLE_RT(Input1, input.TexCoord).rg * (DebugAmplitude * 5.0f); - float4 motionColor = VectorToColor(motionVector); - - float colorRation = saturate(2 - DebugBlend * 2); - float motionColorRatio = saturate(DebugBlend * 2); - color.rgb = lerp(color.rgb * colorRation, motionColor.rgb, motionColor.a * motionColorRatio); - - return color; -} - -// Motion vector arrow data from VS to PS -struct ArrowVaryings -{ - float4 Position : SV_POSITION; - float2 ScreenUV : TEXCOORD; - float4 Color : COLOR; -}; - -META_VS(true, FEATURE_LEVEL_ES2) -ArrowVaryings VS_DebugArrow(uint VertexId : SV_VertexID) -{ - // Screen aspect ratio - float aspect = GBuffer.ScreenSize.x * GBuffer.ScreenSize.w; - float aspectInv = GBuffer.ScreenSize.y * GBuffer.ScreenSize.z; - - // Vertex IDs - uint arrowId = VertexId / 6; - uint pointId = VertexId - arrowId * 6; - - // Column and row number of the arrow - uint row = arrowId / DebugColumnCount; - uint col = arrowId - row * DebugColumnCount; - - // Get the motion vector - float2 uv = float2((col + 0.5) / DebugColumnCount, (row + 0.5) / DebugRowCount); - float2 motionVector = SAMPLE_RT(Input1, uv).rg * DebugAmplitude; - - // Arrow color - float4 color = VectorToColor(motionVector); - - // Arrow transformation - float isEnd = pointId > 0; - float2 direction = normalize(motionVector * float2(aspect, 1)); - float2x2 rotation = float2x2(direction.y, direction.x, -direction.x, direction.y); - float offsetStart = pointId == 3 ? -1 : (pointId == 5 ? 1 : 0); - offsetStart *= isEnd * 0.3f * saturate(length(motionVector) * DebugRowCount); - float2 offset = float2(offsetStart, -abs(offsetStart)); - offset = mul(rotation, offset) * float2(aspectInv, 1); - - // Vertex position in the clip space - float2 pos = motionVector * isEnd + offset * 2 / DebugRowCount + uv * 2.0f - 1.0f; - - // Convert to the screen coordinates - float2 posSS = (pos + 1) * 0.5f * GBuffer.ScreenSize.xy; - posSS = round(posSS); - - // Bring back to the clip space - pos = (posSS + 0.5f) * GBuffer.ScreenSize.zw * 2.0f - 1.0f; - pos.y *= -1; - - // Color tweaks - color.rgb = lerp(color.rgb, 1, 0.5f); - color.a = DebugBlend; - - // Output - ArrowVaryings output; - output.Position = float4(pos, 0, 1); - output.ScreenUV = posSS; - output.Color = color; - return output; -} - -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_DebugArrow(ArrowVaryings input) : SV_Target -{ - // Pseudo anti-aliasing - float aa = length(frac(input.ScreenUV) - 0.5f) / 0.707f; - aa *= (aa * (aa * 0.305306011f + 0.682171111f) + 0.012522878f); - return float4(input.Color.rgb, input.Color.a * aa); -} - // Pixel shader for camera motion vectors META_PS(true, FEATURE_LEVEL_ES2) float4 PS_CameraMotionVectors(Quad_VS2PS input) : SV_Target @@ -169,224 +48,3 @@ float4 PS_CameraMotionVectors(Quad_VS2PS input) : SV_Target return float4(vPosCur - vPosPrev, 0, 1); } - -// Pixel Shader for velocity texture setup -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_VelocitySetup(Quad_VS2PS input) : SV_Target -{ - // Sample the motion vector - float2 v = SAMPLE_RT(Input0, input.TexCoord).rg; - - // Apply the exposure time and convert to the pixel space - v *= (VelocityScale * 0.5f) * GBuffer.ScreenSize.xy; - - // Clamp the vector with the maximum blur radius - v /= max(1.0f, length(v) * RcpMaxBlurRadius); - - // Sample the depth of the pixel - float depth = SAMPLE_RT(Input1, input.TexCoord).r; - GBufferData gBufferData = GetGBufferData(); - depth = LinearizeZ(gBufferData, depth); - - // Pack into 10/10/10/2 format - return float4((v * RcpMaxBlurRadius + 1.0f) * 0.5f, depth, 0.0f); -} - -float2 MaxV(float2 v1, float2 v2) -{ - return dot(v1, v1) < dot(v2, v2) ? v2 : v1; -} - -// Pixel Shader for TileMax filter (2 pixel width with normalization) -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_TileMax1(Quad_VS2PS input) : SV_Target -{ - float4 d = TexelSize1.xyxy * float4(-0.5, -0.5, 0.5, 0.5); - - float2 v1 = SAMPLE_RT(Input0, input.TexCoord + d.xy).rg; - float2 v2 = SAMPLE_RT(Input0, input.TexCoord + d.zy).rg; - float2 v3 = SAMPLE_RT(Input0, input.TexCoord + d.xw).rg; - float2 v4 = SAMPLE_RT(Input0, input.TexCoord + d.zw).rg; - - v1 = (v1 * 2.0f - 1.0f) * MaxBlurRadius; - v2 = (v2 * 2.0f - 1.0f) * MaxBlurRadius; - v3 = (v3 * 2.0f - 1.0f) * MaxBlurRadius; - v4 = (v4 * 2.0f - 1.0f) * MaxBlurRadius; - - return float4(MaxV(MaxV(MaxV(v1, v2), v3), v4), 0.0f, 0.0f); -} - -// Pixel Shader for TileMax filter (2 pixel width) -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_TileMax2(Quad_VS2PS input) : SV_Target -{ - float4 d = TexelSize2.xyxy * float4(-0.5f, -0.5f, 0.5f, 0.5f); - - float2 v1 = SAMPLE_RT(Input0, input.TexCoord + d.xy).rg; - float2 v2 = SAMPLE_RT(Input0, input.TexCoord + d.zy).rg; - float2 v3 = SAMPLE_RT(Input0, input.TexCoord + d.xw).rg; - float2 v4 = SAMPLE_RT(Input0, input.TexCoord + d.zw).rg; - - return float4(MaxV(MaxV(MaxV(v1, v2), v3), v4), 0.0f, 0.0f); -} - -// Pixel Shader for TileMax filter (2 pixel width) -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_TileMax4(Quad_VS2PS input) : SV_Target -{ - float4 d = TexelSize4.xyxy * float4(-0.5f, -0.5f, 0.5f, 0.5f); - - float2 v1 = SAMPLE_RT(Input0, input.TexCoord + d.xy).rg; - float2 v2 = SAMPLE_RT(Input0, input.TexCoord + d.zy).rg; - float2 v3 = SAMPLE_RT(Input0, input.TexCoord + d.xw).rg; - float2 v4 = SAMPLE_RT(Input0, input.TexCoord + d.zw).rg; - - return float4(MaxV(MaxV(MaxV(v1, v2), v3), v4), 0.0f, 0.0f); -} - -// Pixel Shader for TileMax filter (variable width) -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_TileMaxV(Quad_VS2PS input) : SV_Target -{ - float2 uv0 = input.TexCoord + TexelSizeV.xy * TileMaxOffs.xy; - - float2 du = float2(TexelSizeV.x, 0.0); - float2 dv = float2(0.0, TexelSizeV.y); - - float2 vo = 0.0; - - LOOP - for (int x = 0; x < TileMaxLoop; x++) - { - LOOP - for (int y = 0; y < TileMaxLoop; y++) - { - float2 uv = uv0 + du * x + dv * y; - vo = MaxV(vo, SAMPLE_RT(Input0, uv).rg); - } - } - - return float4(vo, 0.0, 0.0); -} - -// Pixel Shader for NeighborMax filter -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_NeighborMax(Quad_VS2PS input) : SV_Target -{ - // Center weight tweak - const float cw = 1.01; - - float4 d = TexelSizeNM.xyxy * float4(1.0, 1.0, -1.0, 0.0); - - float2 v1 = SAMPLE_RT(Input0, input.TexCoord - d.xy).rg; - float2 v2 = SAMPLE_RT(Input0, input.TexCoord - d.wy).rg; - float2 v3 = SAMPLE_RT(Input0, input.TexCoord - d.zy).rg; - - float2 v4 = SAMPLE_RT(Input0, input.TexCoord - d.xw).rg; - float2 v5 = SAMPLE_RT(Input0, input.TexCoord).rg * cw; - float2 v6 = SAMPLE_RT(Input0, input.TexCoord + d.xw).rg; - - float2 v7 = SAMPLE_RT(Input0, input.TexCoord + d.zy).rg; - float2 v8 = SAMPLE_RT(Input0, input.TexCoord + d.wy).rg; - float2 v9 = SAMPLE_RT(Input0, input.TexCoord + d.xy).rg; - - float2 va = MaxV(v1, MaxV(v2, v3)); - float2 vb = MaxV(v4, MaxV(v5, v6)); - float2 vc = MaxV(v7, MaxV(v8, v9)); - - return float4(MaxV(va, MaxV(vb, vc)) * (1.0f / cw), 0.0f, 0.0f); -} - -// Interleaved gradient function from Jimenez 2014 -// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare -float GradientNoise(float2 uv) -{ - uv = floor(uv * GBuffer.ScreenSize.xy); - float f = dot(float2(0.06711056f, 0.00583715f), uv); - return frac(52.9829189f * frac(f)); -} - -// Returns true or false with a given interval -bool Interval(float phase, float interval) -{ - return frac(phase / interval) > 0.499; -} - -// Jitter function for tile lookup -float2 JitterTile(float2 uv) -{ - float rx, ry; - sincos(GradientNoise(uv + float2(2.0f, 0.0f)) * (2.0f * PI), ry, rx); - return float2(rx, ry) * TexelSizeNM.xy * 0.25f; -} - -// Velocity sampling function -float3 SampleVelocity(float2 uv) -{ - float3 v = SAMPLE_RT(Input1, uv).xyz; - return float3((v.xy * 2.0f - 1.0f) * MaxBlurRadius, v.z); -} - -// Pixel Shader for reconstruction filter (applies the motion blur to the frame) -META_PS(true, FEATURE_LEVEL_ES2) -float4 PS_Reconstruction(Quad_VS2PS input) : SV_Target -{ - // Sample at the current location - const float4 color = SAMPLE_RT(Input0, input.TexCoord); - const float3 velocity = SampleVelocity(input.TexCoord); - const float velocityLen = max(length(velocity.xy), 0.5); - const float depthInv = 1.0 / velocity.z; - - const float2 velocityMax = SAMPLE_RT(Input2, input.TexCoord + JitterTile(input.TexCoord)).xy; - const float velocityMaxLength = length(velocityMax); - if (velocityMaxLength < 2.0f) - return color; - const float2 velocityWeighted = (velocityLen * 2.0f > velocityMaxLength) ? velocity.xy * (velocityMaxLength / velocityLen) : velocityMax; - - // Calculate the amount of samples - const float sc = floor(min(LoopCount, velocityMaxLength * 0.5f)); - - // Accumlation loop - float backgroudVelocity = max(velocityLen, 1.0f); - const float dt = 1.0f / sc; - const float offsetNoise = (GradientNoise(input.TexCoord) - 0.5f) * dt; - float t = 1.0f - dt * 0.5f; - float count = 0.0f; - float4 sum = 0.0f; - LOOP - while (t > dt * 0.25) - { - // Sampling direction (switched per every two samples) - const float2 sampleVelocity = Interval(count, 4.0) ? velocityWeighted : velocityMax; - - // Sample position (inverted per every sample) - const float samplePosition = (Interval(count, 2.0) ? -t : t) + offsetNoise; - - // Calculate UVs for the sample position - const float2 sampleUV = input.TexCoord + sampleVelocity * samplePosition * GBuffer.ScreenSize.zw; - - // Sample color and velocity with depth - const float3 c = SAMPLE_RT(Input0, sampleUV).rgb; - const float3 velocityDepth = SampleVelocity(sampleUV); - - // Length of the velocity vector - const float foreground = saturate((velocity.z - velocityDepth.z) * 20.0f * depthInv); - const float sampleVelocityLength = lerp(backgroudVelocity, length(velocityDepth.xy), foreground); - - // Apply color accumulation - float weight = saturate(sampleVelocityLength - (velocityMaxLength * abs(samplePosition))) / sampleVelocityLength * (1.2f - t); - sum += float4(c, 1.0) * weight; - - // Calculate the background velocity - backgroudVelocity = max(backgroudVelocity, sampleVelocityLength); - - // Move to the next sample - t = Interval(count, 2.0f) ? t - dt : t; - count += 1.0f; - } - - // Add the center sample - sum += float4(color.rgb, 1.0f) * (1.2f / (backgroudVelocity * sc * 2.0f)); - - return float4(sum.rgb / sum.a, color.a); -} diff --git a/Source/Shaders/TAA.shader b/Source/Shaders/TAA.shader index 436c68186..0949e110d 100644 --- a/Source/Shaders/TAA.shader +++ b/Source/Shaders/TAA.shader @@ -1,151 +1,10 @@ // Copyright (c) 2012-2020 Wojciech Figat. All rights reserved. #include "./Flax/Common.hlsl" -#include "./Flax/GammaCorrectionCommon.hlsl" - -#define USE_TONEMAP 0 - -META_CB_BEGIN(0, Data) -float4 ScreenSize;// x-width, y-height, z-1/width, w-1/height -float4 TaaJitterStrength; // x, y, x/width, y/height -float4 FinalBlendParameters; // x: static, y: dynamic, z: motion amplification, w; sharpness -META_CB_END - -Texture2D Input : register(t0); -Texture2D InputHistory : register(t1); -Texture2D MotionVectors : register(t2); -Texture2D Depth : register(t3); - -float3 Fetch(Texture2D tex, float2 coords) -{ - return tex.SampleLevel(SamplerLinearClamp, coords, 0).rgb; -} - -float3 Map(float3 x) -{ -#if USE_TONEMAP - return FastTonemap(x); -#else - return x; -#endif -} - -float3 Unmap(float3 x) -{ -#if USE_TONEMAP - return FastTonemapInvert(x); -#else - return x; -#endif -} - -float3 ClipToAABB(float3 color, float3 minimum, float3 maximum) -{ - // Note: only clips towards aabb center (but fast!) - float3 center = 0.5 * (maximum + minimum); - float3 extents = 0.5 * (maximum - minimum); - - // This is actually `distance`, however the keyword is reserved - float3 offset = color - center; - - float3 ts = abs(extents / max(offset, 0.0001)); - float t = saturate(min(min(ts.x, ts.y), ts.z)); - return center + offset * t; -} - -float2 GetClosestFragment(float2 uv) -{ - const float2 k = ScreenSize.zw; - - const float4 neighborhood = float4( - SAMPLE_RT(Depth, uv - k).r, - SAMPLE_RT(Depth, uv + float2(k.x, -k.y)).r, - SAMPLE_RT(Depth, uv + float2(-k.x, k.y)).r, - SAMPLE_RT(Depth, uv + k).r - ); - -#if defined(REVERSED_Z) - #define COMPARE_DEPTH(a, b) step(b, a) -#else - #define COMPARE_DEPTH(a, b) step(a, b) -#endif - - float3 result = float3(0.0, 0.0, SAMPLE_RT(Depth, uv).r); - result = lerp(result, float3(-1.0, -1.0, neighborhood.x), COMPARE_DEPTH(neighborhood.x, result.z)); - result = lerp(result, float3( 1.0, -1.0, neighborhood.y), COMPARE_DEPTH(neighborhood.y, result.z)); - result = lerp(result, float3(-1.0, 1.0, neighborhood.z), COMPARE_DEPTH(neighborhood.z, result.z)); - result = lerp(result, float3( 1.0, 1.0, neighborhood.w), COMPARE_DEPTH(neighborhood.w, result.z)); - - return (uv + result.xy * k); -} // Pixel Shader for Temporal Anti-Aliasing META_PS(true, FEATURE_LEVEL_ES2) -META_PERMUTATION_1(IS_ORTHO=0) -META_PERMUTATION_1(IS_ORTHO=1) -void PS(Quad_VS2PS input, out float4 output : SV_Target0, out float4 outputHistory : SV_Target1) +float4 PS(Quad_VS2PS input) : SV_Target0 { - float2 jitter = TaaJitterStrength.zw; - float2 texcoord = input.TexCoord; - const float2 k = ScreenSize.zw; - -#if IS_ORTHO - float2 closest = texcoord; -#else - float2 closest = GetClosestFragment(texcoord); -#endif - - // Sample velocity - float2 velocity = MotionVectors.SampleLevel(SamplerLinearClamp, closest, 0).xy; - - // Sample color and surround - float2 uv = texcoord - jitter; - float3 color = Fetch(Input, uv); - float3 topLeft = Fetch(Input, uv - k); - float3 bottomRight = Fetch(Input, uv + k); - float3 topRight = Fetch(Input, uv + float2(k.x, -k.y)); - float3 bottomLeft = Fetch(Input, uv + float2(-k.x, k.y)); - - float3 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color; - - // Sharpen output - float sharpness = FinalBlendParameters.w; - float3 blur = (topLeft + topRight + bottomLeft + bottomRight) * 0.25; - color += (color - blur) * sharpness; - color = clamp(color, 0.0, HDR_CLAMP_MAX); - - // Tonemap color - float3 average = Map((corners + color) / 7.0); - topLeft = Map(topLeft); - bottomRight = Map(bottomRight); - color = Map(color); - - // Sample history - float3 history = Fetch(InputHistory, texcoord - velocity); - history = Map(history); - - float colorLuma = Luminance(color); - float averageLuma = Luminance(average); - float velocityLength = length(velocity); - float nudge = lerp(4.0, 0.25, velocityLength * 100.0) * abs(averageLuma - colorLuma); - - float3 minimum = min(bottomRight, topLeft) - nudge; - float3 maximum = max(topLeft, bottomRight) + nudge; - - // Clip history sample - history = ClipToAABB(history, minimum, maximum); - - // Blend color with history - //float historyLuma = Luminance(history); - //float weight = 1.0f - saturate(abs(colorLuma - historyLuma) / max(max(colorLuma, historyLuma), 0.2)); - float weight = saturate(velocityLength * FinalBlendParameters.z); - float feedback = lerp(FinalBlendParameters.x, FinalBlendParameters.y, weight * weight); - //feedback = lerp(feedback, 0.02, velocityWeight); - color = Unmap(lerp(color, history, feedback)); - color = clamp(color, 0.0, HDR_CLAMP_MAX); - - output = float4(color, 1); - outputHistory = output; - - //output = float4(1, 0, 0, 1) * feedback; + return float4(0, 0, 0, 0); }