AreaLightExampleComponent.h 9.0 KB

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