From 0185d581259ad4255083f46a89c1c1657daba002 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 18 Jul 2019 21:23:10 -0700 Subject: Shadows: implemented world-size filtering of VSM/EVSM --- Components/src/ShadowMapManager.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'Components/src/ShadowMapManager.cpp') diff --git a/Components/src/ShadowMapManager.cpp b/Components/src/ShadowMapManager.cpp index cba347e..a3ec564 100644 --- a/Components/src/ShadowMapManager.cpp +++ b/Components/src/ShadowMapManager.cpp @@ -454,23 +454,38 @@ void ShadowMapManager::ConvertToFilterable(IDeviceContext* pCtx, const ShadowMap "Incorrect 32-bit VSM flag"); int iFilterRadius = (ShadowAttribs.iFixedFilterSize-1)/2; + bool bSkipBlur = ShadowAttribs.iFixedFilterSize == 2; for (Uint32 i=0; i < ShadowMapDesc.ArraySize; ++i) { - ITextureView* pRTVs[] = {iFilterRadius == 0 ? m_pFilterableShadowMapRTVs[i] : m_pIntermediateRTV}; + ITextureView* pRTVs[] = {bSkipBlur ? m_pFilterableShadowMapRTVs[i] : m_pIntermediateRTV}; pCtx->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); { struct ConversionAttribs { - int iCascade; - int iFilterRadius; + int iCascade; + float fHorzFilterRadius; + float fVertFilterRadius; float fEVSMPositiveExponent; - float fEVSMNegativeExponent; + float fEVSMNegativeExponent; int Is32BitEVSM; }; MapHelper pAttribs(pCtx, m_pConversionAttribsBuffer, MAP_WRITE, MAP_FLAG_DISCARD ); pAttribs->iCascade = i; - pAttribs->iFilterRadius = iFilterRadius; + if (ShadowAttribs.iFixedFilterSize > 0) + { + pAttribs->fHorzFilterRadius = static_cast(iFilterRadius); + pAttribs->fVertFilterRadius = static_cast(iFilterRadius); + } + else + { + const auto& Cascade = ShadowAttribs.Cascades[i]; + float fNDCtoUVScale = 0.5f; + float fFilterWidth = ShadowAttribs.fFilterWorldSize * Cascade.f4LightSpaceScale.x * fNDCtoUVScale; + float fFilterHeight = ShadowAttribs.fFilterWorldSize * Cascade.f4LightSpaceScale.y * fNDCtoUVScale; + pAttribs->fHorzFilterRadius = fFilterWidth / 2.f * static_cast(ShadowMapDesc.Width); + pAttribs->fVertFilterRadius = fFilterHeight / 2.f * static_cast(ShadowMapDesc.Height); + } pAttribs->fEVSMPositiveExponent = ShadowAttribs.fEVSMPositiveExponent; pAttribs->fEVSMNegativeExponent = ShadowAttribs.fEVSMNegativeExponent; pAttribs->Is32BitEVSM = ShadowAttribs.bIs32BitEVSM; @@ -480,7 +495,7 @@ void ShadowMapManager::ConvertToFilterable(IDeviceContext* pCtx, const ShadowMap DrawAttribs drawAttribs{3, DRAW_FLAG_VERIFY_ALL}; pCtx->Draw(drawAttribs); - if (iFilterRadius > 0) + if (!bSkipBlur) { pRTVs[0] = m_pFilterableShadowMapRTVs[i]; pCtx->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); -- cgit v1.2.3