3
0

AreaLightComponentController.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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. #include <CoreLights/AreaLightComponentController.h>
  9. #include <CoreLights/CapsuleLightDelegate.h>
  10. #include <CoreLights/DiskLightDelegate.h>
  11. #include <CoreLights/PolygonLightDelegate.h>
  12. #include <CoreLights/QuadLightDelegate.h>
  13. #include <CoreLights/SimplePointLightDelegate.h>
  14. #include <CoreLights/SimpleSpotLightDelegate.h>
  15. #include <CoreLights/SphereLightDelegate.h>
  16. #include <Atom/Feature/CoreLights/PhotometricValue.h>
  17. #include <AzCore/RTTI/BehaviorContext.h>
  18. #include <AzCore/Serialization/EditContext.h>
  19. #include <AzCore/Serialization/SerializeContext.h>
  20. #include <AtomLyIntegration/CommonFeatures/CoreLights/CoreLightsConstants.h>
  21. #include <LmbrCentral/Shape/ShapeComponentBus.h>
  22. #include <LmbrCentral/Shape/SphereShapeComponentBus.h>
  23. #include <LmbrCentral/Shape/DiskShapeComponentBus.h>
  24. #include <LmbrCentral/Shape/CapsuleShapeComponentBus.h>
  25. #include <LmbrCentral/Shape/PolygonPrismShapeComponentBus.h>
  26. #include <LmbrCentral/Shape/QuadShapeComponentBus.h>
  27. namespace AZ::Render
  28. {
  29. void AreaLightComponentController::Reflect(ReflectContext* context)
  30. {
  31. AreaLightComponentConfig::Reflect(context);
  32. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  33. {
  34. serializeContext->Class<AreaLightComponentController>()
  35. ->Version(1)
  36. ->Field("Configuration", &AreaLightComponentController::m_configuration);
  37. }
  38. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  39. {
  40. behaviorContext->EBus<AreaLightRequestBus>("AreaLightRequestBus")
  41. ->Event("GetAttenuationRadius", &AreaLightRequestBus::Events::GetAttenuationRadius)
  42. ->Event("SetAttenuationRadius", &AreaLightRequestBus::Events::SetAttenuationRadius)
  43. ->Event("SetAttenuationRadiusMode", &AreaLightRequestBus::Events::SetAttenuationRadiusMode)
  44. ->Event("GetColor", &AreaLightRequestBus::Events::GetColor)
  45. ->Event("SetColor", &AreaLightRequestBus::Events::SetColor)
  46. ->Event("GetEmitsLightBothDirections", &AreaLightRequestBus::Events::GetLightEmitsBothDirections)
  47. ->Event("SetEmitsLightBothDirections", &AreaLightRequestBus::Events::SetLightEmitsBothDirections)
  48. ->Event("GetUseFastApproximation", &AreaLightRequestBus::Events::GetUseFastApproximation)
  49. ->Event("SetUseFastApproximation", &AreaLightRequestBus::Events::SetUseFastApproximation)
  50. ->Event("GetIntensity", &AreaLightRequestBus::Events::GetIntensity)
  51. ->Event("SetIntensity", static_cast<void(AreaLightRequestBus::Events::*)(float)>(&AreaLightRequestBus::Events::SetIntensity))
  52. ->Event("SetIntensityAndMode", &AreaLightRequestBus::Events::SetIntensityAndMode)
  53. ->Event("GetIntensityMode", &AreaLightRequestBus::Events::GetIntensityMode)
  54. ->Event("ConvertToIntensityMode", &AreaLightRequestBus::Events::ConvertToIntensityMode)
  55. ->Event("GetEnableShutters", &AreaLightRequestBus::Events::GetEnableShutters)
  56. ->Event("SetEnableShutters", &AreaLightRequestBus::Events::SetEnableShutters)
  57. ->Event("GetInnerShutterAngle", &AreaLightRequestBus::Events::GetInnerShutterAngle)
  58. ->Event("SetInnerShutterAngle", &AreaLightRequestBus::Events::SetInnerShutterAngle)
  59. ->Event("GetOuterShutterAngle", &AreaLightRequestBus::Events::GetOuterShutterAngle)
  60. ->Event("SetOuterShutterAngle", &AreaLightRequestBus::Events::SetOuterShutterAngle)
  61. ->Event("GetEnableShadow", &AreaLightRequestBus::Events::GetEnableShadow)
  62. ->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow)
  63. ->Event("GetShadowBias", &AreaLightRequestBus::Events::GetShadowBias)
  64. ->Event("SetShadowBias", &AreaLightRequestBus::Events::SetShadowBias)
  65. ->Event("GetNormalShadowBias", &AreaLightRequestBus::Events::GetNormalShadowBias)
  66. ->Event("SetNormalShadowBias", &AreaLightRequestBus::Events::SetNormalShadowBias)
  67. ->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize)
  68. ->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize)
  69. ->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod)
  70. ->Event("SetShadowFilterMethod", &AreaLightRequestBus::Events::SetShadowFilterMethod)
  71. ->Event("GetFilteringSampleCount", &AreaLightRequestBus::Events::GetFilteringSampleCount)
  72. ->Event("SetFilteringSampleCount", &AreaLightRequestBus::Events::SetFilteringSampleCount)
  73. ->Event("GetEsmExponent", &AreaLightRequestBus::Events::GetEsmExponent)
  74. ->Event("SetEsmExponent", &AreaLightRequestBus::Events::SetEsmExponent)
  75. ->Event("GetShadowCachingMode", &AreaLightRequestBus::Events::GetShadowCachingMode)
  76. ->Event("SetShadowCachingMode", &AreaLightRequestBus::Events::SetShadowCachingMode)
  77. ->Event("GetAffectsGI", &AreaLightRequestBus::Events::GetAffectsGI)
  78. ->Event("SetAffectsGI", &AreaLightRequestBus::Events::SetAffectsGI)
  79. ->Event("GetAffectsGIFactor", &AreaLightRequestBus::Events::GetAffectsGIFactor)
  80. ->Event("SetAffectsGIFactor", &AreaLightRequestBus::Events::SetAffectsGIFactor)
  81. ->VirtualProperty("AttenuationRadius", "GetAttenuationRadius", "SetAttenuationRadius")
  82. ->VirtualProperty("Color", "GetColor", "SetColor")
  83. ->VirtualProperty("EmitsLightBothDirections", "GetEmitsLightBothDirections", "SetEmitsLightBothDirections")
  84. ->VirtualProperty("UseFastApproximation", "GetUseFastApproximation", "SetUseFastApproximation")
  85. ->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
  86. ->VirtualProperty("ShuttersEnabled", "GetEnableShutters", "SetEnableShutters")
  87. ->VirtualProperty("InnerShutterAngle", "GetInnerShutterAngle", "SetInnerShutterAngle")
  88. ->VirtualProperty("OuterShutterAngle", "GetOuterShutterAngle", "SetOuterShutterAngle")
  89. ->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
  90. ->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
  91. ->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
  92. ->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
  93. ->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
  94. ->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
  95. ->VirtualProperty("EsmExponent", "GetEsmExponent", "SetEsmExponent")
  96. ->VirtualProperty("ShadowCachingMode", "GetShadowCachingMode", "SetShadowCachingMode")
  97. ->VirtualProperty("AffectsGI", "GetAffectsGI", "SetAffectsGI")
  98. ->VirtualProperty("AffectsGIFactor", "GetAffectsGIFactor", "SetAffectsGIFactor");
  99. }
  100. }
  101. void AreaLightComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  102. {
  103. provided.push_back(AZ_CRC_CE("AreaLightService"));
  104. }
  105. void AreaLightComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  106. {
  107. incompatible.push_back(AZ_CRC_CE("AreaLightService"));
  108. }
  109. void AreaLightComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
  110. {
  111. dependent.push_back(AZ_CRC_CE("ShapeService"));
  112. }
  113. AreaLightComponentController::AreaLightComponentController(const AreaLightComponentConfig& config)
  114. : m_configuration(config)
  115. {
  116. }
  117. void AreaLightComponentController::Activate(EntityId entityId)
  118. {
  119. m_entityId = entityId;
  120. // Used to determine which features are supported.
  121. m_configuration.m_shapeType = 0;
  122. LmbrCentral::ShapeComponentRequestsBus::EventResult(m_configuration.m_shapeType, m_entityId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetShapeType);
  123. VerifyLightTypeAndShapeComponent();
  124. CreateLightShapeDelegate();
  125. if (m_configuration.RequiresShapeComponent() && m_lightShapeDelegate == nullptr)
  126. {
  127. AZ_Error("AreaLightComponentController", false, "AreaLightComponentController activated without having required shape component.");
  128. }
  129. AreaLightRequestBus::Handler::BusConnect(m_entityId);
  130. ConfigurationChanged();
  131. }
  132. void AreaLightComponentController::Deactivate()
  133. {
  134. AreaLightRequestBus::Handler::BusDisconnect(m_entityId);
  135. m_lightShapeDelegate.reset();
  136. }
  137. void AreaLightComponentController::SetConfiguration(const AreaLightComponentConfig& config)
  138. {
  139. m_configuration = config;
  140. VerifyLightTypeAndShapeComponent();
  141. ConfigurationChanged();
  142. }
  143. const AreaLightComponentConfig& AreaLightComponentController::GetConfiguration() const
  144. {
  145. m_configuration.m_cacheShadows = m_configuration.m_shadowCachingMode == AreaLightComponentConfig::ShadowCachingMode::UpdateOnChange;
  146. return m_configuration;
  147. }
  148. void AreaLightComponentController::SetVisibiliy(bool isVisible)
  149. {
  150. m_isVisible = isVisible;
  151. if (m_lightShapeDelegate)
  152. {
  153. m_lightShapeDelegate->SetVisibility(m_isVisible);
  154. if (m_isVisible)
  155. {
  156. // If the light is made visible, make sure to apply the configuration so all properties as set correctly.
  157. ConfigurationChanged();
  158. }
  159. }
  160. }
  161. void AreaLightComponentController::VerifyLightTypeAndShapeComponent()
  162. {
  163. constexpr Crc32 SphereShapeTypeId = AZ_CRC_CE("Sphere");
  164. constexpr Crc32 DiskShapeTypeId = AZ_CRC_CE("DiskShape");
  165. constexpr Crc32 CapsuleShapeTypeId = AZ_CRC_CE("Capsule");
  166. constexpr Crc32 QuadShapeTypeId = AZ_CRC_CE("QuadShape");
  167. constexpr Crc32 PoylgonShapeTypeId = AZ_CRC_CE("PolygonPrism");
  168. if (m_configuration.m_lightType == AreaLightComponentConfig::LightType::Unknown)
  169. {
  170. // Light type is unknown, see if it can be determined from a shape component.
  171. switch (m_configuration.m_shapeType)
  172. {
  173. case SphereShapeTypeId:
  174. m_configuration.m_lightType = AreaLightComponentConfig::LightType::Sphere;
  175. break;
  176. case DiskShapeTypeId:
  177. m_configuration.m_lightType = AreaLightComponentConfig::LightType::SpotDisk;
  178. break;
  179. case CapsuleShapeTypeId:
  180. m_configuration.m_lightType = AreaLightComponentConfig::LightType::Capsule;
  181. break;
  182. case QuadShapeTypeId:
  183. m_configuration.m_lightType = AreaLightComponentConfig::LightType::Quad;
  184. break;
  185. case PoylgonShapeTypeId:
  186. m_configuration.m_lightType = AreaLightComponentConfig::LightType::Polygon;
  187. break;
  188. default:
  189. break; // Light type can't be deduced.
  190. }
  191. }
  192. else if (m_configuration.m_shapeType == Crc32(0))
  193. {
  194. AZ_Error("AreaLightComponentController", !m_configuration.RequiresShapeComponent(), "The light type used on this area light requires a corresponding shape component");
  195. }
  196. else
  197. {
  198. // Validate the the light type matches up with shape type if the light type is an area light.
  199. AZ_Error("AreaLightComponentController",
  200. !(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Sphere && m_configuration.m_shapeType != SphereShapeTypeId),
  201. "The light type is a sphere, but the shape component is not.");
  202. AZ_Error("AreaLightComponentController",
  203. !(m_configuration.m_lightType == AreaLightComponentConfig::LightType::SpotDisk && m_configuration.m_shapeType != DiskShapeTypeId),
  204. "The light type is a disk, but the shape component is not.");
  205. AZ_Error("AreaLightComponentController",
  206. !(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Capsule && m_configuration.m_shapeType != CapsuleShapeTypeId),
  207. "The light type is a capsule, but the shape component is not.");
  208. AZ_Error("AreaLightComponentController",
  209. !(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Quad && m_configuration.m_shapeType != QuadShapeTypeId),
  210. "The light type is a quad, but the shape component is not.");
  211. AZ_Error("AreaLightComponentController",
  212. !(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Polygon && m_configuration.m_shapeType != PoylgonShapeTypeId),
  213. "The light type is a polygon, but the shape component is not.");
  214. }
  215. if (m_configuration.m_lightType == AreaLightComponentConfig::LightType::SimpleSpot)
  216. {
  217. m_configuration.m_enableShutters = true; // Simple spot always has shutters.
  218. }
  219. }
  220. void AreaLightComponentController::ConfigurationChanged()
  221. {
  222. m_configuration.m_shadowCachingMode = m_configuration.m_cacheShadows
  223. ? AreaLightComponentConfig::ShadowCachingMode::UpdateOnChange
  224. : AreaLightComponentConfig::ShadowCachingMode::NoCaching;
  225. ChromaChanged();
  226. IntensityChanged();
  227. AttenuationRadiusChanged();
  228. ShuttersChanged();
  229. ShadowsChanged();
  230. if (m_lightShapeDelegate)
  231. {
  232. m_lightShapeDelegate->SetLightEmitsBothDirections(m_configuration.m_lightEmitsBothDirections);
  233. m_lightShapeDelegate->SetUseFastApproximation(m_configuration.m_useFastApproximation);
  234. m_lightShapeDelegate->SetAffectsGI(m_configuration.m_affectsGI);
  235. m_lightShapeDelegate->SetAffectsGIFactor(m_configuration.m_affectsGIFactor);
  236. }
  237. }
  238. void AreaLightComponentController::IntensityChanged()
  239. {
  240. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorOrIntensityChanged, m_configuration.m_color, m_configuration.m_intensity);
  241. if (m_lightShapeDelegate)
  242. {
  243. m_lightShapeDelegate->SetPhotometricUnit(m_configuration.m_intensityMode);
  244. m_lightShapeDelegate->SetIntensity(m_configuration.m_intensity);
  245. }
  246. if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
  247. {
  248. AttenuationRadiusChanged();
  249. }
  250. }
  251. void AreaLightComponentController::ChromaChanged()
  252. {
  253. if (m_lightShapeDelegate)
  254. {
  255. m_lightShapeDelegate->SetChroma(m_configuration.m_color);
  256. }
  257. }
  258. void AreaLightComponentController::AttenuationRadiusChanged()
  259. {
  260. if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
  261. {
  262. AutoCalculateAttenuationRadius();
  263. }
  264. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnAttenutationRadiusChanged, m_configuration.m_attenuationRadius);
  265. if (m_lightShapeDelegate)
  266. {
  267. m_lightShapeDelegate->SetAttenuationRadius(m_configuration.m_attenuationRadius);
  268. }
  269. }
  270. void AreaLightComponentController::ShuttersChanged()
  271. {
  272. if (m_lightShapeDelegate)
  273. {
  274. m_lightShapeDelegate->SetEnableShutters(m_configuration.m_enableShutters);
  275. if (m_configuration.m_enableShutters)
  276. {
  277. m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
  278. }
  279. }
  280. }
  281. void AreaLightComponentController::ShadowsChanged()
  282. {
  283. if (m_lightShapeDelegate)
  284. {
  285. m_lightShapeDelegate->SetEnableShadow(m_configuration.m_enableShadow);
  286. if (m_configuration.m_enableShadow)
  287. {
  288. m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias);
  289. m_lightShapeDelegate->SetNormalShadowBias(m_configuration.m_normalShadowBias);
  290. m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize);
  291. m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
  292. m_lightShapeDelegate->SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
  293. m_lightShapeDelegate->SetEsmExponent(m_configuration.m_esmExponent);
  294. m_lightShapeDelegate->SetShadowCachingMode(m_configuration.m_shadowCachingMode);
  295. }
  296. }
  297. }
  298. void AreaLightComponentController::AutoCalculateAttenuationRadius()
  299. {
  300. if (m_lightShapeDelegate)
  301. {
  302. m_configuration.m_attenuationRadius = m_lightShapeDelegate->CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity);
  303. }
  304. }
  305. const Color& AreaLightComponentController::GetColor() const
  306. {
  307. return m_configuration.m_color;
  308. }
  309. void AreaLightComponentController::SetColor(const Color& color)
  310. {
  311. m_configuration.m_color = color;
  312. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnColorChanged, color);
  313. ChromaChanged();
  314. }
  315. bool AreaLightComponentController::GetLightEmitsBothDirections() const
  316. {
  317. return m_configuration.m_lightEmitsBothDirections;
  318. }
  319. void AreaLightComponentController::SetLightEmitsBothDirections(bool value)
  320. {
  321. m_configuration.m_lightEmitsBothDirections = value;
  322. }
  323. bool AreaLightComponentController::GetUseFastApproximation() const
  324. {
  325. return m_configuration.m_useFastApproximation;
  326. }
  327. void AreaLightComponentController::SetUseFastApproximation(bool value)
  328. {
  329. m_configuration.m_useFastApproximation = value;
  330. }
  331. PhotometricUnit AreaLightComponentController::GetIntensityMode() const
  332. {
  333. return m_configuration.m_intensityMode;
  334. }
  335. float AreaLightComponentController::GetIntensity() const
  336. {
  337. return m_configuration.m_intensity;
  338. }
  339. void AreaLightComponentController::SetIntensityAndMode(float intensity, PhotometricUnit intensityMode)
  340. {
  341. m_configuration.m_intensityMode = intensityMode;
  342. m_configuration.m_intensity = intensity;
  343. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, intensityMode);
  344. IntensityChanged();
  345. }
  346. void AreaLightComponentController::SetIntensity(float intensity, PhotometricUnit intensityMode)
  347. {
  348. AZ_Warning("Main Window", false, "This verion of SetIntensity() is deprecated. Use SetIntensityMode() instead.");
  349. m_configuration.m_intensityMode = intensityMode;
  350. m_configuration.m_intensity = intensity;
  351. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, intensityMode);
  352. IntensityChanged();
  353. }
  354. void AreaLightComponentController::SetIntensity(float intensity)
  355. {
  356. m_configuration.m_intensity = intensity;
  357. AreaLightNotificationBus::Event(m_entityId, &AreaLightNotifications::OnIntensityChanged, intensity, m_configuration.m_intensityMode);
  358. IntensityChanged();
  359. }
  360. float AreaLightComponentController::GetAttenuationRadius() const
  361. {
  362. return m_configuration.m_attenuationRadius;
  363. }
  364. void AreaLightComponentController::SetAttenuationRadius(float radius)
  365. {
  366. m_configuration.m_attenuationRadius = radius;
  367. m_configuration.m_attenuationRadiusMode = LightAttenuationRadiusMode::Explicit;
  368. AttenuationRadiusChanged();
  369. }
  370. void AreaLightComponentController::SetAttenuationRadiusMode(LightAttenuationRadiusMode attenuationRadiusMode)
  371. {
  372. m_configuration.m_attenuationRadiusMode = attenuationRadiusMode;
  373. AttenuationRadiusChanged();
  374. }
  375. void AreaLightComponentController::ConvertToIntensityMode(PhotometricUnit intensityMode)
  376. {
  377. if (m_lightShapeDelegate && m_lightShapeDelegate->GetPhotometricValue().GetType() != intensityMode)
  378. {
  379. m_configuration.m_intensityMode = intensityMode;
  380. m_configuration.m_intensity = m_lightShapeDelegate->SetPhotometricUnit(intensityMode);
  381. }
  382. }
  383. float AreaLightComponentController::GetSurfaceArea() const
  384. {
  385. return m_lightShapeDelegate ? m_lightShapeDelegate->GetSurfaceArea() : 0.0f;
  386. }
  387. bool AreaLightComponentController::GetEnableShutters() const
  388. {
  389. return m_configuration.m_enableShutters;
  390. }
  391. void AreaLightComponentController::SetEnableShutters(bool enabled)
  392. {
  393. m_configuration.m_enableShutters = enabled && m_configuration.SupportsShutters();
  394. if (m_lightShapeDelegate)
  395. {
  396. m_lightShapeDelegate->SetEnableShutters(enabled);
  397. }
  398. }
  399. float AreaLightComponentController::GetInnerShutterAngle() const
  400. {
  401. return m_configuration.m_innerShutterAngleDegrees;
  402. }
  403. void AreaLightComponentController::SetInnerShutterAngle(float degrees)
  404. {
  405. m_configuration.m_innerShutterAngleDegrees = degrees;
  406. if (m_lightShapeDelegate)
  407. {
  408. m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
  409. }
  410. }
  411. float AreaLightComponentController::GetOuterShutterAngle() const
  412. {
  413. return m_configuration.m_outerShutterAngleDegrees;
  414. }
  415. void AreaLightComponentController::SetOuterShutterAngle(float degrees)
  416. {
  417. m_configuration.m_outerShutterAngleDegrees = degrees;
  418. if (m_lightShapeDelegate)
  419. {
  420. m_lightShapeDelegate->SetShutterAngles(m_configuration.m_innerShutterAngleDegrees, m_configuration.m_outerShutterAngleDegrees);
  421. }
  422. }
  423. bool AreaLightComponentController::GetEnableShadow() const
  424. {
  425. return m_configuration.m_enableShadow;
  426. }
  427. void AreaLightComponentController::SetEnableShadow(bool enabled)
  428. {
  429. m_configuration.m_enableShadow = enabled && m_configuration.SupportsShadows();
  430. if (m_lightShapeDelegate)
  431. {
  432. m_lightShapeDelegate->SetEnableShadow(enabled);
  433. }
  434. }
  435. float AreaLightComponentController::GetShadowBias() const
  436. {
  437. return m_configuration.m_bias;
  438. }
  439. void AreaLightComponentController::SetShadowBias(float bias)
  440. {
  441. m_configuration.m_bias = bias;
  442. if (m_lightShapeDelegate)
  443. {
  444. m_lightShapeDelegate->SetShadowBias(bias);
  445. }
  446. }
  447. void AreaLightComponentController::SetNormalShadowBias(float bias)
  448. {
  449. m_configuration.m_normalShadowBias = bias;
  450. if (m_lightShapeDelegate)
  451. {
  452. m_lightShapeDelegate->SetNormalShadowBias(bias);
  453. }
  454. }
  455. float AreaLightComponentController::GetNormalShadowBias() const
  456. {
  457. return m_configuration.m_normalShadowBias;
  458. }
  459. ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const
  460. {
  461. return m_configuration.m_shadowmapMaxSize;
  462. }
  463. void AreaLightComponentController::SetShadowmapMaxSize(ShadowmapSize size)
  464. {
  465. m_configuration.m_shadowmapMaxSize = size;
  466. if (m_lightShapeDelegate)
  467. {
  468. m_lightShapeDelegate->SetShadowmapMaxSize(size);
  469. }
  470. }
  471. ShadowFilterMethod AreaLightComponentController::GetShadowFilterMethod() const
  472. {
  473. return m_configuration.m_shadowFilterMethod;
  474. }
  475. void AreaLightComponentController::SetShadowFilterMethod(ShadowFilterMethod method)
  476. {
  477. m_configuration.m_shadowFilterMethod = method;
  478. if (m_lightShapeDelegate)
  479. {
  480. m_lightShapeDelegate->SetShadowFilterMethod(method);
  481. }
  482. }
  483. uint32_t AreaLightComponentController::GetFilteringSampleCount() const
  484. {
  485. return m_configuration.m_filteringSampleCount;
  486. }
  487. void AreaLightComponentController::SetFilteringSampleCount(uint32_t count)
  488. {
  489. m_configuration.m_filteringSampleCount = static_cast<uint16_t>(count);
  490. if (m_lightShapeDelegate)
  491. {
  492. m_lightShapeDelegate->SetFilteringSampleCount(count);
  493. }
  494. }
  495. void AreaLightComponentController::HandleDisplayEntityViewport(
  496. [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
  497. AzFramework::DebugDisplayRequests& debugDisplay,
  498. bool isSelected)
  499. {
  500. Transform transform = Transform::CreateIdentity();
  501. TransformBus::EventResult(transform, m_entityId, &TransformBus::Events::GetWorldTM);
  502. AZ::Vector3 translationOffset = AZ::Vector3::CreateZero();
  503. LmbrCentral::ShapeComponentRequestsBus::EventResult(
  504. translationOffset, m_entityId, &LmbrCentral::ShapeComponentRequests::GetTranslationOffset);
  505. if (m_lightShapeDelegate)
  506. {
  507. m_lightShapeDelegate->DrawDebugDisplay(
  508. transform * AZ::Transform::CreateTranslation(translationOffset), m_configuration.m_color, debugDisplay, isSelected);
  509. }
  510. }
  511. float AreaLightComponentController::GetEsmExponent() const
  512. {
  513. return m_configuration.m_esmExponent;
  514. }
  515. void AreaLightComponentController::SetEsmExponent(float esmExponent)
  516. {
  517. m_configuration.m_esmExponent = esmExponent;
  518. if (m_lightShapeDelegate)
  519. {
  520. m_lightShapeDelegate->SetEsmExponent(esmExponent);
  521. }
  522. }
  523. AreaLightComponentConfig::ShadowCachingMode AreaLightComponentController::GetShadowCachingMode() const
  524. {
  525. return m_configuration.m_shadowCachingMode;
  526. }
  527. void AreaLightComponentController::SetShadowCachingMode(AreaLightComponentConfig::ShadowCachingMode cachingMode)
  528. {
  529. m_configuration.m_shadowCachingMode = cachingMode;
  530. m_configuration.m_cacheShadows = m_configuration.m_shadowCachingMode == AreaLightComponentConfig::ShadowCachingMode::UpdateOnChange;
  531. if (m_lightShapeDelegate)
  532. {
  533. m_lightShapeDelegate->SetShadowCachingMode(cachingMode);
  534. }
  535. }
  536. bool AreaLightComponentController::GetAffectsGI() const
  537. {
  538. return m_configuration.m_affectsGI;
  539. }
  540. void AreaLightComponentController::SetAffectsGI(bool affectsGI) const
  541. {
  542. if (m_lightShapeDelegate)
  543. {
  544. m_lightShapeDelegate->SetAffectsGI(affectsGI);
  545. }
  546. }
  547. float AreaLightComponentController::GetAffectsGIFactor() const
  548. {
  549. return m_configuration.m_affectsGIFactor;
  550. }
  551. void AreaLightComponentController::SetAffectsGIFactor(float affectsGIFactor) const
  552. {
  553. if (m_lightShapeDelegate)
  554. {
  555. m_lightShapeDelegate->SetAffectsGIFactor(affectsGIFactor);
  556. }
  557. }
  558. AZ::Aabb AreaLightComponentController::GetLocalVisualizationBounds() const
  559. {
  560. return m_lightShapeDelegate ? m_lightShapeDelegate->GetLocalVisualizationBounds()
  561. : AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
  562. }
  563. void AreaLightComponentController::CreateLightShapeDelegate()
  564. {
  565. switch (m_configuration.m_lightType)
  566. {
  567. // Simple types
  568. case AreaLightComponentConfig::LightType::SimplePoint:
  569. m_lightShapeDelegate = AZStd::make_unique<SimplePointLightDelegate>(m_entityId, m_isVisible);
  570. break;
  571. case AreaLightComponentConfig::LightType::SimpleSpot:
  572. m_lightShapeDelegate = AZStd::make_unique<SimpleSpotLightDelegate>(m_entityId, m_isVisible);
  573. break;
  574. // Area light types
  575. case AreaLightComponentConfig::LightType::Sphere:
  576. {
  577. LmbrCentral::SphereShapeComponentRequests* sphereShapeInterface = LmbrCentral::SphereShapeComponentRequestsBus::FindFirstHandler(m_entityId);
  578. if (sphereShapeInterface)
  579. {
  580. m_lightShapeDelegate = AZStd::make_unique<SphereLightDelegate>(sphereShapeInterface, m_entityId, m_isVisible);
  581. }
  582. break;
  583. }
  584. case AreaLightComponentConfig::LightType::SpotDisk:
  585. {
  586. LmbrCentral::DiskShapeComponentRequests* diskShapeInterface = LmbrCentral::DiskShapeComponentRequestBus::FindFirstHandler(m_entityId);
  587. if (diskShapeInterface)
  588. {
  589. m_lightShapeDelegate = AZStd::make_unique<DiskLightDelegate>(diskShapeInterface, m_entityId, m_isVisible);
  590. }
  591. break;
  592. }
  593. case AreaLightComponentConfig::LightType::Capsule:
  594. {
  595. LmbrCentral::CapsuleShapeComponentRequests* capsuleShapeInterface = LmbrCentral::CapsuleShapeComponentRequestsBus::FindFirstHandler(m_entityId);
  596. if (capsuleShapeInterface)
  597. {
  598. m_lightShapeDelegate = AZStd::make_unique<CapsuleLightDelegate>(capsuleShapeInterface, m_entityId, m_isVisible);
  599. }
  600. break;
  601. }
  602. case AreaLightComponentConfig::LightType::Quad:
  603. {
  604. LmbrCentral::QuadShapeComponentRequests* quadShapeInterface = LmbrCentral::QuadShapeComponentRequestBus::FindFirstHandler(m_entityId);
  605. if (quadShapeInterface)
  606. {
  607. m_lightShapeDelegate = AZStd::make_unique<QuadLightDelegate>(quadShapeInterface, m_entityId, m_isVisible);
  608. }
  609. break;
  610. }
  611. case AreaLightComponentConfig::LightType::Polygon:
  612. {
  613. LmbrCentral::PolygonPrismShapeComponentRequests* polyPrismShapeInterface = LmbrCentral::PolygonPrismShapeComponentRequestBus::FindFirstHandler(m_entityId);
  614. if (polyPrismShapeInterface)
  615. {
  616. m_lightShapeDelegate = AZStd::make_unique<PolygonLightDelegate>(polyPrismShapeInterface, m_entityId, m_isVisible);
  617. }
  618. break;
  619. }
  620. }
  621. if (m_lightShapeDelegate)
  622. {
  623. m_lightShapeDelegate->SetConfig(&m_configuration);
  624. }
  625. }
  626. } // namespace AZ::Render