Initial pointlight shadow work
This commit is contained in:
@@ -73,6 +73,8 @@ partial ShaderResourceGroup ViewSrg
|
||||
float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2.
|
||||
float3 m_rgbIntensityCandelas;
|
||||
float m_bulbRadius;
|
||||
uint m_shadowIndex;
|
||||
uint m_padding[3];
|
||||
};
|
||||
|
||||
StructuredBuffer<PointLight> m_pointLights;
|
||||
|
||||
@@ -63,6 +63,8 @@ partial ShaderResourceGroup RayTracingSceneSrg
|
||||
float m_invAttenuationRadiusSquared;
|
||||
float3 m_rgbIntensity;
|
||||
float m_bulbRadius;
|
||||
uint m_shadowIndex;
|
||||
uint m_padding[3];
|
||||
};
|
||||
|
||||
StructuredBuffer<PointLight> m_pointLights;
|
||||
|
||||
@@ -59,6 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2.
|
||||
float3 m_rgbIntensityCandelas;
|
||||
float m_bulbRadius;
|
||||
uint m_shadowIndex;
|
||||
uint m_padding[3];
|
||||
};
|
||||
|
||||
struct DiskLight
|
||||
|
||||
+3
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <Atom/RPI.Public/FeatureProcessor.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <Atom/Feature/CoreLights/ShadowConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -48,6 +49,8 @@ namespace AZ
|
||||
virtual void SetAttenuationRadius(LightHandle handle, float attenuationRadius) = 0;
|
||||
//! Sets the bulb radius for the provided LightHandle. Values greater than zero effectively make it a spherical light.
|
||||
virtual void SetBulbRadius(LightHandle handle, float bulbRadius) = 0;
|
||||
//! Sets if shadows are enabled
|
||||
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace AZ
|
||||
template <typename Functor, typename ParamType>
|
||||
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param);
|
||||
|
||||
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor;
|
||||
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr;
|
||||
|
||||
IndexedDataVector<DiskLightData> m_diskLightData;
|
||||
GpuBufferHandler m_lightBufferHandler;
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace AZ
|
||||
desc.m_elementCountSrgName = "m_pointLightCount";
|
||||
desc.m_elementSize = sizeof(PointLightData);
|
||||
desc.m_srgLayout = RPI::RPISystemInterface::Get()->GetViewSrgAsset()->GetLayout();
|
||||
m_shadowFeatureProcessor = GetParentScene()->GetFeatureProcessor<ProjectedShadowFeatureProcessor>();
|
||||
|
||||
m_lightBufferHandler = GpuBufferHandler(desc);
|
||||
}
|
||||
@@ -83,6 +84,11 @@ namespace AZ
|
||||
{
|
||||
if (handle.IsValid())
|
||||
{
|
||||
ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndex);
|
||||
if (shadowId.IsValid())
|
||||
{
|
||||
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
|
||||
}
|
||||
m_pointLightData.RemoveIndex(handle.GetIndex());
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
handle.Reset();
|
||||
@@ -177,5 +183,86 @@ namespace AZ
|
||||
return m_lightBufferHandler.GetElementCount();
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowsEnabled(LightHandle handle, bool enabled)
|
||||
{
|
||||
auto& light = m_pointLightData.GetData(handle.GetIndex());
|
||||
ShadowId shadowId = ShadowId(light.m_shadowIndex);
|
||||
if (shadowId.IsValid() && enabled == false)
|
||||
{
|
||||
// Disable shadows
|
||||
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
|
||||
shadowId.Reset();
|
||||
light.m_shadowIndex = shadowId.GetIndex();
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
else if (shadowId.IsNull() && enabled == true)
|
||||
{
|
||||
// Enable shadows
|
||||
light.m_shadowIndex = m_shadowFeatureProcessor->AcquireShadow().GetIndex();
|
||||
|
||||
UpdateShadow(handle);
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::UpdateShadow(LightHandle handle)
|
||||
{
|
||||
const auto& pointLight = m_pointLightData.GetData(handle.GetIndex());
|
||||
ShadowId shadowId = ShadowId(pointLight.m_shadowIndex);
|
||||
if (shadowId.IsNull())
|
||||
{
|
||||
// Early out if shadows are disabled.
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc =
|
||||
m_shadowFeatureProcessor->GetShadowProperties(shadowId);
|
||||
|
||||
Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data());
|
||||
|
||||
constexpr float SmallAngle = 0.01f;
|
||||
desc.m_fieldOfViewYRadians = 1.57f;
|
||||
|
||||
// To handle bulb radius, set the position of the shadow caster behind the actual light depending on the radius of the bulb
|
||||
//
|
||||
// \ /
|
||||
// \ /
|
||||
// \_____/ <-- position of light itself (and forward plane of shadow casting view)
|
||||
// . .
|
||||
// . .
|
||||
// * <-- position of shadow casting view
|
||||
//
|
||||
desc.m_transform = Transform::CreateLookAt(position, AZ::Vector3::CreateZero());
|
||||
|
||||
desc.m_aspectRatio = 1.0f;
|
||||
desc.m_nearPlaneDistance = 0.1f;
|
||||
|
||||
const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared;
|
||||
if (invRadiusSquared <= 0.f)
|
||||
{
|
||||
AZ_Assert(false, "Attenuation radius have to be set before use the light.");
|
||||
return;
|
||||
}
|
||||
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
|
||||
desc.m_farPlaneDistance = attenuationRadius;
|
||||
|
||||
m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc);
|
||||
}
|
||||
|
||||
template<typename Functor, typename ParamType>
|
||||
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_shadowIndex);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/Utils/GpuBufferHandler.h>
|
||||
#include <CoreLights/IndexedDataVector.h>
|
||||
#include <Shadows/ProjectedShadowFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -31,6 +32,8 @@ namespace AZ
|
||||
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.
|
||||
uint32_t m_shadowIndex;
|
||||
uint32_t m_padding[3];
|
||||
};
|
||||
|
||||
class PointLightFeatureProcessor final
|
||||
@@ -58,14 +61,21 @@ namespace AZ
|
||||
void SetPosition(LightHandle handle, const AZ::Vector3& lightPosition) override;
|
||||
void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override;
|
||||
void SetBulbRadius(LightHandle handle, float bulbRadius) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
|
||||
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
|
||||
uint32_t GetLightCount()const;
|
||||
|
||||
private:
|
||||
PointLightFeatureProcessor(const PointLightFeatureProcessor&) = delete;
|
||||
using ShadowId = ProjectedShadowFeatureProcessor::ShadowId;
|
||||
|
||||
static constexpr const char* FeatureProcessorName = "PointLightFeatureProcessor";
|
||||
void UpdateShadow(LightHandle handle);
|
||||
// Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor
|
||||
template<typename Functor, typename ParamType>
|
||||
void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param);
|
||||
ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr;
|
||||
|
||||
IndexedDataVector<PointLightData> m_pointLightData;
|
||||
GpuBufferHandler m_lightBufferHandler;
|
||||
|
||||
Reference in New Issue
Block a user