Merge pull request #395 from aws-lumberyard-dev/Atom/mriegger/PLS
Atom/mriegger/pls
This commit is contained in:
+72
-2
@@ -13,6 +13,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
|
||||
#include <Atom/Features/Shadow/ProjectedShadow.azsli>
|
||||
|
||||
// The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp
|
||||
static const float3 PointLightShadowCubemapDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)};
|
||||
|
||||
int GetPointLightShadowCubemapFace(const float3 targetPos, const float3 lightPos)
|
||||
{
|
||||
const float3 toPoint = targetPos - lightPos;
|
||||
const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y)));
|
||||
if (toPoint.x == -maxElement)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (toPoint.x == maxElement)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (toPoint.y == -maxElement)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if (toPoint.y == maxElement)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
else if (toPoint.z == -maxElement)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
// PointLight::m_shadowIndices actually consists of uint16_t x 6 on the CPU, but visible as a uint32_t x 3 on the GPU.
|
||||
// This function returns the proper uint16_t value given an input face in the range 0-5
|
||||
int UnpackPointLightShadowIndex(const ViewSrg::PointLight light, const int face)
|
||||
{
|
||||
const int index = face >> 1;
|
||||
const int shiftAmount = (face & 1) * 16;
|
||||
return (light.m_shadowIndices[index] >> shiftAmount) & 0xFFFF;
|
||||
}
|
||||
|
||||
void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData)
|
||||
{
|
||||
@@ -31,11 +74,38 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD
|
||||
d2 = max(0.001 * 0.001, d2); // clamp the light to at least 1mm away to avoid extreme values.
|
||||
float3 lightIntensity = (light.m_rgbIntensityCandelas / d2) * radiusAttenuation;
|
||||
|
||||
// shadow
|
||||
float litRatio = 1.0;
|
||||
|
||||
// How much is back face shadowed, it's set to the reverse of litRatio to share the same default value with thickness, which should be 0 if no shadow map available
|
||||
float backShadowRatio = 0.0;
|
||||
if (o_enableShadows)
|
||||
{
|
||||
const int shadowCubemapFace = GetPointLightShadowCubemapFace(surface.position, light.m_position);
|
||||
const int shadowIndex = UnpackPointLightShadowIndex(light, shadowCubemapFace);
|
||||
|
||||
litRatio *= ProjectedShadow::GetVisibility(
|
||||
shadowIndex,
|
||||
light.m_position,
|
||||
surface.position,
|
||||
PointLightShadowCubemapDirections[shadowCubemapFace],
|
||||
surface.normal);
|
||||
|
||||
// Use backShadowRatio to carry thickness from shadow map for thick mode
|
||||
backShadowRatio = 1.0 - litRatio;
|
||||
if (o_transmission_mode == TransmissionMode::ThickObject)
|
||||
{
|
||||
backShadowRatio = ProjectedShadow::GetThickness(
|
||||
shadowIndex,
|
||||
surface.position);
|
||||
}
|
||||
}
|
||||
|
||||
// Diffuse contribution
|
||||
lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight));
|
||||
lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio;
|
||||
|
||||
// Tranmission contribution
|
||||
lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0);
|
||||
lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), backShadowRatio);
|
||||
|
||||
// Adjust the light direcion for specular based on bulb size
|
||||
|
||||
|
||||
+2
@@ -61,6 +61,8 @@ ShaderResourceGroup RayTracingSceneSrg : SRG_RayTracingScene
|
||||
float m_invAttenuationRadiusSquared;
|
||||
float3 m_rgbIntensity;
|
||||
float m_bulbRadius;
|
||||
uint3 m_shadowIndices;
|
||||
uint m_padding;
|
||||
};
|
||||
|
||||
StructuredBuffer<PointLight> m_pointLights;
|
||||
|
||||
@@ -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;
|
||||
uint3 m_shadowIndices;
|
||||
uint m_padding;
|
||||
};
|
||||
|
||||
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;
|
||||
uint3 m_shadowIndices;
|
||||
uint m_padding;
|
||||
};
|
||||
|
||||
struct DiskLight
|
||||
|
||||
+50
-14
@@ -1,19 +1,20 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/FeatureProcessor.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <Atom/Feature/CoreLights/ShadowConstants.h>
|
||||
#include <Atom/RPI.Public/FeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -22,9 +23,25 @@ namespace AZ
|
||||
|
||||
namespace Render
|
||||
{
|
||||
struct PointLightData
|
||||
{
|
||||
AZStd::array<float, 3> m_position = {{0.0f, 0.0f, 0.0f}};
|
||||
|
||||
// Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations.
|
||||
float m_invAttenuationRadiusSquared = 0.0f;
|
||||
|
||||
AZStd::array<float, 3> m_rgbIntensity = {{0.0f, 0.0f, 0.0f}};
|
||||
|
||||
// Radius of spherical light in meters.
|
||||
float m_bulbRadius = 0.0f;
|
||||
|
||||
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
|
||||
class PointLightFeatureProcessorInterface : public RPI::FeatureProcessor
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AZ::Render::PointLightFeatureProcessorInterface, "{D3E0B016-F3C6-4C7A-A29E-0B3A4FA87806}", AZ::RPI::FeatureProcessor);
|
||||
@@ -33,7 +50,8 @@ namespace AZ
|
||||
using LightHandle = RHI::Handle<uint16_t, class PointLight>;
|
||||
static constexpr PhotometricUnit PhotometricUnitType = PhotometricUnit::Candela;
|
||||
|
||||
//! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no longer needed.
|
||||
//! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no
|
||||
//! longer needed.
|
||||
virtual LightHandle AcquireLight() = 0;
|
||||
//! Releases a LightHandle which removes the point light.
|
||||
virtual bool ReleaseLight(LightHandle& handle) = 0;
|
||||
@@ -48,6 +66,24 @@ 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;
|
||||
//! 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
|
||||
|
||||
@@ -380,7 +380,7 @@ namespace AZ
|
||||
const float invRadiusSquared = diskLight.m_invAttenuationRadiusSquared;
|
||||
if (invRadiusSquared <= 0.f)
|
||||
{
|
||||
AZ_Assert(false, "Attenuation radius have to be set before use the light.");
|
||||
AZ_Assert(false, "Attenuation radius must be set before using the light.");
|
||||
return;
|
||||
}
|
||||
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -44,6 +44,13 @@ namespace AZ
|
||||
PointLightFeatureProcessor::PointLightFeatureProcessor()
|
||||
: PointLightFeatureProcessorInterface()
|
||||
{
|
||||
// Note must match PointShadowDirections in PointLight.azsli
|
||||
m_pointShadowTransforms[0] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisX());
|
||||
m_pointShadowTransforms[1] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisX());
|
||||
m_pointShadowTransforms[2] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisY());
|
||||
m_pointShadowTransforms[3] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisY());
|
||||
m_pointShadowTransforms[4] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisZ());
|
||||
m_pointShadowTransforms[5] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisZ());
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::Activate()
|
||||
@@ -54,6 +61,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 +91,15 @@ namespace AZ
|
||||
{
|
||||
if (handle.IsValid())
|
||||
{
|
||||
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
|
||||
{
|
||||
ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndices[i]);
|
||||
if (shadowId.IsValid())
|
||||
{
|
||||
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
|
||||
}
|
||||
}
|
||||
|
||||
m_pointLightData.RemoveIndex(handle.GetIndex());
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
handle.Reset();
|
||||
@@ -148,6 +165,7 @@ namespace AZ
|
||||
lightPosition.StoreToFloat3(position.data());
|
||||
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
UpdateShadow(handle);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetAttenuationRadius(LightHandle handle, float attenuationRadius)
|
||||
@@ -177,5 +195,122 @@ namespace AZ
|
||||
return m_lightBufferHandler.GetElementCount();
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetShadowsEnabled(LightHandle handle, bool enabled)
|
||||
{
|
||||
auto& light = m_pointLightData.GetData(handle.GetIndex());
|
||||
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
|
||||
{
|
||||
ShadowId shadowId = ShadowId(light.m_shadowIndices[i]);
|
||||
if (shadowId.IsValid() && !enabled)
|
||||
{
|
||||
// Disable shadows
|
||||
m_shadowFeatureProcessor->ReleaseShadow(shadowId);
|
||||
shadowId.Reset();
|
||||
light.m_shadowIndices[i] = shadowId.GetIndex();
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
else if (shadowId.IsNull() && enabled)
|
||||
{
|
||||
// Enable shadows
|
||||
light.m_shadowIndices[i] = m_shadowFeatureProcessor->AcquireShadow().GetIndex();
|
||||
|
||||
UpdateShadow(handle);
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetPointData(LightHandle handle, const PointLightData& data)
|
||||
{
|
||||
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetPointData().");
|
||||
|
||||
m_pointLightData.GetData(handle.GetIndex()) = data;
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
UpdateShadow(handle);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::UpdateShadow(LightHandle handle)
|
||||
{
|
||||
constexpr float SqrtHalf = 0.707106781187f; // sqrt(0.5);
|
||||
|
||||
const auto& pointLight = m_pointLightData.GetData(handle.GetIndex());
|
||||
for (int i = 0; i < PointLightData::NumShadowFaces; ++i)
|
||||
{
|
||||
ShadowId shadowId = ShadowId(pointLight.m_shadowIndices[i]);
|
||||
if (shadowId.IsNull())
|
||||
{
|
||||
// Early out if shadows are disabled.
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId);
|
||||
// Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces
|
||||
desc.m_fieldOfViewYRadians = DegToRad(91.0f);
|
||||
desc.m_transform = m_pointShadowTransforms[i];
|
||||
desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]);
|
||||
desc.m_aspectRatio = 1.0f;
|
||||
desc.m_nearPlaneDistance = SqrtHalf * pointLight.m_bulbRadius;
|
||||
|
||||
const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared;
|
||||
if (invRadiusSquared <= 0.f)
|
||||
{
|
||||
AZ_Assert(false, "Attenuation radius must be set before using the light.");
|
||||
return;
|
||||
}
|
||||
const float attenuationRadius = sqrtf(1.f / invRadiusSquared);
|
||||
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)
|
||||
{
|
||||
AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting().");
|
||||
|
||||
auto& light = m_pointLightData.GetData(handle.GetIndex());
|
||||
for (int lightIndex = 0; lightIndex < PointLightData::NumShadowFaces; ++lightIndex)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -24,15 +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.
|
||||
};
|
||||
|
||||
class PointLightFeatureProcessor final
|
||||
: public PointLightFeatureProcessorInterface
|
||||
{
|
||||
@@ -58,18 +50,34 @@ 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;
|
||||
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;
|
||||
|
||||
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;
|
||||
bool m_deviceBufferNeedsUpdate = false;
|
||||
|
||||
AZStd::array<AZ::Transform, PointLightData::NumShadowFaces> m_pointShadowTransforms;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ namespace AZ
|
||||
|
||||
bool AreaLightComponentConfig::SupportsShadows() const
|
||||
{
|
||||
return m_shapeType == AZ_CRC_CE("DiskShape");
|
||||
return m_lightType == LightType::SpotDisk || m_lightType == LightType::Sphere;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::ShadowsDisabled() const
|
||||
|
||||
@@ -63,5 +63,64 @@ namespace AZ
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetEnableShadow(bool enabled)
|
||||
{
|
||||
Base::SetEnableShadow(enabled);
|
||||
|
||||
if (GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetPredictionSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetPcfMethod(PcfMethod method)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace AZ
|
||||
class SphereLightDelegate final
|
||||
: public LightDelegateBase<PointLightFeatureProcessorInterface>
|
||||
{
|
||||
using Base = LightDelegateBase<PointLightFeatureProcessorInterface>;
|
||||
|
||||
public:
|
||||
SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible);
|
||||
|
||||
@@ -32,6 +34,13 @@ namespace AZ
|
||||
void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override;
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; }
|
||||
void SetEnableShadow(bool enabled) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
void SetPredictionSampleCount(uint32_t count) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetPcfMethod(PcfMethod method) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user