ShadowExampleComponent.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <CommonSampleComponentBase.h>
  10. #include <Atom/Feature/CoreLights/DirectionalLightFeatureProcessorInterface.h>
  11. #include <Atom/Feature/CoreLights/ShadowConstants.h>
  12. #include <Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h>
  13. #include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
  14. #include <AzCore/Component/TickBus.h>
  15. #include <Atom/Utils/ImGuiMaterialDetails.h>
  16. #include <Utils/ImGuiSidebar.h>
  17. #include <Utils/Utils.h>
  18. namespace AtomSampleViewer
  19. {
  20. /*
  21. * This component creates a simple scene to test shadows.
  22. * At the 2nd step, we implement cascaded shadowmap for a directional light.
  23. * At the 3rd step, we made the number of cascades configurable.
  24. * At the 4th step, we implement softening shadow edge by PCF (Percentage Closer Filtering).
  25. * At the 5th step, we implement softening shadow edge by ESM (Exponential Shadow Maps).
  26. * At the 6th step, we implement disk light shadows.
  27. */
  28. class ShadowExampleComponent final
  29. : public CommonSampleComponentBase
  30. , public AZ::TickBus::Handler
  31. {
  32. public:
  33. AZ_COMPONENT(ShadowExampleComponent, "4B0F5D1F-71ED-41BB-9302-FE42C7F46E3C", CommonSampleComponentBase);
  34. static void Reflect(AZ::ReflectContext* context);
  35. ShadowExampleComponent();
  36. ~ShadowExampleComponent() override = default;
  37. void Activate() override;
  38. void Deactivate() override;
  39. private:
  40. using DirectionalLightHandle = AZ::Render::DirectionalLightFeatureProcessorInterface::LightHandle;
  41. using DiskLightHandle = AZ::Render::DiskLightFeatureProcessorInterface::LightHandle;
  42. using PointLightHandle = AZ::Render::PointLightFeatureProcessorInterface::LightHandle;
  43. // AZ::TickBus::Handler overrides...
  44. void OnTick(float deltaTime, AZ::ScriptTimePoint time);
  45. // CommonSampleComponentBase overrides...
  46. void OnAllAssetsReadyActivate() override;
  47. void SaveCameraConfiguration();
  48. void RestoreCameraConfiguration();
  49. void UseArcBallCameraController();
  50. void SetInitialArcBallControllerParams();
  51. void RemoveController();
  52. void CreateMeshes();
  53. void CreateDirectionalLight();
  54. void CreateDiskLights();
  55. void CreatePointLights();
  56. void DestroyDiskLights();
  57. void DestroyPointLights();
  58. void SetInitialShadowParams();
  59. void SetupDebugFlags();
  60. void DrawSidebar();
  61. void DrawSidebarDirectionalLight();
  62. // Return true if settings have changed
  63. bool DrawSidebarPositionalLights();
  64. void DrawSidebarCamera();
  65. void ApplyDiskLightSettings();
  66. void ApplyPointLightSettings();
  67. void UpdateDirectionalLight();
  68. AZ::Transform GetTransformForLight(const uint32_t index) const;
  69. float GetAttenuationForLight(const uint32_t index) const;
  70. AZ::Render::PhotometricColor<AZ::Render::PhotometricUnit::Candela> GetRgbIntensityForLight(const uint32_t index) const;
  71. AZStd::pair<float, float> GetConeAnglesForLight(const uint32_t index) const;
  72. static constexpr uint32_t PositionalLightCount = 3;
  73. static constexpr float ConeAngleInnerRatio = 0.9f;
  74. static constexpr float CutoffIntensity = 0.1f;
  75. static constexpr float FarClipDistance = 20.f;
  76. static const AZ::Color DirectionalLightColor;
  77. static AZ::Color s_positionalLightColors[PositionalLightCount];
  78. // Mesh Handles
  79. using MeshHandle = AZ::Render::MeshFeatureProcessorInterface::MeshHandle;
  80. MeshHandle m_floorMeshHandle;
  81. MeshHandle m_bunnyMeshHandle;
  82. // lights
  83. AZ::Render::DirectionalLightFeatureProcessorInterface* m_directionalLightFeatureProcessor = nullptr;
  84. AZ::Render::DiskLightFeatureProcessorInterface* m_diskLightFeatureProcessor = nullptr;
  85. AZ::Render::PointLightFeatureProcessorInterface* m_pointLightFeatureProcessor = nullptr;
  86. DirectionalLightHandle m_directionalLightHandle;
  87. DiskLightHandle m_diskLightHandles[PositionalLightCount];
  88. PointLightHandle m_pointLightHandles[PositionalLightCount];
  89. // asset
  90. AZ::Data::Asset<AZ::RPI::ModelAsset> m_bunnyModelAsset;
  91. AZ::Data::Asset<AZ::RPI::ModelAsset> m_floorModelAsset;
  92. AZ::Data::Asset<AZ::RPI::MaterialAsset> m_materialAsset;
  93. AZ::Data::Instance<AZ::RPI::Material> m_materialInstance;
  94. // ModelReadyHandles
  95. bool m_bunnyMeshIsReady = false;
  96. bool m_floorMeshIsReady = false;
  97. // GUI
  98. float m_elapsedTime = 0.f;
  99. int m_positionalLightTypeActive = 0;
  100. int m_controlTargetPositionalLightIndex = 0;
  101. float m_directionalLightRotationAngle = 0.f; // in radian
  102. float m_positionalLightRotationAngle = 0.f; // in radian
  103. bool m_isDirectionalLightAutoRotate = true;
  104. bool m_isPositionalLightAutoRotate = true;
  105. float m_directionalLightHeight = 10.f;
  106. float m_positionalLightHeights[PositionalLightCount] = {5.f, 6.f, 7.f};
  107. float m_directionalLightIntensity = 5.f;
  108. float m_lightIntensities[PositionalLightCount] = {500.f, 900.f, 500.f};
  109. float m_outerConeAngles[PositionalLightCount] = {17.5f, 20.f, 22.5f};
  110. float m_cameraFovY = AZ::Constants::QuarterPi;
  111. // Shadowmap
  112. static const AZ::Render::ShadowmapSize s_shadowmapImageSizes[];
  113. static const char* s_shadowmapImageSizeLabels[];
  114. int m_directionalLightImageSizeIndex = 2; // image size is 1024.
  115. int m_positionalLightImageSizeIndices[PositionalLightCount] = {2, 2, 2}; // image size is 1024.
  116. int m_cascadeCount = 2;
  117. bool m_shadowmapFrustumSplitIsAutomatic = true;
  118. float m_ratioLogarithmUniform = 0.5f;
  119. float m_cascadeFarDepth[AZ::Render::Shadow::MaxNumberOfCascades] =
  120. {
  121. FarClipDistance * 1 / 4,
  122. FarClipDistance * 2 / 4,
  123. FarClipDistance * 3 / 4,
  124. FarClipDistance * 4 / 4
  125. };
  126. bool m_shadowEnabled = true;
  127. bool m_useFullscreenBlur = false;
  128. bool m_isCascadeCorrectionEnabled = false;
  129. bool m_isDebugColoringEnabled = false;
  130. bool m_isDebugBoundingBoxEnabled = false;
  131. bool m_positionalLightShadowEnabled[PositionalLightCount] = {true, true, true};
  132. bool m_pointLightShadowEnabled[PositionalLightCount] = {true, true, true};
  133. // Edge-softening of shadows
  134. static const AZ::Render::ShadowFilterMethod s_shadowFilterMethods[];
  135. static const char* s_shadowFilterMethodLabels[];
  136. int m_shadowFilterMethodIndexDirectional = 0; // filter method is None.
  137. int m_shadowFilterMethodIndicesPositional[PositionalLightCount] = { 0, 0, 0 }; // filter method is None.
  138. int m_filteringSampleCountDirectional = 32;
  139. int m_filteringSampleCountsPositional[PositionalLightCount] = { 32, 32, 32 };
  140. ImGuiSidebar m_imguiSidebar;
  141. AZ::Render::ImGuiMaterialDetails m_imguiMaterialDetails;
  142. // original camera configuration
  143. float m_originalFarClipDistance = 0.f;
  144. float m_originalCameraFovRadians = 0.f;
  145. Utils::DefaultIBL m_defaultIbl;
  146. };
  147. } // namespace AtomSampleViewer