Remove SHADOW_MAPS_FORMAT and support fallback formats for shadow maps
This commit is contained in:
@@ -114,6 +114,3 @@ PACK_STRUCT(struct ProbeData {
|
|||||||
|
|
||||||
// Maximum amount of directional light cascades (using CSM technique)
|
// Maximum amount of directional light cascades (using CSM technique)
|
||||||
#define MAX_CSM_CASCADES 4
|
#define MAX_CSM_CASCADES 4
|
||||||
|
|
||||||
// Default format for the shadow map textures
|
|
||||||
#define SHADOW_MAPS_FORMAT PixelFormat::D16_UNorm
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
#include "GBufferPass.h"
|
#include "GBufferPass.h"
|
||||||
#include "VolumetricFogPass.h"
|
#include "VolumetricFogPass.h"
|
||||||
#include "Engine/Graphics/Graphics.h"
|
#include "Engine/Graphics/Graphics.h"
|
||||||
|
#include "Engine/Graphics/GPUContext.h"
|
||||||
#include "Engine/Graphics/RenderTask.h"
|
#include "Engine/Graphics/RenderTask.h"
|
||||||
#include "Engine/Graphics/RenderBuffers.h"
|
#include "Engine/Graphics/RenderBuffers.h"
|
||||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||||
#include "Engine/Content/Content.h"
|
#include "Engine/Content/Content.h"
|
||||||
#include "Engine/Graphics/GPUContext.h"
|
|
||||||
#include "Engine/Scripting/Enums.h"
|
#include "Engine/Scripting/Enums.h"
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
#include "Engine/Renderer/Lightmaps.h"
|
#include "Engine/Renderer/Lightmaps.h"
|
||||||
@@ -81,19 +81,22 @@ bool ShadowsPass::Init()
|
|||||||
_shader.Get()->OnReloading.Bind<ShadowsPass, &ShadowsPass::OnShaderReloading>(this);
|
_shader.Get()->OnReloading.Bind<ShadowsPass, &ShadowsPass::OnShaderReloading>(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If GPU doesn't support linear sampling for the shadow map then fallback to the single sample on lowest quality
|
// Select format for shadow maps
|
||||||
const auto formatTexture = PixelFormatExtensions::FindShaderResourceFormat(SHADOW_MAPS_FORMAT, false);
|
_shadowMapFormat = PixelFormat::Unknown;
|
||||||
const auto formatFeaturesDepth = GPUDevice::Instance->GetFormatFeatures(SHADOW_MAPS_FORMAT);
|
for (const PixelFormat format : { PixelFormat::D16_UNorm, PixelFormat::D24_UNorm_S8_UInt, PixelFormat::D32_Float })
|
||||||
const auto formatFeaturesTexture = GPUDevice::Instance->GetFormatFeatures(formatTexture);
|
|
||||||
_supportsShadows = EnumHasAllFlags(formatFeaturesDepth.Support, FormatSupport::DepthStencil | FormatSupport::Texture2D)
|
|
||||||
&& EnumHasAllFlags(formatFeaturesTexture.Support, FormatSupport::ShaderSample | FormatSupport::ShaderSampleComparison);
|
|
||||||
// TODO: fallback to 32-bit shadow map format if 16-bit is not supported
|
|
||||||
if (!_supportsShadows)
|
|
||||||
{
|
{
|
||||||
LOG(Warning, "GPU doesn't support shadows rendering");
|
const auto formatTexture = PixelFormatExtensions::FindShaderResourceFormat(format, false);
|
||||||
LOG(Warning, "Format: {0}, features support: {1}", ScriptingEnum::ToString(SHADOW_MAPS_FORMAT), (uint32)formatFeaturesDepth.Support);
|
const auto formatFeaturesDepth = GPUDevice::Instance->GetFormatFeatures(format);
|
||||||
LOG(Warning, "Format: {0}, features support: {1}", ScriptingEnum::ToString(formatTexture), (uint32)formatFeaturesTexture.Support);
|
const auto formatFeaturesTexture = GPUDevice::Instance->GetFormatFeatures(formatTexture);
|
||||||
|
if (EnumHasAllFlags(formatFeaturesDepth.Support, FormatSupport::DepthStencil | FormatSupport::Texture2D) &&
|
||||||
|
EnumHasAllFlags(formatFeaturesTexture.Support, FormatSupport::ShaderSample | FormatSupport::ShaderSampleComparison))
|
||||||
|
{
|
||||||
|
_shadowMapFormat = format;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (_shadowMapFormat == PixelFormat::Unknown)
|
||||||
|
LOG(Warning, "GPU doesn't support shadows rendering");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -148,7 +151,7 @@ void ShadowsPass::updateShadowMapSize()
|
|||||||
|
|
||||||
// Select new size
|
// Select new size
|
||||||
_currentShadowMapsQuality = Graphics::ShadowMapsQuality;
|
_currentShadowMapsQuality = Graphics::ShadowMapsQuality;
|
||||||
if (_supportsShadows)
|
if (_shadowMapFormat != PixelFormat::Unknown)
|
||||||
{
|
{
|
||||||
switch (_currentShadowMapsQuality)
|
switch (_currentShadowMapsQuality)
|
||||||
{
|
{
|
||||||
@@ -174,18 +177,18 @@ void ShadowsPass::updateShadowMapSize()
|
|||||||
// Check if size will change
|
// Check if size will change
|
||||||
if (newSizeCSM > 0 && newSizeCSM != _shadowMapsSizeCSM)
|
if (newSizeCSM > 0 && newSizeCSM != _shadowMapsSizeCSM)
|
||||||
{
|
{
|
||||||
if (_shadowMapCSM->Init(GPUTextureDescription::New2D(newSizeCSM, newSizeCSM, SHADOW_MAPS_FORMAT, GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil, 1, MAX_CSM_CASCADES)))
|
if (_shadowMapCSM->Init(GPUTextureDescription::New2D(newSizeCSM, newSizeCSM, _shadowMapFormat, GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil, 1, MAX_CSM_CASCADES)))
|
||||||
{
|
{
|
||||||
LOG(Fatal, "Cannot setup shadow map '{0}' Size: {1}, format: {2}.", TEXT("CSM"), newSizeCSM, (int32)SHADOW_MAPS_FORMAT);
|
LOG(Fatal, "Cannot setup shadow map '{0}' Size: {1}, format: {2}.", TEXT("CSM"), newSizeCSM, ScriptingEnum::ToString(_shadowMapFormat));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_shadowMapsSizeCSM = newSizeCSM;
|
_shadowMapsSizeCSM = newSizeCSM;
|
||||||
}
|
}
|
||||||
if (newSizeCube > 0 && newSizeCube != _shadowMapsSizeCube)
|
if (newSizeCube > 0 && newSizeCube != _shadowMapsSizeCube)
|
||||||
{
|
{
|
||||||
if (_shadowMapCube->Init(GPUTextureDescription::NewCube(newSizeCube, SHADOW_MAPS_FORMAT, GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil)))
|
if (_shadowMapCube->Init(GPUTextureDescription::NewCube(newSizeCube, _shadowMapFormat, GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil)))
|
||||||
{
|
{
|
||||||
LOG(Fatal, "Cannot setup shadow map '{0}' Size: {1}, format: {2}.", TEXT("Cube"), newSizeCube, (int32)SHADOW_MAPS_FORMAT);
|
LOG(Fatal, "Cannot setup shadow map '{0}' Size: {1}, format: {2}.", TEXT("Cube"), newSizeCube, ScriptingEnum::ToString(_shadowMapFormat));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_shadowMapsSizeCube = newSizeCube;
|
_shadowMapsSizeCube = newSizeCube;
|
||||||
@@ -586,7 +589,7 @@ bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const Rend
|
|||||||
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||||
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
|
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
|
||||||
|
|
||||||
return fade > ZeroTolerance && _supportsShadows;
|
return fade > ZeroTolerance && _shadowMapFormat != PixelFormat::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const RendererSpotLightData& light)
|
bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const RendererSpotLightData& light)
|
||||||
@@ -598,12 +601,12 @@ bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const Rend
|
|||||||
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||||
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
|
const float fade = 1 - Math::Saturate((dstLightToView - light.Radius - light.ShadowsDistance + fadeDistance) / fadeDistance);
|
||||||
|
|
||||||
return fade > ZeroTolerance && _supportsShadows;
|
return fade > ZeroTolerance && _shadowMapFormat != PixelFormat::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const RendererDirectionalLightData& light)
|
bool ShadowsPass::CanRenderShadow(const RenderContext& renderContext, const RendererDirectionalLightData& light)
|
||||||
{
|
{
|
||||||
return _supportsShadows;
|
return _shadowMapFormat != PixelFormat::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowsPass::RenderShadow(RenderContextBatch& renderContextBatch, RendererPointLightData& light, GPUTextureView* shadowMask)
|
void ShadowsPass::RenderShadow(RenderContextBatch& renderContextBatch, RendererPointLightData& light, GPUTextureView* shadowMask)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ private:
|
|||||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2 * 2> _psShadowDir;
|
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2 * 2> _psShadowDir;
|
||||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowPoint;
|
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowPoint;
|
||||||
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowSpot;
|
GPUPipelineStatePermutationsPs<static_cast<int32>(Quality::MAX) * 2> _psShadowSpot;
|
||||||
bool _supportsShadows;
|
PixelFormat _shadowMapFormat;
|
||||||
|
|
||||||
// Shadow maps stuff
|
// Shadow maps stuff
|
||||||
int32 _shadowMapsSizeCSM;
|
int32 _shadowMapsSizeCSM;
|
||||||
|
|||||||
Reference in New Issue
Block a user