Adding full shadowmap support
This commit is contained in:
+28
@@ -23,6 +23,20 @@ namespace AZ
|
||||
|
||||
namespace Render
|
||||
{
|
||||
struct PointLightData
|
||||
{
|
||||
AZStd::array<float, 3> m_position = {{0.0f, 0.0f, 0.0f}};
|
||||
float m_invAttenuationRadiusSquared =
|
||||
0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations.
|
||||
AZStd::array<float, 3> m_rgbIntensity = {{0.0f, 0.0f, 0.0f}};
|
||||
float m_bulbRadius = 0.0f; // Radius of spherical light in meters.
|
||||
|
||||
static const int NumShadowFaces = 6;
|
||||
|
||||
AZStd::array<uint16_t, NumShadowFaces> m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}};
|
||||
uint32_t m_padding;
|
||||
};
|
||||
|
||||
//! PointLightFeatureProcessorInterface provides an interface to acquire, release, and update a point light.
|
||||
class PointLightFeatureProcessorInterface
|
||||
: public RPI::FeatureProcessor
|
||||
@@ -53,6 +67,20 @@ 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;
|
||||
//! 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
|
||||
//! the boundary. 0 disables softening.
|
||||
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
|
||||
//! Sets sample count to predict boundary of shadow (up to 16). It will be clamped to be less than or equal to the filtering
|
||||
//! sample count.
|
||||
virtual void SetPredictionSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets sample count for filtering of shadow boundary (up to 64)
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets the shadowmap Pcf (percentage closer filtering) method.
|
||||
virtual void SetPcfMethod(LightHandle handle, PcfMethod method) = 0;
|
||||
//! Sets all of the the point data for the provided LightHandle.
|
||||
virtual void SetPointData(LightHandle handle, const PointLightData& data) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace AZ
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
void SetPredictionSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetPcfMethod(LightHandle handle, PcfMethod method);
|
||||
void SetPcfMethod(LightHandle handle, PcfMethod method) override;
|
||||
|
||||
void SetDiskData(LightHandle handle, const DiskLightData& data) override;
|
||||
|
||||
|
||||
@@ -219,6 +219,15 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetPointData(LightHandle handle, const PointLightData& data)
|
||||
{
|
||||
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetDiskData().");
|
||||
|
||||
m_pointLightData.GetData(handle.GetIndex()) = data;
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
UpdateShadow(handle);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::UpdateShadow(LightHandle handle)
|
||||
{
|
||||
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
|
||||
@@ -237,7 +246,7 @@ namespace AZ
|
||||
desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces
|
||||
desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]);
|
||||
desc.m_aspectRatio = 1.0f;
|
||||
desc.m_nearPlaneDistance = 0.1f;
|
||||
desc.m_nearPlaneDistance = 0.0f;
|
||||
|
||||
const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared;
|
||||
if (invRadiusSquared <= 0.f)
|
||||
@@ -246,33 +255,59 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
|
||||
desc.m_farPlaneDistance = attenuationRadius;
|
||||
desc.m_farPlaneDistance = attenuationRadius + pointLight.m_bulbRadius;
|
||||
|
||||
m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Functor, typename ParamType>
|
||||
void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param, const int lightIndex)
|
||||
void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param)
|
||||
{
|
||||
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting().");
|
||||
|
||||
auto& light = m_pointLightData.GetData(handle.GetIndex());
|
||||
ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]);
|
||||
|
||||
AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled.");
|
||||
if (shadowId.IsValid())
|
||||
for (int lightIndex = 0; lightIndex < PointLightData::NumShadowFaces; ++lightIndex)
|
||||
{
|
||||
AZStd::invoke(AZStd::forward<Functor>(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward<ParamType>(param));
|
||||
ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]);
|
||||
|
||||
AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled.");
|
||||
if (shadowId.IsValid())
|
||||
{
|
||||
AZStd::invoke(AZStd::forward<Functor>(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward<ParamType>(param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
|
||||
{
|
||||
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize, i);
|
||||
}
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetPredictionSampleCount(LightHandle handle, uint16_t count)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPredictionSampleCount, count);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetFilteringSampleCount, count);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetPcfMethod(LightHandle handle, PcfMethod method)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPcfMethod, method);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -25,20 +25,6 @@ namespace AZ
|
||||
|
||||
namespace Render
|
||||
{
|
||||
|
||||
struct PointLightData
|
||||
{
|
||||
AZStd::array<float, 3> m_position = { { 0.0f, 0.0f, 0.0f } };
|
||||
float m_invAttenuationRadiusSquared = 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations.
|
||||
AZStd::array<float, 3> m_rgbIntensity = { { 0.0f, 0.0f, 0.0f } };
|
||||
float m_bulbRadius = 0.0f; // Radius of spherical light in meters.
|
||||
|
||||
static const int NumShadowFaces = 6;
|
||||
|
||||
AZStd::array<uint16_t, NumShadowFaces> m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}};
|
||||
uint32_t m_padding;
|
||||
};
|
||||
|
||||
class PointLightFeatureProcessor final
|
||||
: public PointLightFeatureProcessorInterface
|
||||
{
|
||||
@@ -66,6 +52,12 @@ namespace AZ
|
||||
void SetBulbRadius(LightHandle handle, float bulbRadius) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
void SetPredictionSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetPcfMethod(LightHandle handle, PcfMethod method) override;
|
||||
void SetPointData(LightHandle handle, const PointLightData& data) override;
|
||||
|
||||
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
|
||||
uint32_t GetLightCount()const;
|
||||
@@ -78,7 +70,7 @@ namespace AZ
|
||||
void UpdateShadow(LightHandle handle);
|
||||
// Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor
|
||||
template<typename Functor, typename ParamType>
|
||||
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param, const int lightIndex);
|
||||
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param);
|
||||
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr;
|
||||
|
||||
IndexedDataVector<PointLightData> m_pointLightData;
|
||||
|
||||
Reference in New Issue
Block a user