Merge pull request #4734 from aws-lumberyard-dev/Atom/mriegger/directionallightbias

Atom/mriegger/directionallightbias
This commit is contained in:
Guthrie Adams
2021-10-20 15:22:33 -05:00
committed by GitHub
11 changed files with 74 additions and 24 deletions
@@ -111,16 +111,18 @@ void DirectionalLightShadow::GetShadowCoords(
float3 worldPosition,
out float3 shadowCoords[ViewSrg::MaxCascadeCount])
{
const float4x4 depthBiasMatrices[ViewSrg::MaxCascadeCount] =
ViewSrg::m_directionalLightShadows[lightIndex].m_depthBiasMatrices;
const uint cascadeCount = ViewSrg::m_directionalLightShadows[lightIndex].m_cascadeCount;
const float shadowBias = ViewSrg::m_directionalLightShadows[lightIndex].m_shadowBias;
const float4x4 lightViewToShadowmapMatrices[ViewSrg::MaxCascadeCount] = ViewSrg::m_directionalLightShadows[lightIndex].m_lightViewToShadowmapMatrices;
const float4x4 worldToLightViewMatrices[ViewSrg::MaxCascadeCount] = ViewSrg::m_directionalLightShadows[lightIndex].m_worldToLightViewMatrices;
for (uint index = 0; index < cascadeCount; ++index)
{
const float4x4 depthBiasMatrix = depthBiasMatrices[index];
const float4 shadowCoordHomogeneous = mul(depthBiasMatrix,
float4(worldPosition, 1.));
shadowCoords[index] = shadowCoordHomogeneous.xyz / shadowCoordHomogeneous.w;
float4 lightSpacePos = mul(worldToLightViewMatrices[index], float4(worldPosition, 1.));
lightSpacePos.z += shadowBias;
const float4 clipSpacePos = mul(lightViewToShadowmapMatrices[index], lightSpacePos);
shadowCoords[index] = clipSpacePos.xyz / clipSpacePos.w;
}
}
@@ -102,18 +102,19 @@ partial ShaderResourceGroup ViewSrg
struct DirectionalLightShadow
{
float4x4 m_depthBiasMatrices[MaxCascadeCount];
float4x4 m_lightViewToShadowmapMatrices[MaxCascadeCount];
float4x4 m_worldToLightViewMatrices[MaxCascadeCount];
float m_slopeBiasBase[MaxCascadeCount];
float m_boundaryScale;
uint m_shadowmapSize; // width and height of shadowmap
uint m_cascadeCount;
float m_shadowBias;
uint m_predictionSampleCount;
uint m_filteringSampleCount;
uint m_debugFlags;
uint m_shadowFilterMethod;
float m_far_minus_near;
float3 m_padding;
};
enum ShadowFilterMethod
@@ -157,6 +157,9 @@ namespace AZ
//! Sets whether the directional shadowmap should use receiver plane bias.
//! This attempts to reduce shadow acne when using large pcf filters.
virtual void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) = 0;
//! Reduces acne by applying a small amount of bias along shadow-space z.
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
};
} // namespace Render
} // namespace AZ
@@ -589,6 +589,15 @@ namespace AZ
m_shadowProperties.GetData(handle.GetIndex()).m_isReceiverPlaneBiasEnabled = enable;
}
void DirectionalLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias)
{
for (auto& it : m_shadowData)
{
it.second.GetData(handle.GetIndex()).m_shadowBias = bias;
}
m_shadowBufferNeedsUpdate = true;
}
void DirectionalLightFeatureProcessor::OnRenderPipelineAdded(RPI::RenderPipelinePtr pipeline)
{
PrepareForChangingRenderPipelineAndCameraView();
@@ -1522,10 +1531,6 @@ namespace AZ
for (uint16_t cascadeIndex = 0; cascadeIndex < GetCascadeCount(handle); ++cascadeIndex)
{
const Matrix4x4& worldToLightClipMatrix = property.m_segments.at(cameraView)[cascadeIndex].m_view->GetWorldToClipMatrix();
const Matrix4x4 depthBiasMatrix = Shadow::GetClipToShadowmapTextureMatrix() * worldToLightClipMatrix;
shadowData.m_depthBiasMatrices[cascadeIndex] = depthBiasMatrix;
const Matrix4x4& lightViewToLightClipMatrix = property.m_segments.at(cameraView)[cascadeIndex].m_view->GetViewToClipMatrix();
const Matrix4x4 lightViewToShadowmapMatrix = Shadow::GetClipToShadowmapTextureMatrix() * lightViewToLightClipMatrix;
shadowData.m_lightViewToShadowmapMatrices[cascadeIndex] = lightViewToShadowmapMatrix;
@@ -72,12 +72,6 @@ namespace AZ
// [GFX TODO][ATOM-15172] Look into compacting struct DirectionalLightShadowData
struct DirectionalLightShadowData
{
AZStd::array<Matrix4x4, Shadow::MaxNumberOfCascades> m_depthBiasMatrices =
{ {
Matrix4x4::CreateIdentity(),
Matrix4x4::CreateIdentity(),
Matrix4x4::CreateIdentity(),
Matrix4x4::CreateIdentity() } };
AZStd::array<Matrix4x4, Shadow::MaxNumberOfCascades> m_lightViewToShadowmapMatrices =
{ {
Matrix4x4::CreateIdentity(),
@@ -97,11 +91,14 @@ namespace AZ
float m_boundaryScale = 0.f;
uint32_t m_shadowmapSize = 1; // width and height of shadowmap
uint32_t m_cascadeCount = 1;
// Reduce acne by applying a small amount of bias to apply along shadow-space z.
float m_shadowBias = 0.0f;
uint32_t m_predictionSampleCount = 0;
uint32_t m_filteringSampleCount = 0;
uint32_t m_debugFlags = 0;
uint32_t m_shadowFilterMethod = 0;
float m_far_minus_near = 0;
float m_padding[3];
};
class DirectionalLightFeatureProcessor final
@@ -218,6 +215,7 @@ namespace AZ
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) override;
void SetShadowBias(LightHandle handle, float bias) override;
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
uint32_t GetLightCount() const;
@@ -168,6 +168,14 @@ namespace AZ
//! Sets whether the directional shadowmap should use receiver plane bias.
//! @param enable flag specifying whether to enable the receiver plane bias feature
virtual void SetShadowReceiverPlaneBiasEnabled(bool enable) = 0;
//! Shadow bias reduces acne by applying a small amount of offset along shadow-space z.
//! @return Returns the amount of bias to apply.
virtual float GetShadowBias() const = 0;
//! Shadow bias reduces acne by applying a small amount of offset along shadow-space z.
//! @param Sets the amount of bias to apply.
virtual void SetShadowBias(float bias) = 0;
};
using DirectionalLightRequestBus = EBus<DirectionalLightRequests>;
@@ -109,6 +109,9 @@ namespace AZ
//! This uses partial derivatives to reduce shadow acne when using large pcf kernels.
bool m_receiverPlaneBiasEnabled = true;
//! Reduces shadow acne by applying a small amount of offset along shadow-space z.
float m_shadowBias = 0.0f;
bool IsSplitManual() const;
bool IsSplitAutomatic() const;
bool IsCascadeCorrectionDisabled() const;
@@ -38,7 +38,8 @@ namespace AZ
->Field("IsDebugColoringEnabled", &DirectionalLightComponentConfig::m_isDebugColoringEnabled)
->Field("ShadowFilterMethod", &DirectionalLightComponentConfig::m_shadowFilterMethod)
->Field("PcfFilteringSampleCount", &DirectionalLightComponentConfig::m_filteringSampleCount)
->Field("ShadowReceiverPlaneBiasEnabled", &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled);
->Field("ShadowReceiverPlaneBiasEnabled", &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled)
->Field("Shadow Bias", &DirectionalLightComponentConfig::m_shadowBias);
}
}
@@ -84,6 +84,8 @@ namespace AZ
->Event("SetFilteringSampleCount", &DirectionalLightRequestBus::Events::SetFilteringSampleCount)
->Event("GetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::GetShadowReceiverPlaneBiasEnabled)
->Event("SetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::SetShadowReceiverPlaneBiasEnabled)
->Event("GetShadowBias", &DirectionalLightRequestBus::Events::GetShadowBias)
->Event("SetShadowBias", &DirectionalLightRequestBus::Events::SetShadowBias)
->VirtualProperty("Color", "GetColor", "SetColor")
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
->VirtualProperty("AngularDiameter", "GetAngularDiameter", "SetAngularDiameter")
@@ -98,7 +100,8 @@ namespace AZ
->VirtualProperty("DebugColoringEnabled", "GetDebugColoringEnabled", "SetDebugColoringEnabled")
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled");
->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled")
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias");
;
}
}
@@ -406,6 +409,20 @@ namespace AZ
return aznumeric_cast<uint32_t>(m_configuration.m_filteringSampleCount);
}
void DirectionalLightComponentController::SetShadowBias(float bias)
{
m_configuration.m_shadowBias = bias;
if (m_featureProcessor)
{
m_featureProcessor->SetShadowBias(m_lightHandle, bias);
}
}
float DirectionalLightComponentController::GetShadowBias() const
{
return m_configuration.m_shadowBias;
}
void DirectionalLightComponentController::SetFilteringSampleCount(uint32_t count)
{
const uint16_t count16 = GetMin(Shadow::MaxPcfSamplingCount, aznumeric_cast<uint16_t>(count));
@@ -499,6 +516,7 @@ namespace AZ
SetViewFrustumCorrectionEnabled(m_configuration.m_isCascadeCorrectionEnabled);
SetDebugColoringEnabled(m_configuration.m_isDebugColoringEnabled);
SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
SetShadowBias(m_configuration.m_shadowBias);
SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
SetShadowReceiverPlaneBiasEnabled(m_configuration.m_receiverPlaneBiasEnabled);
@@ -80,6 +80,8 @@ namespace AZ
void SetFilteringSampleCount(uint32_t count) override;
bool GetShadowReceiverPlaneBiasEnabled() const override;
void SetShadowReceiverPlaneBiasEnabled(bool enable) override;
float GetShadowBias() const override;
void SetShadowBias(float width) override;
private:
friend class EditorDirectionalLightComponent;
@@ -133,8 +133,8 @@ namespace AZ
->EnumAttribute(ShadowFilterMethod::Esm, "ESM")
->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count",
"This is used only when the pixel is predicted as on the boundary. "
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count\n",
"This is used only when the pixel is predicted as on the boundary.\n"
"Specific to PCF and ESM+PCF.")
->Attribute(Edit::Attributes::Min, 4)
->Attribute(Edit::Attributes::Max, 64)
@@ -142,10 +142,19 @@ namespace AZ
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
->DataElement(
Edit::UIHandlers::CheckBox, &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled,
"Shadow Receiver Plane Bias Enable",
"Shadow Receiver Plane Bias Enable\n",
"This reduces shadow acne when using large pcf kernels.")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled);
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
->DataElement(
Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowBias,
"Shadow Bias\n",
"Reduces acne by applying a fixed bias along z in shadow-space.\n"
"If this is 0, no biasing is applied.")
->Attribute(Edit::Attributes::Min, 0.f)
->Attribute(Edit::Attributes::Max, 0.2)
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
;
}
}