2
0
Эх сурвалжийг харах

Added exposure controls to the ReflectionProbe component

Signed-off-by: dmcdiar <[email protected]>
dmcdiar 3 жил өмнө
parent
commit
fe005c9c50
16 өөрчлөгдсөн 99 нэмэгдсэн , 9 устгасан
  1. 1 0
      Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli
  2. 3 3
      Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
  3. 1 0
      Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Skin/SkinObjectSrg.azsli
  4. 1 1
      Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl
  5. 1 0
      Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli
  6. 1 1
      Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl
  7. 2 0
      Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h
  8. 2 0
      Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h
  9. 4 0
      Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp
  10. 15 2
      Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp
  11. 11 0
      Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h
  12. 12 0
      Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp
  13. 20 0
      Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp
  14. 2 0
      Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.h
  15. 17 2
      Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp
  16. 6 0
      Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.h

+ 1 - 0
Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli

@@ -37,6 +37,7 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject
         float m_padding;
         float m_padding;
         bool m_useReflectionProbe;
         bool m_useReflectionProbe;
         bool m_useParallaxCorrection;
         bool m_useParallaxCorrection;
+        float m_exposure;
     };
     };
 
 
     ReflectionProbeData m_reflectionProbeData;
     ReflectionProbeData m_reflectionProbeData;

+ 3 - 3
Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli

@@ -85,12 +85,12 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
 
 
     if(useIbl)
     if(useIbl)
     {
     {
-        float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
+        float exposure = pow(2.0, ObjectSrg::m_reflectionProbeData.m_exposure);
         
         
         if(useDiffuseIbl)
         if(useDiffuseIbl)
         {
         {
             float3 iblDiffuse = GetIblDiffuse(surface.normal, surface.albedo, lightingData.diffuseResponse);
             float3 iblDiffuse = GetIblDiffuse(surface.normal, surface.albedo, lightingData.diffuseResponse);
-            lightingData.diffuseLighting += (iblDiffuse * iblExposureFactor * lightingData.diffuseAmbientOcclusion);
+            lightingData.diffuseLighting += (iblDiffuse * exposure * lightingData.diffuseAmbientOcclusion);
         }
         }
 
 
         if(useSpecularIbl)
         if(useSpecularIbl)
@@ -116,7 +116,7 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
                 iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
                 iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
             }
             }
 
 
-            lightingData.specularLighting += (iblSpecular * iblExposureFactor);
+            lightingData.specularLighting += (iblSpecular * exposure);
         }
         }
     }
     }
 }
 }

+ 1 - 0
Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Skin/SkinObjectSrg.azsli

@@ -46,6 +46,7 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject
         float m_padding;
         float m_padding;
         bool m_useReflectionProbe;
         bool m_useReflectionProbe;
         bool m_useParallaxCorrection;
         bool m_useParallaxCorrection;
+        float m_exposure;
     };
     };
 
 
     ReflectionProbeData m_reflectionProbeData;
     ReflectionProbeData m_reflectionProbeData;

+ 1 - 1
Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderInner.azsl

@@ -81,7 +81,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
     }
     }
 
 
     // apply exposure setting
     // apply exposure setting
-    specular *= pow(2.0, SceneSrg::m_iblExposure);
+    specular *= pow(2.0, ObjectSrg::m_exposure);
 
 
     PSOutput OUT;
     PSOutput OUT;
     OUT.m_color = float4(specular, 1.0f);
     OUT.m_color = float4(specular, 1.0f);

+ 1 - 0
Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderObjectSrg.azsli

@@ -17,6 +17,7 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject
     float3 m_outerObbHalfLengths;
     float3 m_outerObbHalfLengths;
     float3 m_innerObbHalfLengths;
     float3 m_innerObbHalfLengths;
     bool m_useParallaxCorrection;
     bool m_useParallaxCorrection;
+    float m_exposure;
     TextureCube m_reflectionCubeMap;
     TextureCube m_reflectionCubeMap;
 
 
     float4x4 GetWorldMatrix()
     float4x4 GetWorldMatrix()

