Atom/mriegger/normaloffsetbiasarealight (#4917)
* Adding directional light shadow bias * Adding normal offset bias for projected shadows Signed-off-by: mrieggeramzn <mriegger@amazon.com>
This commit is contained in:
+8
-1
@@ -14,6 +14,7 @@
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "BicubicPcfFilters.azsli"
|
||||
#include "Shadow.azsli"
|
||||
#include "NormalOffsetShadows.azsli"
|
||||
|
||||
// ProjectedShadow calculates shadowed area projected from a light.
|
||||
class ProjectedShadow
|
||||
@@ -123,6 +124,7 @@ float ProjectedShadow::GetThickness(uint shadowIndex, float3 worldPosition)
|
||||
|
||||
ProjectedShadow shadow;
|
||||
shadow.m_worldPosition = worldPosition;
|
||||
shadow.m_normalVector = 0; // The normal vector is used to reduce acne, this is not an issue when using the shadowmap to determine thickness.
|
||||
shadow.m_shadowIndex = shadowIndex;
|
||||
shadow.SetShadowPosition();
|
||||
return shadow.GetThickness();
|
||||
@@ -317,8 +319,13 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition)
|
||||
|
||||
void ProjectedShadow::SetShadowPosition()
|
||||
{
|
||||
const float normalBias = ViewSrg::m_projectedShadows[m_shadowIndex].m_normalShadowBias;
|
||||
const float shadowmapSize = ViewSrg::m_projectedFilterParams[m_shadowIndex].m_shadowmapSize;
|
||||
const float3 shadowOffset = ComputeNormalShadowOffset(normalBias, m_normalVector, shadowmapSize);
|
||||
const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix;
|
||||
float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition, 1));
|
||||
|
||||
float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition + shadowOffset, 1));
|
||||
|
||||
m_shadowPosition = shadowPositionHomogeneous.xyz / shadowPositionHomogeneous.w;
|
||||
|
||||
m_bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias / shadowPositionHomogeneous.w;
|
||||
|
||||
+2
@@ -86,6 +86,8 @@ namespace AZ
|
||||
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets the normal shadow bias
|
||||
virtual void SetNormalShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets the shadowmap size (width and height) of the light.
|
||||
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
|
||||
//! Specifies filter method of shadows.
|
||||
|
||||
+2
@@ -74,6 +74,8 @@ namespace AZ
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
|
||||
virtual void SetEsmExponent(LightHandle handle, float exponent) = 0;
|
||||
//! Sets the normal shadow bias. Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
virtual void SetNormalShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets all of the the point data for the provided LightHandle.
|
||||
virtual void SetPointData(LightHandle handle, const PointLightData& data) = 0;
|
||||
};
|
||||
|
||||
@@ -313,6 +313,11 @@ namespace AZ
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetNormalShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetNormalShadowBias, bias);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize);
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace AZ
|
||||
void SetConeAngles(LightHandle handle, float innerDegrees, float outerDegrees) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetNormalShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
|
||||
@@ -302,5 +302,10 @@ namespace AZ
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetEsmExponent, esmExponent);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetNormalShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetNormalShadowBias, bias);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetEsmExponent(LightHandle handle, float esmExponent) override;
|
||||
void SetNormalShadowBias(LightHandle handle, float bias) override;
|
||||
void SetPointData(LightHandle handle, const PointLightData& data) override;
|
||||
|
||||
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
|
||||
|
||||
@@ -155,8 +155,9 @@ namespace AZ::Render
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetNormalShadowBias().");
|
||||
|
||||
ShadowProperty& shadowProperty = GetShadowPropertyFromShadowId(id);
|
||||
shadowProperty.m_normalShadowBias = normalShadowBias;
|
||||
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(id.GetIndex());
|
||||
shadowData.m_normalShadowBias = normalShadowBias;
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size)
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace AZ::Render
|
||||
uint32_t m_filteringSampleCount = 0;
|
||||
AZStd::array<float, 2> m_unprojectConstants = { {0, 0} };
|
||||
float m_bias;
|
||||
float m_normalShadowBias;
|
||||
float m_normalShadowBias = 0;
|
||||
float m_esmExponent = 87.0f;
|
||||
float m_padding[3];
|
||||
};
|
||||
@@ -79,7 +79,6 @@ namespace AZ::Render
|
||||
ProjectedShadowDescriptor m_desc;
|
||||
RPI::ViewPtr m_shadowmapView;
|
||||
float m_bias = 0.1f;
|
||||
float m_normalShadowBias = 0.0f;
|
||||
ShadowId m_shadowId;
|
||||
};
|
||||
|
||||
|
||||
+7
@@ -132,6 +132,13 @@ namespace AZ
|
||||
//! Sets the Esm exponent. Higher values produce a steeper falloff between light and shadow.
|
||||
virtual void SetEsmExponent(float exponent) = 0;
|
||||
|
||||
//! Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
//! @return Returns the amount of bias to apply.
|
||||
virtual float GetNormalShadowBias() const = 0;
|
||||
|
||||
//! Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
//! @param normalShadowBias Sets the amount of normal shadow bias to apply.
|
||||
virtual void SetNormalShadowBias(float normalShadowBias) = 0;
|
||||
};
|
||||
|
||||
//! The EBus for requests to for setting and getting light component properties.
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ namespace AZ
|
||||
// Shadows (only used for supported shapes)
|
||||
bool m_enableShadow = false;
|
||||
float m_bias = 0.1f;
|
||||
float m_normalShadowBias = 0.0f;
|
||||
ShadowmapSize m_shadowmapMaxSize = ShadowmapSize::Size256;
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
uint16_t m_filteringSampleCount = 12;
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ namespace AZ
|
||||
// Shadows
|
||||
->Field("Enable Shadow", &AreaLightComponentConfig::m_enableShadow)
|
||||
->Field("Shadow Bias", &AreaLightComponentConfig::m_bias)
|
||||
->Field("Normal Shadow Bias", &AreaLightComponentConfig::m_normalShadowBias)
|
||||
->Field("Shadowmap Max Size", &AreaLightComponentConfig::m_shadowmapMaxSize)
|
||||
->Field("Shadow Filter Method", &AreaLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("Filtering Sample Count", &AreaLightComponentConfig::m_filteringSampleCount)
|
||||
|
||||
+18
@@ -70,6 +70,8 @@ namespace AZ::Render
|
||||
->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow)
|
||||
->Event("GetShadowBias", &AreaLightRequestBus::Events::GetShadowBias)
|
||||
->Event("SetShadowBias", &AreaLightRequestBus::Events::SetShadowBias)
|
||||
->Event("GetNormalShadowBias", &AreaLightRequestBus::Events::GetNormalShadowBias)
|
||||
->Event("SetNormalShadowBias", &AreaLightRequestBus::Events::SetNormalShadowBias)
|
||||
->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize)
|
||||
->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize)
|
||||
->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod)
|
||||
@@ -91,6 +93,7 @@ namespace AZ::Render
|
||||
|
||||
->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
@@ -302,6 +305,7 @@ namespace AZ::Render
|
||||
if (m_configuration.m_enableShadow)
|
||||
{
|
||||
m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias);
|
||||
m_lightShapeDelegate->SetNormalShadowBias(m_configuration.m_normalShadowBias);
|
||||
m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize);
|
||||
m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
m_lightShapeDelegate->SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
@@ -474,6 +478,20 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetNormalShadowBias(float bias)
|
||||
{
|
||||
m_configuration.m_normalShadowBias = bias;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetNormalShadowBias(bias);
|
||||
}
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetNormalShadowBias() const
|
||||
{
|
||||
return m_configuration.m_normalShadowBias;
|
||||
}
|
||||
|
||||
ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const
|
||||
{
|
||||
return m_configuration.m_shadowmapMaxSize;
|
||||
|
||||
+2
@@ -86,6 +86,8 @@ namespace AZ
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
float GetEsmExponent() const override;
|
||||
void SetEsmExponent(float exponent) override;
|
||||
float GetNormalShadowBias() const override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
void HandleDisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
|
||||
@@ -138,6 +138,14 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetNormalShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetNormalShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float exponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+11
-2
@@ -136,7 +136,7 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 100.0f)
|
||||
->Attribute(Edit::Attributes::SoftMin, 0.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 10.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
@@ -171,7 +171,16 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsEsmDisabled)
|
||||
;
|
||||
->DataElement(
|
||||
Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_normalShadowBias, "Normal Shadow Bias\n",
|
||||
"Reduces acne by biasing the shadowmap lookup along the geometric normal.\n"
|
||||
"If this is 0, no biasing is applied.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 10.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ namespace AZ
|
||||
void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {};
|
||||
void SetFilteringSampleCount([[maybe_unused]] uint32_t count) override {};
|
||||
void SetEsmExponent([[maybe_unused]] float esmExponent) override{};
|
||||
|
||||
void SetNormalShadowBias([[maybe_unused]] float bias) override{};
|
||||
|
||||
protected:
|
||||
void InitBase(EntityId entityId);
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace AZ
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff between light and shadow.
|
||||
virtual void SetEsmExponent(float exponent) = 0;
|
||||
//! Sets the normal bias. Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
virtual void SetNormalShadowBias(float bias) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -107,4 +107,13 @@ namespace AZ::Render
|
||||
GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetNormalShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetNormalShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float esmExponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user