Reimplement cascaded shadow maps blending via dithering
This commit is contained in:
@@ -13,13 +13,13 @@
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Debug/DebugDraw.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/Graphics.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Level/Actors/BrushMode.h"
|
||||
#include "Engine/Renderer/GBufferPass.h"
|
||||
@@ -480,18 +480,7 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
||||
auto& cascade = ddgiData.Cascades[cascadeIndex];
|
||||
data.ProbeScrollClears[cascadeIndex] = Int4(cascade.ProbeScrollClears, 0);
|
||||
}
|
||||
if (renderContext.List->Setup.UseTemporalAAJitter)
|
||||
{
|
||||
// Use temporal offset in the dithering factor (gets cleaned out by TAA)
|
||||
const float time = Time::Draw.UnscaledTime.GetTotalSeconds();
|
||||
const float scale = 10;
|
||||
const float integral = roundf(time / scale) * scale;
|
||||
data.TemporalTime = time - integral;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.TemporalTime = 0.0f;
|
||||
}
|
||||
data.TemporalTime = renderContext.List->Setup.UseTemporalAAJitter ? RenderTools::ComputeTemporalTime() : 0.0f;
|
||||
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
|
||||
context->UpdateCB(_cb0, &data);
|
||||
context->BindCB(0, _cb0);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include "Engine/Platform/Window.h"
|
||||
#include "Utils/MultiScaler.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
@@ -247,13 +246,7 @@ void ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTexture
|
||||
data.TemporalEffect = useTemporal ? 1.0f : 0.0f;
|
||||
if (useTemporal)
|
||||
{
|
||||
const float time = Time::Draw.UnscaledTime.GetTotalSeconds();
|
||||
|
||||
// Keep time in smaller range to prevent temporal noise errors
|
||||
const double scale = 10;
|
||||
const double integral = round(time / scale) * scale;
|
||||
data.TemporalTime = static_cast<float>(time - integral);
|
||||
|
||||
data.TemporalTime = RenderTools::ComputeTemporalTime();
|
||||
buffers->LastFrameTemporalSSR = Engine::FrameCount;
|
||||
if (!buffers->TemporalSSR || buffers->TemporalSSR->Width() != temporalWidth || buffers->TemporalSSR->Height() != temporalHeight)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,8 @@ PACK_STRUCT(struct Data{
|
||||
ShaderLightData Light;
|
||||
Matrix WVP;
|
||||
Matrix ViewProjectionMatrix;
|
||||
Float2 Dummy0;
|
||||
float Dummy0;
|
||||
float TemporalTime;
|
||||
float ContactShadowsDistance;
|
||||
float ContactShadowsLength;
|
||||
});
|
||||
@@ -62,7 +63,6 @@ struct ShadowAtlasLight
|
||||
int32 ContextCount;
|
||||
uint16 Resolution;
|
||||
uint16 TilesNeeded;
|
||||
bool BlendCSM;
|
||||
float Sharpness, Fade, NormalOffsetScale, Bias, FadeDistance;
|
||||
Float4 CascadeSplits;
|
||||
ShadowsAtlasTile* Tiles[MaxTiles];
|
||||
@@ -294,15 +294,7 @@ void ShadowsPass::SetupLight(RenderContext& renderContext, RenderContextBatch& r
|
||||
Float3 lightDirection = light.Direction;
|
||||
float shadowsDistance = Math::Min(view.Far, light.ShadowsDistance);
|
||||
int32 csmCount = Math::Clamp(light.CascadeCount, 0, MAX_CSM_CASCADES);
|
||||
bool blendCSM = Graphics::AllowCSMBlending;
|
||||
const auto shadowMapsSize = (float)atlasLight.Resolution;
|
||||
#if USE_EDITOR
|
||||
if (IsRunningRadiancePass)
|
||||
blendCSM = false;
|
||||
#elif PLATFORM_SWITCH || PLATFORM_IOS || PLATFORM_ANDROID
|
||||
// Disable cascades blending on low-end platforms
|
||||
blendCSM = false;
|
||||
#endif
|
||||
|
||||
// Views with orthographic cameras cannot use cascades, we force it to 1 shadow map here
|
||||
if (view.Projection.M44 == 1.0f)
|
||||
@@ -397,7 +389,6 @@ void ShadowsPass::SetupLight(RenderContext& renderContext, RenderContextBatch& r
|
||||
// Init shadow data
|
||||
atlasLight.ContextIndex = renderContextBatch.Contexts.Count();
|
||||
atlasLight.ContextCount = csmCount;
|
||||
atlasLight.BlendCSM = blendCSM;
|
||||
renderContextBatch.Contexts.AddDefault(atlasLight.ContextCount);
|
||||
|
||||
// Create the different view and projection matrices for each split
|
||||
@@ -413,9 +404,7 @@ void ShadowsPass::SetupLight(RenderContext& renderContext, RenderContextBatch& r
|
||||
// Calculate cascade split frustum corners in view space
|
||||
for (int32 j = 0; j < 4; j++)
|
||||
{
|
||||
float overlap = 0;
|
||||
if (blendCSM)
|
||||
overlap = 0.2f * (splitMinRatio - oldSplitMinRatio);
|
||||
float overlap = 0.1f * (splitMinRatio - oldSplitMinRatio); // CSM blending overlap
|
||||
const auto frustumRangeVS = mainCache->FrustumCornersVs[j + 4] - mainCache->FrustumCornersVs[j];
|
||||
frustumCorners[j] = mainCache->FrustumCornersVs[j] + frustumRangeVS * (splitMinRatio - overlap);
|
||||
frustumCorners[j + 4] = mainCache->FrustumCornersVs[j] + frustumRangeVS * splitMaxRatio;
|
||||
@@ -927,6 +916,7 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende
|
||||
else if (light.IsSpotLight)
|
||||
((RenderSpotLightData&)light).SetShaderData(sperLight.Light, true);
|
||||
Matrix::Transpose(view.ViewProjection(), sperLight.ViewProjectionMatrix);
|
||||
sperLight.TemporalTime = renderContext.List->Setup.UseTemporalAAJitter ? RenderTools::ComputeTemporalTime() : 0.0f;
|
||||
sperLight.ContactShadowsDistance = light.ShadowsDistance;
|
||||
sperLight.ContactShadowsLength = EnumHasAnyFlags(view.Flags, ViewFlags::ContactShadows) ? light.ContactShadowsLength : 0.0f;
|
||||
if (isLocalLight)
|
||||
|
||||
Reference in New Issue
Block a user