+ 1 - 1
Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionProbeRenderOuter.azsl

@@ -104,7 +104,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
     blendWeight /= max(1.0f, blendWeightAllProbes);
     blendWeight /= max(1.0f, blendWeightAllProbes);
 
 
     // apply exposure setting
     // apply exposure setting
-    specular *= pow(2.0, SceneSrg::m_iblExposure);
+    specular *= pow(2.0, ObjectSrg::m_exposure);
 
 
     // apply blend weight for additive blending
     // apply blend weight for additive blending
     specular *= blendWeight;
     specular *= blendWeight;

+ 2 - 0
Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h

@@ -39,6 +39,8 @@ namespace AZ
             bool IsCubeMapReferenced(const AZStd::string& relativePath) override;
             bool IsCubeMapReferenced(const AZStd::string& relativePath) override;
             bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const override { return (probe.get() != nullptr); }
             bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const override { return (probe.get() != nullptr); }
             void ShowProbeVisualization(const ReflectionProbeHandle& probe, bool showVisualization) override;
             void ShowProbeVisualization(const ReflectionProbeHandle& probe, bool showVisualization) override;
+            void SetRenderExposure(const ReflectionProbeHandle& probe, float renderExposure) override;
+            void SetBakeExposure(const ReflectionProbeHandle& probe, float bakeExposure) override;
 
 
             // FeatureProcessor overrides
             // FeatureProcessor overrides
             void Activate() override;
             void Activate() override;

+ 2 - 0
Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h

@@ -50,6 +50,8 @@ namespace AZ
             virtual bool IsCubeMapReferenced(const AZStd::string& relativePath) = 0;
             virtual bool IsCubeMapReferenced(const AZStd::string& relativePath) = 0;
             virtual bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const = 0;
             virtual bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const = 0;
             virtual void ShowProbeVisualization(const ReflectionProbeHandle& probe, bool showVisualization) = 0;
             virtual void ShowProbeVisualization(const ReflectionProbeHandle& probe, bool showVisualization) = 0;
+            virtual void SetRenderExposure(const ReflectionProbeHandle& probe, float renderExposure) = 0;
+            virtual void SetBakeExposure(const ReflectionProbeHandle& probe, float bakeExposure) = 0;
         };
         };
     } // namespace Render
     } // namespace Render
 } // namespace AZ
 } // namespace AZ

+ 4 - 0
Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp

@@ -1178,6 +1178,9 @@ namespace AZ
                 AZ::RHI::ShaderInputConstantIndex useParallaxCorrectionConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useParallaxCorrection"));
                 AZ::RHI::ShaderInputConstantIndex useParallaxCorrectionConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_useParallaxCorrection"));
                 AZ_Error("MeshDataInstance", useParallaxCorrectionConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
                 AZ_Error("MeshDataInstance", useParallaxCorrectionConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
 
 
+                AZ::RHI::ShaderInputConstantIndex exposureConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_exposure"));
+                AZ_Error("MeshDataInstance", exposureConstantIndex.IsValid(), "Failed to find ReflectionProbe constant index");
+
                 // retrieve probe cubemap index
                 // retrieve probe cubemap index
                 Name reflectionCubeMapImageName = Name("m_reflectionProbeCubeMap");
                 Name reflectionCubeMapImageName = Name("m_reflectionProbeCubeMap");
                 RHI::ShaderInputImageIndex reflectionCubeMapImageIndex = m_shaderResourceGroup->FindShaderInputImageIndex(reflectionCubeMapImageName);
                 RHI::ShaderInputImageIndex reflectionCubeMapImageIndex = m_shaderResourceGroup->FindShaderInputImageIndex(reflectionCubeMapImageName);
@@ -1198,6 +1201,7 @@ namespace AZ
                     m_shaderResourceGroup->SetConstant(innerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetInnerObbWs().GetHalfLengths());
                     m_shaderResourceGroup->SetConstant(innerObbHalfLengthsConstantIndex, reflectionProbes[0]->GetInnerObbWs().GetHalfLengths());
                     m_shaderResourceGroup->SetConstant(useReflectionProbeConstantIndex, true);
                     m_shaderResourceGroup->SetConstant(useReflectionProbeConstantIndex, true);
                     m_shaderResourceGroup->SetConstant(useParallaxCorrectionConstantIndex, reflectionProbes[0]->GetUseParallaxCorrection());
                     m_shaderResourceGroup->SetConstant(useParallaxCorrectionConstantIndex, reflectionProbes[0]->GetUseParallaxCorrection());
+                    m_shaderResourceGroup->SetConstant(exposureConstantIndex, reflectionProbes[0]->GetRenderExposure());
 
 
                     m_shaderResourceGroup->SetImage(reflectionCubeMapImageIndex, reflectionProbes[0]->GetCubeMapImage());
                     m_shaderResourceGroup->SetImage(reflectionCubeMapImageIndex, reflectionProbes[0]->GetCubeMapImage());
                 }
                 }

