AreaLightExampleComponent.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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 <AzCore/Component/TickBus.h>
  11. #include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
  12. #include <Atom/Feature/Mesh/MeshFeatureProcessorInterface.h>
  13. #include <Atom/Feature/CoreLights/CapsuleLightFeatureProcessorInterface.h>
  14. #include <Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h>
  15. #include <Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h>
  16. #include <Atom/Feature/CoreLights/PolygonLightFeatureProcessorInterface.h>
  17. #include <Atom/Feature/CoreLights/QuadLightFeatureProcessorInterface.h>
  18. #include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
  19. #include <Utils/ImGuiAssetBrowser.h>
  20. #include <Utils/ImGuiSidebar.h>
  21. namespace AtomSampleViewer
  22. {
  23. // This component renders a model with pbr material using checkerboard render pipeline.
  24. class AreaLightExampleComponent final
  25. : public CommonSampleComponentBase
  26. , public AZ::TickBus::Handler
  27. {
  28. public:
  29. AZ_COMPONENT(AreaLightExampleComponent, "{1CFEDA71-9459-44CE-A88B-F0CAE9192819}", CommonSampleComponentBase);
  30. static void Reflect(AZ::ReflectContext* context);
  31. AreaLightExampleComponent();
  32. ~AreaLightExampleComponent() override = default;
  33. // AZ::Component overrides...
  34. void Activate() override;
  35. void Deactivate() override;
  36. private:
  37. static const uint32_t MaxVariants = 10;
  38. using MeshHandleDescriptor = AZ::Render::MeshHandleDescriptor;
  39. using MeshHandle = AZ::Render::MeshFeatureProcessorInterface::MeshHandle;
  40. using PointLightHandle = AZ::Render::PointLightFeatureProcessorInterface::LightHandle;
  41. using DiskLightHandle = AZ::Render::DiskLightFeatureProcessorInterface::LightHandle;
  42. using CapsuleLightHandle = AZ::Render::CapsuleLightFeatureProcessorInterface::LightHandle;
  43. using QuadLightHandle = AZ::Render::QuadLightFeatureProcessorInterface::LightHandle;
  44. using PolygonLightHandle = AZ::Render::PolygonLightFeatureProcessorInterface::LightHandle;
  45. using MaterialInstance = AZ::Data::Instance<AZ::RPI::Material>;
  46. enum LightType
  47. {
  48. Point,
  49. Disk,
  50. Capsule,
  51. Quad,
  52. Polygon,
  53. };
  54. union LightHandle
  55. {
  56. LightHandle() { m_point.Reset(); };
  57. PointLightHandle m_point;
  58. DiskLightHandle m_disk;
  59. CapsuleLightHandle m_capsule;
  60. QuadLightHandle m_quad;
  61. PolygonLightHandle m_polygon;
  62. };
  63. // Various data the user can alter in ImGui stored in ImGui friendly types.
  64. struct Configuration
  65. {
  66. LightType m_lightType = Point;
  67. AZStd::string m_modelAssetPath = "objects/test/area_light_test_sphere.fbx.azmodel";
  68. uint32_t m_count = 1;
  69. float m_intensity = 30.0f;
  70. float m_color[3] = { 1.0f, 1.0f, 1.0f };
  71. float m_lightDistance = 3.0f;
  72. float m_positionOffset[3] = { 0.0f, 0.0f, 0.0f };
  73. float m_rotations[3] = { 0.0f, 0.0f, 0.0f };
  74. bool m_varyRadius = false;
  75. float m_radius[2] = { 0.1f, 1.0f };
  76. bool m_varyRoughness = false;
  77. float m_roughness[2] = { 1.0f, 0.0f };
  78. bool m_varyMetallic = false;
  79. float m_metallic[2] = { 0.0f, 1.0f };
  80. float m_capsuleHeight = 2.0f;
  81. float m_quadSize[2] = { 1.0f, 1.0f };
  82. int32_t m_polyStarCount = 5;
  83. float m_polyMinMaxRadius[2] = { 0.25f, 0.5f };
  84. bool m_emitsBothDirections = false;
  85. bool m_validation = false;
  86. bool m_fastApproximation = false;
  87. bool m_multiScattering = false;
  88. //! Creates a quaterion based on m_rotations
  89. AZ::Quaternion GetRotationQuaternion();
  90. //! Creates a Matrix3x3 based on m_rotations
  91. AZ::Matrix3x3 GetRotationMatrix();
  92. bool GetVaryRadius() { return m_varyRadius && m_count > 1; }
  93. bool GetVaryRoughness() { return m_varyRoughness && m_count > 1; }
  94. bool GetVaryMetallic() { return m_varyMetallic && m_count > 1; }
  95. };
  96. AZ_DISABLE_COPY_MOVE(AreaLightExampleComponent);
  97. // AZ::TickBus::Handler overrides...
  98. void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
  99. //! Creates material instances for the given material asset.
  100. void InitializeMaterials(AZ::Data::Asset< AZ::RPI::MaterialAsset> materialAsset);
  101. //! Updates the number of model and asset shown.
  102. void UpdateModels(AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset);
  103. //! Updates material instances based on user config (roughness, metalness etc)
  104. void UpdateMaterials();
  105. //! Updates the lights based on user config (light type, intensity etc)
  106. void UpdateLights();
  107. //! Handles generic properties that apply to all lights.
  108. template <typename FeatureProcessorType, typename HandleType>
  109. void UpdateLightForType(FeatureProcessorType featureProcessor, HandleType& handle, uint32_t index);
  110. // Specific light configuration...
  111. void UpdatePointLight(PointLightHandle& handle, uint32_t index, AZ::Vector3 position);
  112. void UpdateDiskLight(DiskLightHandle& handle, uint32_t index, AZ::Vector3 position);
  113. void UpdateCapsuleLight(CapsuleLightHandle& handle, uint32_t index, AZ::Vector3 position);
  114. void UpdateQuadLight(QuadLightHandle& handle, uint32_t index, AZ::Vector3 position);
  115. void UpdatePolygonLight(PolygonLightHandle& handle, uint32_t index, AZ::Vector3 position);
  116. //! Gets a 0.0 -> 1.0 value based on index and m_config's m_count.
  117. float GetPositionPercentage(uint32_t index);
  118. //! Gets the model's position based on the index.
  119. AZ::Vector3 GetModelPosition(uint32_t index);
  120. //! Gets the light's position based on the index.
  121. AZ::Vector3 GetLightPosition(uint32_t index);
  122. //! Convience function to either lerp two values or just return the first depending on bool.
  123. template<typename T>
  124. T GetLerpValue(T values[2], uint32_t index, bool doLerp);
  125. //! Releases all the models.
  126. void ReleaseModels();
  127. //! Releases all the lights.
  128. void ReleaseLights();
  129. //! Draws all the ImGui controls.
  130. void DrawUI();
  131. //! Draws the lights themselves using AuxGeom
  132. void DrawAuxGeom();
  133. // Transforms the points based on the rotation and translation settings.
  134. static void TransformVertices(AZStd::vector<AZ::Vector3>& vertices, const AZ::Quaternion& orientation, const AZ::Vector3& translation);
  135. // Utility function to get the nth point out of 'count' points on a unit circle on the z plane. Runs counter-clockwise starting from (1.0, 0.0, 0.0).
  136. static AZ::Vector3 GetCirclePoint(float n, float count);
  137. // Calculates the area of a polygon star.
  138. static float CalculatePolygonArea(const AZStd::vector<AZ::Vector3>& vertices);
  139. // Gets the edge vertices for a polygon star on the z plane.
  140. static AZStd::vector<AZ::Vector3> GetPolygonVertices(uint32_t pointCount, float minMaxRadius[2]);
  141. // Gets triangles for a polygon star on the z plane.
  142. static AZStd::vector<AZ::Vector3> GetPolygonTriangles(uint32_t pointCount, float minMaxRadius[2]);
  143. Configuration m_config;
  144. AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
  145. AZ::RPI::AuxGeomDrawPtr m_auxGeom;
  146. // Feature processors
  147. AZ::Render::MeshFeatureProcessorInterface* m_meshFeatureProcessor = nullptr;
  148. AZ::Render::PointLightFeatureProcessorInterface* m_pointLightFeatureProcessor = nullptr;
  149. AZ::Render::DiskLightFeatureProcessorInterface* m_diskLightFeatureProcessor = nullptr;
  150. AZ::Render::CapsuleLightFeatureProcessorInterface* m_capsuleLightFeatureProcessor = nullptr;
  151. AZ::Render::QuadLightFeatureProcessorInterface* m_quadLightFeatureProcessor = nullptr;
  152. AZ::Render::PolygonLightFeatureProcessorInterface* m_polygonLightFeatureProcessor = nullptr;
  153. AZ::Render::SkyBoxFeatureProcessorInterface* m_skyBoxFeatureProcessor = nullptr;
  154. AZ::RPI::MaterialPropertyIndex m_roughnessPropertyIndex;
  155. AZ::RPI::MaterialPropertyIndex m_metallicPropertyIndex;
  156. AZ::RPI::MaterialPropertyIndex m_multiScatteringEnabledIndex;
  157. AZStd::vector<MaterialInstance> m_materialInstances;
  158. AZStd::vector<MeshHandle> m_meshHandles;
  159. AZStd::vector<LightHandle> m_lightHandles;
  160. AZ::Render::PhotometricValue m_photometricValue;
  161. ImGuiSidebar m_imguiSidebar;
  162. ImGuiAssetBrowser m_materialBrowser;
  163. ImGuiAssetBrowser m_modelBrowser;
  164. ImGuiAssetBrowser::WidgetSettings m_materialBrowserSettings;
  165. ImGuiAssetBrowser::WidgetSettings m_modelBrowserSettings;
  166. bool m_materialsNeedUpdate = true;
  167. };
  168. }