AreaLightExampleComponent.h 9.3 KB

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