+ 15 - 2
Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp

@@ -127,8 +127,8 @@ namespace AZ
                 }
                 }
                 else
                 else
                 {
                 {
-                    // set exposure to 0.0 while baking the cubemap
-                    sceneSrg->SetConstant(m_iblExposureConstantIndex, 0.0f);
+                    // set exposure to the user specified value while baking the cubemap
+                    sceneSrg->SetConstant(m_iblExposureConstantIndex, m_bakeExposure);
                 }
                 }
             }
             }
 
 
@@ -162,6 +162,7 @@ namespace AZ
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths());
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths());
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths());
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths());
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection);
                 m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection);
+                m_renderOuterSrg->SetConstant(m_reflectionRenderData->m_exposureConstantIndex, m_renderExposure);
                 m_renderOuterSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage);
                 m_renderOuterSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage);
                 m_renderOuterSrg->Compile();
                 m_renderOuterSrg->Compile();
 
 
@@ -172,6 +173,7 @@ namespace AZ
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths());
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerObbHalfLengthsRenderConstantIndex, m_outerObbWs.GetHalfLengths());
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths());
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_innerObbHalfLengthsRenderConstantIndex, m_innerObbWs.GetHalfLengths());
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection);
                 m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_useParallaxCorrectionRenderConstantIndex, m_useParallaxCorrection);
+                m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_exposureConstantIndex, m_renderExposure);
                 m_renderInnerSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage);
                 m_renderInnerSrg->SetImage(m_reflectionRenderData->m_reflectionCubeMapRenderImageIndex, m_cubeMapImage);
                 m_renderInnerSrg->Compile();
                 m_renderInnerSrg->Compile();
 
 
@@ -326,6 +328,17 @@ namespace AZ
             m_meshFeatureProcessor->SetVisible(m_visualizationMeshHandle, showVisualization);
             m_meshFeatureProcessor->SetVisible(m_visualizationMeshHandle, showVisualization);
         }
         }
 
 
