Expose shadow bias to component & feature processors. (#2406)
* Expose shadow bias to component & feature processors. Shadow bias now works more consistently with various near / far shadow planes and caster positions. Bias now also affects esm shadows which helps eliminate acne in certain situations. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Adding jira comment to light configuration serialization version. Improved comment on final adjustment to bias before its sent to the shader. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com> * Hooking up bias to behavior context. Signed-off-by: Ken Pruiksma <pruiksma@amazon.com>
This commit is contained in:
+8
-5
@@ -62,6 +62,7 @@ class ProjectedShadow
|
||||
float3 m_lightDirection;
|
||||
float3 m_normalVector;
|
||||
float3 m_shadowPosition;
|
||||
float m_bias;
|
||||
};
|
||||
|
||||
float ProjectedShadow::GetVisibility(
|
||||
@@ -238,7 +239,7 @@ float ProjectedShadow::GetVisibilityEsm()
|
||||
}
|
||||
const float3 atlasPosition = GetAtlasPosition(m_shadowPosition.xy);
|
||||
const float depth = PerspectiveDepthToLinear(
|
||||
m_shadowPosition.z,
|
||||
m_shadowPosition.z - m_bias,
|
||||
coefficients);
|
||||
const float occluder = shadowmap.SampleLevel(
|
||||
PassSrg::LinearSampler,
|
||||
@@ -280,7 +281,7 @@ float ProjectedShadow::GetVisibilityEsmPcf()
|
||||
}
|
||||
const float3 atlasPosition = GetAtlasPosition(m_shadowPosition.xy);
|
||||
const float depth = PerspectiveDepthToLinear(
|
||||
m_shadowPosition.z,
|
||||
m_shadowPosition.z - m_bias,
|
||||
coefficients);
|
||||
const float occluder = shadowmap.SampleLevel(
|
||||
PassSrg::LinearSampler,
|
||||
@@ -346,7 +347,7 @@ float ProjectedShadow::SamplePcfBicubic()
|
||||
param.shadowPos = float3(atlasPosition.xy * ViewSrg::m_invShadowmapAtlasSize, atlasPosition.z);
|
||||
param.shadowMapSize = ViewSrg::m_shadowmapAtlasSize;
|
||||
param.invShadowMapSize = ViewSrg::m_invShadowmapAtlasSize;
|
||||
param.comparisonValue = m_shadowPosition.z - ViewSrg::m_projectedShadows[m_shadowIndex].m_bias;
|
||||
param.comparisonValue = m_shadowPosition.z - m_bias;
|
||||
param.samplerState = SceneSrg::m_hwPcfSampler;
|
||||
|
||||
if (filteringSampleCount <= 4)
|
||||
@@ -384,8 +385,8 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition)
|
||||
PassSrg::LinearSampler,
|
||||
float3(atlasPosition.xy * invAtlasSize, atlasPosition.z), /*LOD=*/0).r;
|
||||
const float depthDiff = depthInShadowmap - shadowPosition.z;
|
||||
float bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias;
|
||||
if (depthDiff < -bias)
|
||||
|
||||
if (depthDiff < -m_bias)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -428,6 +429,8 @@ void ProjectedShadow::SetShadowPosition()
|
||||
const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix;
|
||||
float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition, 1));
|
||||
m_shadowPosition = shadowPositionHomogeneous.xyz / shadowPositionHomogeneous.w;
|
||||
|
||||
m_bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias / shadowPositionHomogeneous.w;
|
||||
}
|
||||
|
||||
float3 ProjectedShadow::GetAtlasPosition(float2 texturePosition)
|
||||
|
||||
+2
@@ -84,6 +84,8 @@ namespace AZ
|
||||
|
||||
//! Sets if shadows are enabled
|
||||
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(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
@@ -66,6 +66,8 @@ namespace AZ
|
||||
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
|
||||
//! Sets the shadowmap size (width and height) of the light.
|
||||
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Specifies filter method of shadows.
|
||||
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
|
||||
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on
|
||||
|
||||
+2
@@ -50,6 +50,8 @@ namespace AZ::Render
|
||||
virtual void SetFieldOfViewY(ShadowId id, float fieldOfView) = 0;
|
||||
//! Sets the maximum resolution of the shadow map
|
||||
virtual void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(ShadowId id, float bias) = 0;
|
||||
//! Sets the shadowmap Pcf method.
|
||||
virtual void SetPcfMethod(ShadowId id, PcfMethod method) = 0;
|
||||
//! Sets the shadow filter method
|
||||
|
||||
@@ -308,6 +308,11 @@ namespace AZ
|
||||
AZStd::invoke(AZStd::forward<Functor>(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward<ParamType>(param));
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace AZ
|
||||
void SetConstrainToConeLight(LightHandle handle, bool useCone) override;
|
||||
void SetConeAngles(LightHandle handle, float innerDegrees, float outerDegrees) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
|
||||
@@ -277,6 +277,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace AZ
|
||||
void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override;
|
||||
void SetBulbRadius(LightHandle handle, float bulbRadius) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
|
||||
@@ -143,7 +143,15 @@ namespace AZ::Render
|
||||
shadowProperty.m_desc.m_fieldOfViewYRadians = fieldOfViewYRadians;
|
||||
UpdateShadowView(shadowProperty);
|
||||
}
|
||||
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetShadowBias(ShadowId id, float bias)
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowBias().");
|
||||
|
||||
ShadowProperty& shadowProperty = GetShadowPropertyFromShadowId(id);
|
||||
shadowProperty.m_bias = bias;
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size)
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution().");
|
||||
@@ -265,23 +273,20 @@ namespace AZ::Render
|
||||
view->SetCameraTransform(Matrix3x4::CreateFromTransform(desc.m_transform));
|
||||
|
||||
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(shadowProperty.m_shadowId.GetIndex());
|
||||
shadowData.m_bias = (nearDist / farDist) * 0.1f;
|
||||
|
||||
// Adjust the manually set bias to a more appropriate range for the shader. Scale the bias by the
|
||||
// near plane so that the bias appears consistent as other light properties change.
|
||||
shadowData.m_bias = nearDist * shadowProperty.m_bias * 0.01f;
|
||||
|
||||
FilterParameter& esmData = m_shadowData.GetElement<FilterParamIndex>(shadowProperty.m_shadowId.GetIndex());
|
||||
if (FilterMethodIsEsm(shadowData))
|
||||
{
|
||||
// Set parameters to calculate linear depth if ESM is used.
|
||||
m_filterParameterNeedsUpdate = true;
|
||||
esmData.m_isEnabled = true;
|
||||
esmData.m_n_f_n = nearDist / (farDist - nearDist);
|
||||
esmData.m_n_f = nearDist - farDist;
|
||||
esmData.m_f = farDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset enabling flag if ESM is not used.
|
||||
esmData.m_isEnabled = false;
|
||||
}
|
||||
|
||||
// Set parameters to calculate linear depth if ESM is used.
|
||||
esmData.m_n_f_n = nearDist / (farDist - nearDist);
|
||||
esmData.m_n_f = nearDist - farDist;
|
||||
esmData.m_f = farDist;
|
||||
|
||||
esmData.m_isEnabled = FilterMethodIsEsm(shadowData);
|
||||
m_filterParameterNeedsUpdate = m_filterParameterNeedsUpdate || esmData.m_isEnabled;
|
||||
|
||||
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses)
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace AZ::Render
|
||||
void SetAspectRatio(ShadowId id, float aspectRatio) override;
|
||||
void SetFieldOfViewY(ShadowId id, float fieldOfViewYRadians) override;
|
||||
void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override;
|
||||
void SetShadowBias(ShadowId id, float bias) override;
|
||||
void SetPcfMethod(ShadowId id, PcfMethod method);
|
||||
void SetEsmExponent(ShadowId id, float exponent);
|
||||
void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override;
|
||||
@@ -79,6 +80,7 @@ namespace AZ::Render
|
||||
{
|
||||
ProjectedShadowDescriptor m_desc;
|
||||
RPI::ViewPtr m_shadowmapView;
|
||||
float m_bias = 0.1f;
|
||||
ShadowId m_shadowId;
|
||||
};
|
||||
|
||||
|
||||
+6
@@ -101,6 +101,12 @@ namespace AZ
|
||||
|
||||
//! Sets if shadows should be enabled.
|
||||
virtual void SetEnableShadow(bool enabled) = 0;
|
||||
|
||||
//! Returns the shadow bias.
|
||||
virtual float GetShadowBias() const = 0;
|
||||
|
||||
//! Sets the shadow bias.
|
||||
virtual void SetShadowBias(float bias) = 0;
|
||||
|
||||
//! Returns the maximum width and height of shadowmap.
|
||||
virtual ShadowmapSize GetShadowmapMaxSize() const = 0;
|
||||
|
||||
+1
@@ -56,6 +56,7 @@ namespace AZ
|
||||
|
||||
// Shadows (only used for supported shapes)
|
||||
bool m_enableShadow = false;
|
||||
float m_bias = 0.1f;
|
||||
ShadowmapSize m_shadowmapMaxSize = ShadowmapSize::Size256;
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
PcfMethod m_pcfMethod = PcfMethod::Bicubic;
|
||||
|
||||
+2
-1
@@ -18,7 +18,7 @@ namespace AZ
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AreaLightComponentConfig, ComponentConfig>()
|
||||
->Version(6) // ATOM-15654
|
||||
->Version(7) // ATOM-16034
|
||||
->Field("LightType", &AreaLightComponentConfig::m_lightType)
|
||||
->Field("Color", &AreaLightComponentConfig::m_color)
|
||||
->Field("IntensityMode", &AreaLightComponentConfig::m_intensityMode)
|
||||
@@ -33,6 +33,7 @@ namespace AZ
|
||||
->Field("OuterShutterAngleDegrees", &AreaLightComponentConfig::m_outerShutterAngleDegrees)
|
||||
// Shadows
|
||||
->Field("Enable Shadow", &AreaLightComponentConfig::m_enableShadow)
|
||||
->Field("Shadow Bias", &AreaLightComponentConfig::m_bias)
|
||||
->Field("Shadowmap Max Size", &AreaLightComponentConfig::m_shadowmapMaxSize)
|
||||
->Field("Shadow Filter Method", &AreaLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("Softening Boundary Width", &AreaLightComponentConfig::m_boundaryWidthInDegrees)
|
||||
|
||||
+18
@@ -68,6 +68,8 @@ namespace AZ::Render
|
||||
|
||||
->Event("GetEnableShadow", &AreaLightRequestBus::Events::GetEnableShadow)
|
||||
->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow)
|
||||
->Event("GetShadowBias", &AreaLightRequestBus::Events::GetShadowBias)
|
||||
->Event("SetShadowBias", &AreaLightRequestBus::Events::SetShadowBias)
|
||||
->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize)
|
||||
->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize)
|
||||
->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod)
|
||||
@@ -94,6 +96,7 @@ namespace AZ::Render
|
||||
->VirtualProperty("OuterShutterAngle", "GetOuterShutterAngle", "SetOuterShutterAngle")
|
||||
|
||||
->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle")
|
||||
@@ -307,6 +310,7 @@ namespace AZ::Render
|
||||
m_lightShapeDelegate->SetEnableShadow(m_configuration.m_enableShadow);
|
||||
if (m_configuration.m_enableShadow)
|
||||
{
|
||||
m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias);
|
||||
m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize);
|
||||
m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
m_lightShapeDelegate->SetSofteningBoundaryWidthAngle(m_configuration.m_boundaryWidthInDegrees);
|
||||
@@ -467,6 +471,20 @@ namespace AZ::Render
|
||||
m_lightShapeDelegate->SetEnableShadow(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetShadowBias() const
|
||||
{
|
||||
return m_configuration.m_bias;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetShadowBias(float bias)
|
||||
{
|
||||
m_configuration.m_bias = bias;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetShadowBias(bias);
|
||||
}
|
||||
}
|
||||
|
||||
ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const
|
||||
{
|
||||
|
||||
+2
@@ -76,6 +76,8 @@ namespace AZ
|
||||
|
||||
bool GetEnableShadow() const override;
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
float GetShadowBias() const override;
|
||||
void SetShadowBias(float bias) override;
|
||||
ShadowmapSize GetShadowmapMaxSize() const override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
ShadowFilterMethod GetShadowFilterMethod() const override;
|
||||
|
||||
@@ -123,6 +123,14 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace AZ
|
||||
void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) override;
|
||||
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
void SetShadowBias(float bias) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
|
||||
+9
@@ -131,6 +131,15 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_bias, "Bias", "How deep in shadow a surface must be before being affected by it.")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 100.0f)
|
||||
->Attribute(Edit::Attributes::SoftMin, 0.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 1.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowFilterMethod, "Shadow filter method",
|
||||
"Filtering method of edge-softening of shadows.\n"
|
||||
" None: no filtering\n"
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace AZ
|
||||
void SetShutterAngles([[maybe_unused]]float innerAngleDegrees, [[maybe_unused]]float outerAngleDegrees) override {};
|
||||
|
||||
void SetEnableShadow(bool enabled) override { m_shadowsEnabled = enabled; };
|
||||
void SetShadowBias([[maybe_unused]] float bias) override {};
|
||||
void SetShadowmapMaxSize([[maybe_unused]] ShadowmapSize size) override {};
|
||||
void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {};
|
||||
void SetSofteningBoundaryWidthAngle([[maybe_unused]] float widthInDegrees) override {};
|
||||
|
||||
+3
-1
@@ -67,8 +67,10 @@ namespace AZ
|
||||
|
||||
// Shadows
|
||||
|
||||
//! Sets if shadows should be enabled
|
||||
//! Sets if shadows should be enabled
|
||||
virtual void SetEnableShadow(bool enabled) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(float bias) = 0;
|
||||
//! Sets the maximum resolution of the shadow map
|
||||
virtual void SetShadowmapMaxSize(ShadowmapSize size) = 0;
|
||||
//! Sets the filter method for the shadow
|
||||
|
||||
+85
-82
@@ -11,121 +11,124 @@
|
||||
#include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Render
|
||||
{
|
||||
namespace Render
|
||||
SphereLightDelegate::SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<PointLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
, m_shapeBus(shapeBus)
|
||||
{
|
||||
SphereLightDelegate::SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible)
|
||||
: LightDelegateBase<PointLightFeatureProcessorInterface>(entityId, isVisible)
|
||||
, m_shapeBus(shapeBus)
|
||||
{
|
||||
InitBase(entityId);
|
||||
}
|
||||
InitBase(entityId);
|
||||
}
|
||||
|
||||
float SphereLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
float SphereLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
|
||||
{
|
||||
// Calculate the radius at which the irradiance will be equal to cutoffIntensity.
|
||||
float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
|
||||
return sqrt(intensity / lightThreshold);
|
||||
}
|
||||
|
||||
void SphereLightDelegate::HandleShapeChanged()
|
||||
void SphereLightDelegate::HandleShapeChanged()
|
||||
{
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
GetFeatureProcessor()->SetBulbRadius(GetLightHandle(), GetRadius());
|
||||
}
|
||||
GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
|
||||
GetFeatureProcessor()->SetBulbRadius(GetLightHandle(), GetRadius());
|
||||
}
|
||||
}
|
||||
|
||||
float SphereLightDelegate::GetSurfaceArea() const
|
||||
{
|
||||
float radius = GetRadius();
|
||||
return 4.0f * Constants::Pi * radius * radius;
|
||||
}
|
||||
float SphereLightDelegate::GetSurfaceArea() const
|
||||
{
|
||||
float radius = GetRadius();
|
||||
return 4.0f * Constants::Pi * radius * radius;
|
||||
}
|
||||
|
||||
float SphereLightDelegate::GetRadius() const
|
||||
{
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetUniformScale();
|
||||
}
|
||||
float SphereLightDelegate::GetRadius() const
|
||||
{
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetUniformScale();
|
||||
}
|
||||
|
||||
void SphereLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
void SphereLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
// Draw a sphere for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), GetConfig()->m_attenuationRadius);
|
||||
}
|
||||
// Draw a sphere for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), GetConfig()->m_attenuationRadius);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetEnableShadow(bool enabled)
|
||||
void SphereLightDelegate::SetEnableShadow(bool enabled)
|
||||
{
|
||||
Base::SetEnableShadow(enabled);
|
||||
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
Base::SetEnableShadow(enabled);
|
||||
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
|
||||
}
|
||||
GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
|
||||
}
|
||||
GetFeatureProcessor()->SetShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
|
||||
}
|
||||
GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetPredictionSampleCount(uint32_t count)
|
||||
void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
void SphereLightDelegate::SetPredictionSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetPcfMethod(PcfMethod method)
|
||||
void SphereLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method);
|
||||
}
|
||||
GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetEsmExponent(float esmExponent)
|
||||
void SphereLightDelegate::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent);
|
||||
}
|
||||
GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
void SphereLightDelegate::SetEsmExponent(float esmExponent)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent);
|
||||
}
|
||||
}
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace AZ
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; }
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
void SetShadowBias(float bias) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
|
||||
Reference in New Issue
Block a user