+        void ReflectionProbe::SetRenderExposure(float renderExposure)
+        {
+            m_renderExposure = renderExposure;
+            m_updateSrg = true;
+        }
+
+        void ReflectionProbe::SetBakeExposure(float bakeExposure)
+        {
+            m_bakeExposure = bakeExposure;
+        }
+
         const RHI::DrawPacket* ReflectionProbe::BuildDrawPacket(
         const RHI::DrawPacket* ReflectionProbe::BuildDrawPacket(
             const Data::Instance<RPI::ShaderResourceGroup>& srg,
             const Data::Instance<RPI::ShaderResourceGroup>& srg,
             const RPI::Ptr<RPI::PipelineStateForDraw>& pipelineState,
             const RPI::Ptr<RPI::PipelineStateForDraw>& pipelineState,

+ 11 - 0
Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h

@@ -61,6 +61,7 @@ namespace AZ
             RHI::ShaderInputNameIndex m_outerObbHalfLengthsRenderConstantIndex = "m_outerObbHalfLengths";
             RHI::ShaderInputNameIndex m_outerObbHalfLengthsRenderConstantIndex = "m_outerObbHalfLengths";
             RHI::ShaderInputNameIndex m_innerObbHalfLengthsRenderConstantIndex = "m_innerObbHalfLengths";
             RHI::ShaderInputNameIndex m_innerObbHalfLengthsRenderConstantIndex = "m_innerObbHalfLengths";
             RHI::ShaderInputNameIndex m_useParallaxCorrectionRenderConstantIndex = "m_useParallaxCorrection";
             RHI::ShaderInputNameIndex m_useParallaxCorrectionRenderConstantIndex = "m_useParallaxCorrection";
+            RHI::ShaderInputNameIndex m_exposureConstantIndex = "m_exposure";
             RHI::ShaderInputNameIndex m_reflectionCubeMapRenderImageIndex = "m_reflectionCubeMap";
             RHI::ShaderInputNameIndex m_reflectionCubeMapRenderImageIndex = "m_reflectionCubeMap";
         };
         };
 
 
@@ -106,6 +107,14 @@ namespace AZ
             // enables or disables rendering of the visualization sphere
             // enables or disables rendering of the visualization sphere
             void ShowVisualization(bool showVisualization);
             void ShowVisualization(bool showVisualization);
 
 
+            // the exposure to use when rendering meshes with this probe's cubemap
+            void SetRenderExposure(float renderExposure);
+            float GetRenderExposure() const { return m_renderExposure; }
+
+            // the exposure to use when baking the probe cubemap
+            void SetBakeExposure(float bakeExposure);
+            float GetBakeExposure() const { return m_bakeExposure; }
+
         private:
         private:
 
 
             AZ_DISABLE_COPY_MOVE(ReflectionProbe);
             AZ_DISABLE_COPY_MOVE(ReflectionProbe);
@@ -157,6 +166,8 @@ namespace AZ
             RHI::ConstPtr<RHI::DrawPacket> m_blendWeightDrawPacket;
             RHI::ConstPtr<RHI::DrawPacket> m_blendWeightDrawPacket;
             RHI::ConstPtr<RHI::DrawPacket> m_renderOuterDrawPacket;
             RHI::ConstPtr<RHI::DrawPacket> m_renderOuterDrawPacket;
             RHI::ConstPtr<RHI::DrawPacket> m_renderInnerDrawPacket;
             RHI::ConstPtr<RHI::DrawPacket> m_renderInnerDrawPacket;
+            float m_renderExposure = 0.0f;
+            float m_bakeExposure = 0.0f;
             bool m_updateSrg = false;
             bool m_updateSrg = false;
 
 
             const RHI::DrawItemSortKey InvalidSortKey = static_cast<RHI::DrawItemSortKey>(-1);
             const RHI::DrawItemSortKey InvalidSortKey = static_cast<RHI::DrawItemSortKey>(-1);

+ 12 - 0
Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp

@@ -283,6 +283,18 @@ namespace AZ
             probe->ShowVisualization(showVisualization);
             probe->ShowVisualization(showVisualization);
         }
         }
 
 
+        void ReflectionProbeFeatureProcessor::SetRenderExposure(const ReflectionProbeHandle& probe, float renderExposure)
+        {
+            AZ_Assert(probe.get(), "SetRenderExposure called with an invalid handle");
+            probe->SetRenderExposure(renderExposure);
+        }
+
+        void ReflectionProbeFeatureProcessor::SetBakeExposure(const ReflectionProbeHandle& probe, float bakeExposure)
+        {
+            AZ_Assert(probe.get(), "SetBakeExposure called with an invalid handle");
+            probe->SetBakeExposure(bakeExposure);
+        }
+
         void ReflectionProbeFeatureProcessor::FindReflectionProbes(const Vector3& position, ReflectionProbeVector& reflectionProbes)
         void ReflectionProbeFeatureProcessor::FindReflectionProbes(const Vector3& position, ReflectionProbeVector& reflectionProbes)
         {
         {
             reflectionProbes.clear();
             reflectionProbes.clear();

+ 20 - 0
Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.cpp

@@ -40,6 +40,7 @@ namespace AZ
                     ->Field("bakedCubeMapQualityLevel", &EditorReflectionProbeComponent::m_bakedCubeMapQualityLevel)
                     ->Field("bakedCubeMapQualityLevel", &EditorReflectionProbeComponent::m_bakedCubeMapQualityLevel)
                     ->Field("bakedCubeMapRelativePath", &EditorReflectionProbeComponent::m_bakedCubeMapRelativePath)
                     ->Field("bakedCubeMapRelativePath", &EditorReflectionProbeComponent::m_bakedCubeMapRelativePath)
                     ->Field("authoredCubeMapAsset", &EditorReflectionProbeComponent::m_authoredCubeMapAsset)
                     ->Field("authoredCubeMapAsset", &EditorReflectionProbeComponent::m_authoredCubeMapAsset)
+                    ->Field("bakeExposure", &EditorReflectionProbeComponent::m_bakeExposure)
                 ;
                 ;
 
 
                 if (AZ::EditContext* editContext = serializeContext->GetEditContext())
                 if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@@ -62,6 +63,13 @@ namespace AZ
                                 ->Attribute(AZ::Edit::Attributes::ButtonText, "Bake Reflection Probe")
                                 ->Attribute(AZ::Edit::Attributes::ButtonText, "Bake Reflection Probe")
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorReflectionProbeComponent::BakeReflectionProbe)
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorReflectionProbeComponent::BakeReflectionProbe)
                                 ->Attribute(AZ::Edit::Attributes::Visibility, &EditorReflectionProbeComponent::GetBakedCubemapVisibilitySetting)
                                 ->Attribute(AZ::Edit::Attributes::Visibility, &EditorReflectionProbeComponent::GetBakedCubemapVisibilitySetting)
+                            ->DataElement(AZ::Edit::UIHandlers::Slider, &EditorReflectionProbeComponent::m_bakeExposure, "Bake Exposure", "Exposure to use when baking the cubemap")
+                                ->Attribute(AZ::Edit::Attributes::SoftMin, -5.0f)
+                                ->Attribute(AZ::Edit::Attributes::SoftMax, 5.0f)
+                                ->Attribute(AZ::Edit::Attributes::Min, -20.0f)
+                                ->Attribute(AZ::Edit::Attributes::Max, 20.0f)
+                                ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorReflectionProbeComponent::OnBakeExposureChanged)
+                                ->Attribute(AZ::Edit::Attributes::Visibility, &EditorReflectionProbeComponent::GetBakedCubemapVisibilitySetting)
                         ->ClassElement(AZ::Edit::ClassElements::Group, "Cubemap")
                         ->ClassElement(AZ::Edit::ClassElements::Group, "Cubemap")
                             ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
                             ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
                             ->DataElement(AZ::Edit::UIHandlers::Default, &EditorReflectionProbeComponent::m_useBakedCubemap, "Use Baked Cubemap", "Selects between a cubemap that captures the environment at location in the scene or a preauthored cubemap")
                             ->DataElement(AZ::Edit::UIHandlers::Default, &EditorReflectionProbeComponent::m_useBakedCubemap, "Use Baked Cubemap", "Selects between a cubemap that captures the environment at location in the scene or a preauthored cubemap")
@@ -111,6 +119,11 @@ namespace AZ
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
                             ->DataElement(AZ::Edit::UIHandlers::CheckBox, &ReflectionProbeComponentConfig::m_showVisualization, "Show Visualization", "Show the reflection probe visualization sphere")
                             ->DataElement(AZ::Edit::UIHandlers::CheckBox, &ReflectionProbeComponentConfig::m_showVisualization, "Show Visualization", "Show the reflection probe visualization sphere")
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
                                 ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+                            ->DataElement(AZ::Edit::UIHandlers::Slider, &ReflectionProbeComponentConfig::m_renderExposure, "Exposure", "Exposure to use when rendering meshes with the cubemap")
+                                ->Attribute(AZ::Edit::Attributes::SoftMin, -5.0f)
+                                ->Attribute(AZ::Edit::Attributes::SoftMax, 5.0f)
+                                ->Attribute(AZ::Edit::Attributes::Min, -20.0f)
+                                ->Attribute(AZ::Edit::Attributes::Max, 20.0f)
                         ;
                         ;
                 }
                 }
             }
             }
@@ -275,6 +288,13 @@ namespace AZ
             return AZ::Edit::PropertyRefreshLevels::None;
             return AZ::Edit::PropertyRefreshLevels::None;
         }
         }
 
 
+        AZ::u32 EditorReflectionProbeComponent::OnBakeExposureChanged()
+        {
+            m_controller.SetBakeExposure(m_bakeExposure);
+
+            return AZ::Edit::PropertyRefreshLevels::None;
+        }
+
         AZ::u32 EditorReflectionProbeComponent::GetBakedCubemapVisibilitySetting()
         AZ::u32 EditorReflectionProbeComponent::GetBakedCubemapVisibilitySetting()
         {
         {
             // controls specific to baked cubemaps call this to determine their visibility
             // controls specific to baked cubemaps call this to determine their visibility

+ 2 - 0
Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/EditorReflectionProbeComponent.h

@@ -55,6 +55,7 @@ namespace AZ
             // change notifications
             // change notifications
             AZ::u32 OnUseBakedCubemapChanged();
             AZ::u32 OnUseBakedCubemapChanged();
             AZ::u32 OnAuthoredCubemapChanged();
             AZ::u32 OnAuthoredCubemapChanged();
+            AZ::u32 OnBakeExposureChanged();
 
 
             // retrieves visibility for baked or authored cubemap controls
             // retrieves visibility for baked or authored cubemap controls
             AZ::u32 GetBakedCubemapVisibilitySetting();
             AZ::u32 GetBakedCubemapVisibilitySetting();
@@ -77,6 +78,7 @@ namespace AZ
             AZStd::string m_bakedCubeMapRelativePath;
             AZStd::string m_bakedCubeMapRelativePath;
             Data::Asset<RPI::StreamingImageAsset> m_bakedCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_bakedCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_authoredCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_authoredCubeMapAsset;
+            float m_bakeExposure = 0.0f;
 
 
             // flag indicating if a cubemap bake is currently in progress
             // flag indicating if a cubemap bake is currently in progress
             AZStd::atomic_bool m_bakeInProgress = false;
             AZStd::atomic_bool m_bakeInProgress = false;

+ 17 - 2
Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp

@@ -35,7 +35,7 @@ namespace AZ
             if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
             if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
             {
             {
                 serializeContext->Class<ReflectionProbeComponentConfig>()
                 serializeContext->Class<ReflectionProbeComponentConfig>()
-                    ->Version(0)
+                    ->Version(1)
                     ->Field("OuterHeight", &ReflectionProbeComponentConfig::m_outerHeight)
                     ->Field("OuterHeight", &ReflectionProbeComponentConfig::m_outerHeight)
                     ->Field("OuterLength", &ReflectionProbeComponentConfig::m_outerLength)
                     ->Field("OuterLength", &ReflectionProbeComponentConfig::m_outerLength)
                     ->Field("OuterWidth", &ReflectionProbeComponentConfig::m_outerWidth)
                     ->Field("OuterWidth", &ReflectionProbeComponentConfig::m_outerWidth)
@@ -49,7 +49,9 @@ namespace AZ
                     ->Field("AuthoredCubeMapAsset", &ReflectionProbeComponentConfig::m_authoredCubeMapAsset)
                     ->Field("AuthoredCubeMapAsset", &ReflectionProbeComponentConfig::m_authoredCubeMapAsset)
                     ->Field("EntityId", &ReflectionProbeComponentConfig::m_entityId)
                     ->Field("EntityId", &ReflectionProbeComponentConfig::m_entityId)
                     ->Field("UseParallaxCorrection", &ReflectionProbeComponentConfig::m_useParallaxCorrection)
                     ->Field("UseParallaxCorrection", &ReflectionProbeComponentConfig::m_useParallaxCorrection)
-                    ->Field("ShowVisualization", &ReflectionProbeComponentConfig::m_showVisualization);
+                    ->Field("ShowVisualization", &ReflectionProbeComponentConfig::m_showVisualization)
+                    ->Field("RenderExposure", &ReflectionProbeComponentConfig::m_renderExposure)
+                    ->Field("BakeExposure", &ReflectionProbeComponentConfig::m_bakeExposure);
             }
             }
         }
         }
 
 
@@ -157,6 +159,9 @@ namespace AZ
                 cubeMapAsset.QueueLoad();
                 cubeMapAsset.QueueLoad();
                 Data::AssetBus::MultiHandler::BusConnect(cubeMapAsset.GetId());
                 Data::AssetBus::MultiHandler::BusConnect(cubeMapAsset.GetId());
             }
             }
+
+            // set cubemap render exposure
+            m_featureProcessor->SetRenderExposure(m_handle, m_configuration.m_renderExposure);
         }
         }
 
 
         void ReflectionProbeComponentController::Deactivate()
         void ReflectionProbeComponentController::Deactivate()
@@ -284,6 +289,16 @@ namespace AZ
             m_configuration.m_innerHeight = AZStd::min(m_configuration.m_innerHeight, m_configuration.m_outerHeight);
             m_configuration.m_innerHeight = AZStd::min(m_configuration.m_innerHeight, m_configuration.m_outerHeight);
         }
         }
 
 
+        void ReflectionProbeComponentController::SetBakeExposure(float bakeExposure)
+        {
+            if (!m_featureProcessor)
+            {
+                return;
+            }
+
+            m_featureProcessor->SetBakeExposure(m_handle, bakeExposure);
+        }
+
         void ReflectionProbeComponentController::BakeReflectionProbe(BuildCubeMapCallback callback, const AZStd::string& relativePath)
         void ReflectionProbeComponentController::BakeReflectionProbe(BuildCubeMapCallback callback, const AZStd::string& relativePath)
         {
         {
             if (!m_featureProcessor)
             if (!m_featureProcessor)

+ 6 - 0
Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.h

@@ -68,6 +68,9 @@ namespace AZ
             Data::Asset<RPI::StreamingImageAsset> m_bakedCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_bakedCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_authoredCubeMapAsset;
             Data::Asset<RPI::StreamingImageAsset> m_authoredCubeMapAsset;
             AZ::u64 m_entityId{ EntityId::InvalidEntityId };
             AZ::u64 m_entityId{ EntityId::InvalidEntityId };
+
+            float m_renderExposure = 0.0f;
+            float m_bakeExposure = 0.0f;
         };
         };
 
 
         class ReflectionProbeComponentController final
         class ReflectionProbeComponentController final
@@ -99,6 +102,9 @@ namespace AZ
             // returns the outer extent Aabb for this reflection
             // returns the outer extent Aabb for this reflection
             AZ::Aabb GetAabb() const;
             AZ::Aabb GetAabb() const;
 
 
+            // set the exposure to use when baking the cubemap
+            void SetBakeExposure(float bakeExposure);
+
             // initiate the reflection probe bake, invokes callback when complete
             // initiate the reflection probe bake, invokes callback when complete
             void BakeReflectionProbe(BuildCubeMapCallback callback, const AZStd::string& relativePath);
             void BakeReflectionProbe(BuildCubeMapCallback callback, const AZStd::string& relativePath);