DirectionalLightComponentController.cpp 32 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/DirectionalLightComponentController.h>
  9. #include <Atom/RPI.Public/Scene.h>
  10. #include <Atom/Feature/CoreLights/ShadowConstants.h>
  11. #include <AzCore/RTTI/BehaviorContext.h>
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzCore/Serialization/SerializeContext.h>
  14. #include <AzCore/std/containers/vector.h>
  15. #include <Atom/RPI.Public/ViewportContext.h>
  16. #include <Atom/RPI.Public/ViewportContextBus.h>
  17. #include <Atom/RPI.Public/ViewProviderBus.h>
  18. namespace AZ
  19. {
  20. namespace Render
  21. {
  22. void DirectionalLightComponentController::Reflect(ReflectContext* context)
  23. {
  24. DirectionalLightComponentConfig::Reflect(context);
  25. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  26. {
  27. serializeContext->Class<DirectionalLightComponentController>()
  28. ->Version(1)
  29. ->Field("Configuration", &DirectionalLightComponentController::m_configuration);
  30. ;
  31. }
  32. if (BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context))
  33. {
  34. behaviorContext
  35. ->Enum<static_cast<uint32_t>(ShadowFilterMethod::None)>("ShadowFilterMethod_None")
  36. ->Enum<static_cast<uint32_t>(ShadowFilterMethod::Pcf)>("ShadowFilterMethod_PCF")
  37. ->Enum<static_cast<uint32_t>(ShadowFilterMethod::Esm)>("ShadowFilterMethod_ESM")
  38. ->Enum<static_cast<uint32_t>(ShadowFilterMethod::EsmPcf)>("ShadowFilterMethod_ESM_PCF")
  39. ->Enum<static_cast<uint32_t>(ShadowmapSize::None)>("ShadowmapSize_None")
  40. ->Enum<static_cast<uint32_t>(ShadowmapSize::Size256)>("ShadowmapSize_256")
  41. ->Enum<static_cast<uint32_t>(ShadowmapSize::Size512)>("ShadowmapSize_512")
  42. ->Enum<static_cast<uint32_t>(ShadowmapSize::Size1024)>("ShadowmapSize_1024")
  43. ->Enum<static_cast<uint32_t>(ShadowmapSize::Size2048)>("ShadowmapSize_2045")
  44. ;
  45. behaviorContext->EBus<DirectionalLightRequestBus>("DirectionalLightRequestBus")
  46. ->Attribute(AZ::Script::Attributes::Module, "render")
  47. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
  48. ->Event("GetColor", &DirectionalLightRequestBus::Events::GetColor)
  49. ->Event("SetColor", &DirectionalLightRequestBus::Events::SetColor)
  50. ->Event("GetIntensity", &DirectionalLightRequestBus::Events::GetIntensity)
  51. ->Event("SetIntensity", static_cast<void(DirectionalLightRequestBus::Events::*)(float)>(&DirectionalLightRequestBus::Events::SetIntensity))
  52. ->Event("GetAngularDiameter", &DirectionalLightRequestBus::Events::GetAngularDiameter)
  53. ->Event("SetAngularDiameter", &DirectionalLightRequestBus::Events::SetAngularDiameter)
  54. ->Event("GetShadowmapSize", &DirectionalLightRequestBus::Events::GetShadowmapSize)
  55. ->Event("SetShadowmapSize", &DirectionalLightRequestBus::Events::SetShadowmapSize)
  56. ->Event("GetCascadeCount", &DirectionalLightRequestBus::Events::GetCascadeCount)
  57. ->Event("SetCascadeCount", &DirectionalLightRequestBus::Events::SetCascadeCount)
  58. ->Event("GetSplitRatio", &DirectionalLightRequestBus::Events::GetShadowmapFrustumSplitSchemeRatio)
  59. ->Event("SetSplitRatio", &DirectionalLightRequestBus::Events::SetShadowmapFrustumSplitSchemeRatio)
  60. ->Event("GetCascadeFarDepth", &DirectionalLightRequestBus::Events::GetCascadeFarDepth)
  61. ->Event("SetCascadeFarDepth", &DirectionalLightRequestBus::Events::SetCascadeFarDepth)
  62. ->Event("GetSplitAutomatic", &DirectionalLightRequestBus::Events::GetShadowmapFrustumSplitAutomatic)
  63. ->Event("SetSplitAutomatic", &DirectionalLightRequestBus::Events::SetShadowmapFrustumSplitAutomatic)
  64. ->Event("GetCameraEntityId", &DirectionalLightRequestBus::Events::GetCameraEntityId)
  65. ->Event("SetCameraEntityId", &DirectionalLightRequestBus::Events::SetCameraEntityId)
  66. ->Event("GetShadowFarClipDistance", &DirectionalLightRequestBus::Events::GetShadowFarClipDistance)
  67. ->Event("SetShadowFarClipDistance", &DirectionalLightRequestBus::Events::SetShadowFarClipDistance)
  68. ->Event("GetGroundHeight", &DirectionalLightRequestBus::Events::GetGroundHeight)
  69. ->Event("SetGroundHeight", &DirectionalLightRequestBus::Events::SetGroundHeight)
  70. ->Event("GetViewFrustumCorrectionEnabled", &DirectionalLightRequestBus::Events::GetViewFrustumCorrectionEnabled)
  71. ->Event("SetViewFrustumCorrectionEnabled", &DirectionalLightRequestBus::Events::SetViewFrustumCorrectionEnabled)
  72. ->Event("GetDebugColoringEnabled", &DirectionalLightRequestBus::Events::GetDebugColoringEnabled)
  73. ->Event("SetDebugColoringEnabled", &DirectionalLightRequestBus::Events::SetDebugColoringEnabled)
  74. ->Event("GetShadowFilterMethod", &DirectionalLightRequestBus::Events::GetShadowFilterMethod)
  75. ->Event("SetShadowFilterMethod", &DirectionalLightRequestBus::Events::SetShadowFilterMethod)
  76. ->Event("GetFilteringSampleCount", &DirectionalLightRequestBus::Events::GetFilteringSampleCount)
  77. ->Event("SetFilteringSampleCount", &DirectionalLightRequestBus::Events::SetFilteringSampleCount)
  78. ->Event("GetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::GetShadowReceiverPlaneBiasEnabled)
  79. ->Event("SetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::SetShadowReceiverPlaneBiasEnabled)
  80. ->Event("GetShadowBias", &DirectionalLightRequestBus::Events::GetShadowBias)
  81. ->Event("SetShadowBias", &DirectionalLightRequestBus::Events::SetShadowBias)
  82. ->Event("GetNormalShadowBias", &DirectionalLightRequestBus::Events::GetNormalShadowBias)
  83. ->Event("SetNormalShadowBias", &DirectionalLightRequestBus::Events::SetNormalShadowBias)
  84. ->Event("GetCascadeBlendingEnabled", &DirectionalLightRequestBus::Events::GetCascadeBlendingEnabled)
  85. ->Event("SetCascadeBlendingEnabled", &DirectionalLightRequestBus::Events::SetCascadeBlendingEnabled)
  86. ->Event("GetAffectsGI", &DirectionalLightRequestBus::Events::GetAffectsGI)
  87. ->Event("SetAffectsGI", &DirectionalLightRequestBus::Events::SetAffectsGI)
  88. ->Event("GetAffectsGIFactor", &DirectionalLightRequestBus::Events::GetAffectsGIFactor)
  89. ->Event("SetAffectsGIFactor", &DirectionalLightRequestBus::Events::SetAffectsGIFactor)
  90. ->VirtualProperty("Color", "GetColor", "SetColor")
  91. ->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
  92. ->VirtualProperty("AngularDiameter", "GetAngularDiameter", "SetAngularDiameter")
  93. ->VirtualProperty("ShadowmapSize", "GetShadowmapSize", "SetShadowmapSize")
  94. ->VirtualProperty("CascadeCount", "GetCascadeCount", "SetCascadeCount")
  95. ->VirtualProperty("SplitRatio", "GetSplitRatio", "SetSplitRatio")
  96. ->VirtualProperty("CascadeDepth", "GetCascadeFarDepth", "SetCascadeFarDepth")
  97. ->VirtualProperty("SplitAutomatic", "GetSplitAutomatic", "SetSplitAutomatic")
  98. ->VirtualProperty("ShadowFarClipDistance", "GetShadowFarClipDistance", "SetShadowFarClipDistance")
  99. ->VirtualProperty("GroundHeight", "GetGroundHeight", "SetGroundHeight")
  100. ->VirtualProperty("ViewFrustumCorrectionEnabled", "GetViewFrustumCorrectionEnabled", "SetViewFrustumCorrectionEnabled")
  101. ->VirtualProperty("DebugColoringEnabled", "GetDebugColoringEnabled", "SetDebugColoringEnabled")
  102. ->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
  103. ->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
  104. ->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled")
  105. ->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
  106. ->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
  107. ->VirtualProperty("BlendBetweenCascadesEnabled", "GetCascadeBlendingEnabled", "SetCascadeBlendingEnabled")
  108. ->VirtualProperty("AffectsGI", "GetAffectsGI", "SetAffectsGI")
  109. ->VirtualProperty("AffectsGIFactor", "GetAffectsGIFactor", "SetAffectsGIFactor");
  110. ;
  111. }
  112. }
  113. void DirectionalLightComponentController::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
  114. {
  115. dependent.push_back(AZ_CRC("TransformService", 0x8ee22c50));
  116. }
  117. void DirectionalLightComponentController::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
  118. {
  119. incompatible.push_back(AZ_CRC("DirectionalLightService", 0x5270619f));
  120. incompatible.push_back(AZ_CRC_CE("NonUniformScaleComponent"));
  121. }
  122. void DirectionalLightComponentController::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
  123. {
  124. provided.push_back(AZ_CRC("DirectionalLightService", 0x5270619f));
  125. }
  126. DirectionalLightComponentController::DirectionalLightComponentController(const DirectionalLightComponentConfig& config)
  127. : m_configuration(config)
  128. {
  129. }
  130. void DirectionalLightComponentController::Activate(EntityId entityId)
  131. {
  132. m_entityId = entityId;
  133. m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<DirectionalLightFeatureProcessorInterface>(entityId);
  134. AZ_Error("DirectionalLightComponentController", m_featureProcessor, "Could not find a DirectionalLightFeatureProcessorInterface on the scene.");
  135. if (m_featureProcessor)
  136. {
  137. m_lightHandle = m_featureProcessor->AcquireLight();
  138. ApplyConfiguration();
  139. DirectionalLightRequestBus::Handler::BusConnect(entityId);
  140. TickBus::Handler::BusConnect();
  141. TransformNotificationBus::MultiHandler::BusConnect(entityId);
  142. Camera::CameraNotificationBus::Handler::BusConnect();
  143. }
  144. }
  145. void DirectionalLightComponentController::Deactivate()
  146. {
  147. Camera::CameraNotificationBus::Handler::BusDisconnect();
  148. TransformNotificationBus::MultiHandler::BusDisconnect();
  149. TickBus::Handler::BusDisconnect();
  150. DirectionalLightRequestBus::Handler::BusDisconnect();
  151. if (m_featureProcessor)
  152. {
  153. m_featureProcessor->ReleaseLight(m_lightHandle);
  154. }
  155. m_entityId.SetInvalid();
  156. }
  157. void DirectionalLightComponentController::SetConfiguration(const DirectionalLightComponentConfig& config)
  158. {
  159. m_configuration = config;
  160. if (m_featureProcessor)
  161. {
  162. ApplyConfiguration();
  163. }
  164. }
  165. const Color& DirectionalLightComponentController::GetColor() const
  166. {
  167. return m_configuration.m_color;
  168. }
  169. void DirectionalLightComponentController::SetColor(const Color& color)
  170. {
  171. m_configuration.m_color = color;
  172. ColorIntensityChanged();
  173. }
  174. float DirectionalLightComponentController::GetIntensity() const
  175. {
  176. return m_configuration.m_intensity;
  177. }
  178. void DirectionalLightComponentController::SetIntensity(float intensity, PhotometricUnit unit)
  179. {
  180. m_photometricValue.ConvertToPhotometricUnit(unit);
  181. m_photometricValue.SetIntensity(intensity);
  182. m_configuration.m_intensityMode = unit;
  183. m_configuration.m_intensity = intensity;
  184. ColorIntensityChanged();
  185. }
  186. void DirectionalLightComponentController::SetIntensity(float intensity)
  187. {
  188. m_photometricValue.SetIntensity(intensity);
  189. m_configuration.m_intensity = intensity;
  190. ColorIntensityChanged();
  191. }
  192. float DirectionalLightComponentController::GetAngularDiameter() const
  193. {
  194. return m_configuration.m_angularDiameter;
  195. }
  196. void DirectionalLightComponentController::SetAngularDiameter(float angularDiameter)
  197. {
  198. m_configuration.m_angularDiameter = angularDiameter;
  199. if (m_featureProcessor)
  200. {
  201. m_featureProcessor->SetAngularDiameter(m_lightHandle, m_configuration.m_angularDiameter);
  202. }
  203. }
  204. ShadowmapSize DirectionalLightComponentController::GetShadowmapSize() const
  205. {
  206. return m_configuration.m_shadowmapSize;
  207. }
  208. void DirectionalLightComponentController::SetShadowmapSize(ShadowmapSize size)
  209. {
  210. // The minimum valid ShadowmapSize is 256 and maximum one is 2048.
  211. const uint32_t sizeInt = aznumeric_cast<uint32_t>(size);
  212. if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size512))
  213. {
  214. size = ShadowmapSize::Size256;
  215. }
  216. else if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size1024))
  217. {
  218. size = ShadowmapSize::Size512;
  219. }
  220. else if (sizeInt < aznumeric_cast<uint32_t>(ShadowmapSize::Size2048))
  221. {
  222. size = ShadowmapSize::Size1024;
  223. }
  224. else
  225. {
  226. size = ShadowmapSize::Size2048;
  227. }
  228. m_configuration.m_shadowmapSize = size;
  229. if (m_featureProcessor)
  230. {
  231. m_featureProcessor->SetShadowmapSize(m_lightHandle, size);
  232. }
  233. }
  234. uint32_t DirectionalLightComponentController::GetCascadeCount() const
  235. {
  236. return aznumeric_cast<uint32_t>(m_configuration.m_cascadeCount);
  237. }
  238. void DirectionalLightComponentController::SetCascadeCount(uint32_t cascadeCount)
  239. {
  240. const uint16_t cascadeCount16 = GetMin(static_cast<uint16_t>(Shadow::MaxNumberOfCascades), GetMax<uint16_t>(1, aznumeric_cast<uint16_t>(cascadeCount)));
  241. cascadeCount = cascadeCount16;
  242. m_configuration.m_cascadeCount = cascadeCount16;
  243. if (m_featureProcessor)
  244. {
  245. m_featureProcessor->SetCascadeCount(m_lightHandle, cascadeCount16);
  246. }
  247. }
  248. float DirectionalLightComponentController::GetShadowmapFrustumSplitSchemeRatio() const
  249. {
  250. return m_configuration.m_shadowmapFrustumSplitSchemeRatio;
  251. }
  252. void DirectionalLightComponentController::SetShadowmapFrustumSplitSchemeRatio(float ratio)
  253. {
  254. ratio = GetMin(1.f, GetMax(0.f, ratio));
  255. m_configuration.m_shadowmapFrustumSplitSchemeRatio = ratio;
  256. m_configuration.m_isShadowmapFrustumSplitAutomatic = true;
  257. if (m_featureProcessor)
  258. {
  259. m_featureProcessor->SetShadowmapFrustumSplitSchemeRatio(m_lightHandle, ratio);
  260. }
  261. }
  262. const Vector4& DirectionalLightComponentController::GetCascadeFarDepth()
  263. {
  264. return m_configuration.m_cascadeFarDepths;
  265. }
  266. void DirectionalLightComponentController::SetCascadeFarDepth(const Vector4& farDepth)
  267. {
  268. m_configuration.m_cascadeFarDepths = farDepth;
  269. if (m_featureProcessor)
  270. {
  271. for (uint16_t index = 0; index < Shadow::MaxNumberOfCascades; ++index)
  272. {
  273. m_featureProcessor->SetCascadeFarDepth(m_lightHandle, index, farDepth.GetElement(index));
  274. }
  275. }
  276. }
  277. bool DirectionalLightComponentController::GetShadowmapFrustumSplitAutomatic() const
  278. {
  279. return m_configuration.m_isShadowmapFrustumSplitAutomatic;
  280. }
  281. void DirectionalLightComponentController::SetShadowmapFrustumSplitAutomatic(bool isAutomatic)
  282. {
  283. m_configuration.m_isShadowmapFrustumSplitAutomatic = isAutomatic;
  284. }
  285. EntityId DirectionalLightComponentController::GetCameraEntityId() const
  286. {
  287. return m_configuration.m_cameraEntityId;
  288. }
  289. void DirectionalLightComponentController::SetCameraEntityId(EntityId cameraEntityId)
  290. {
  291. if (m_configuration.m_cameraEntityId.IsValid())
  292. {
  293. TransformNotificationBus::MultiHandler::BusDisconnect(m_configuration.m_cameraEntityId);
  294. }
  295. if (cameraEntityId.IsValid())
  296. {
  297. TransformNotificationBus::MultiHandler::BusConnect(cameraEntityId);
  298. }
  299. m_configuration.m_cameraEntityId = cameraEntityId;
  300. }
  301. float DirectionalLightComponentController::GetShadowFarClipDistance() const
  302. {
  303. return m_configuration.m_shadowFarClipDistance;
  304. }
  305. void DirectionalLightComponentController::SetShadowFarClipDistance(float farDist)
  306. {
  307. m_configuration.m_shadowFarClipDistance = farDist;
  308. if (m_featureProcessor)
  309. {
  310. m_featureProcessor->SetShadowFarClipDistance(m_lightHandle, farDist);
  311. }
  312. }
  313. float DirectionalLightComponentController::GetGroundHeight() const
  314. {
  315. return m_configuration.m_groundHeight;
  316. }
  317. void DirectionalLightComponentController::SetGroundHeight(float groundHeight)
  318. {
  319. m_configuration.m_groundHeight = groundHeight;
  320. if (m_featureProcessor)
  321. {
  322. m_featureProcessor->SetGroundHeight(m_lightHandle, groundHeight);
  323. }
  324. }
  325. bool DirectionalLightComponentController::GetViewFrustumCorrectionEnabled() const
  326. {
  327. return m_configuration.m_isCascadeCorrectionEnabled;
  328. }
  329. void DirectionalLightComponentController::SetViewFrustumCorrectionEnabled(bool enabled)
  330. {
  331. m_configuration.m_isCascadeCorrectionEnabled = enabled;
  332. if (m_featureProcessor)
  333. {
  334. m_featureProcessor->SetViewFrustumCorrectionEnabled(m_lightHandle, enabled);
  335. }
  336. }
  337. bool DirectionalLightComponentController::GetDebugColoringEnabled() const
  338. {
  339. return m_configuration.m_isDebugColoringEnabled;
  340. }
  341. void DirectionalLightComponentController::SetDebugColoringEnabled(bool enabled)
  342. {
  343. m_configuration.m_isDebugColoringEnabled = enabled;
  344. if (m_featureProcessor)
  345. {
  346. m_featureProcessor->SetDebugFlags(m_lightHandle, enabled ?
  347. DirectionalLightFeatureProcessorInterface::DebugDrawFlags::DebugDrawAll :
  348. DirectionalLightFeatureProcessorInterface::DebugDrawFlags::DebugDrawNone
  349. );
  350. }
  351. }
  352. ShadowFilterMethod DirectionalLightComponentController::GetShadowFilterMethod() const
  353. {
  354. return m_configuration.m_shadowFilterMethod;
  355. }
  356. void DirectionalLightComponentController::SetShadowFilterMethod(ShadowFilterMethod method)
  357. {
  358. if (aznumeric_cast<uint32_t>(method) >= aznumeric_cast<uint32_t>(ShadowFilterMethod::Count))
  359. {
  360. method = ShadowFilterMethod::None;
  361. }
  362. m_configuration.m_shadowFilterMethod = method;
  363. if (m_featureProcessor)
  364. {
  365. m_featureProcessor->SetShadowFilterMethod(m_lightHandle, method);
  366. }
  367. }
  368. uint32_t DirectionalLightComponentController::GetFilteringSampleCount() const
  369. {
  370. return aznumeric_cast<uint32_t>(m_configuration.m_filteringSampleCount);
  371. }
  372. void DirectionalLightComponentController::SetShadowBias(float bias)
  373. {
  374. m_configuration.m_shadowBias = bias;
  375. if (m_featureProcessor)
  376. {
  377. m_featureProcessor->SetShadowBias(m_lightHandle, bias);
  378. }
  379. }
  380. float DirectionalLightComponentController::GetShadowBias() const
  381. {
  382. return m_configuration.m_shadowBias;
  383. }
  384. void DirectionalLightComponentController::SetNormalShadowBias(float bias)
  385. {
  386. m_configuration.m_normalShadowBias = bias;
  387. if (m_featureProcessor)
  388. {
  389. m_featureProcessor->SetNormalShadowBias(m_lightHandle, bias);
  390. }
  391. }
  392. float DirectionalLightComponentController::GetNormalShadowBias() const
  393. {
  394. return m_configuration.m_normalShadowBias;
  395. }
  396. void DirectionalLightComponentController::SetFilteringSampleCount(uint32_t count)
  397. {
  398. const uint16_t count16 = GetMin(Shadow::MaxPcfSamplingCount, aznumeric_cast<uint16_t>(count));
  399. m_configuration.m_filteringSampleCount = count16;
  400. if (m_featureProcessor)
  401. {
  402. m_featureProcessor->SetFilteringSampleCount(m_lightHandle, count16);
  403. }
  404. }
  405. void DirectionalLightComponentController::SetFullscreenBlurEnabled(bool enable)
  406. {
  407. m_configuration.m_fullscreenBlurEnabled = enable;
  408. if (m_featureProcessor)
  409. {
  410. m_featureProcessor->SetFullscreenBlurEnabled(m_lightHandle, enable);
  411. }
  412. }
  413. void DirectionalLightComponentController::SetFullscreenBlurConstFalloff(float blurConstFalloff)
  414. {
  415. m_configuration.m_fullscreenBlurConstFalloff = blurConstFalloff;
  416. if (m_featureProcessor)
  417. {
  418. m_featureProcessor->SetFullscreenBlurConstFalloff(m_lightHandle, blurConstFalloff);
  419. }
  420. }
  421. void DirectionalLightComponentController::SetFullscreenBlurDepthFalloffStrength(float blurDepthFalloffStrength)
  422. {
  423. m_configuration.m_fullscreenBlurDepthFalloffStrength = blurDepthFalloffStrength;
  424. if (m_featureProcessor)
  425. {
  426. m_featureProcessor->SetFullscreenBlurDepthFalloffStrength(m_lightHandle, blurDepthFalloffStrength);
  427. }
  428. }
  429. bool DirectionalLightComponentController::GetAffectsGI() const
  430. {
  431. return m_configuration.m_affectsGI;
  432. }
  433. void DirectionalLightComponentController::SetAffectsGI(bool affectsGI)
  434. {
  435. m_configuration.m_affectsGI = affectsGI;
  436. if (m_featureProcessor)
  437. {
  438. m_featureProcessor->SetAffectsGI(m_lightHandle, m_configuration.m_affectsGI);
  439. }
  440. }
  441. float DirectionalLightComponentController::GetAffectsGIFactor() const
  442. {
  443. return m_configuration.m_affectsGIFactor;
  444. }
  445. void DirectionalLightComponentController::SetAffectsGIFactor(float affectsGIFactor)
  446. {
  447. m_configuration.m_affectsGIFactor = affectsGIFactor;
  448. if (m_featureProcessor)
  449. {
  450. m_featureProcessor->SetAffectsGIFactor(m_lightHandle, m_configuration.m_affectsGIFactor);
  451. }
  452. }
  453. void DirectionalLightComponentController::BindConfigurationChangedEventHandler(DirectionalLightConfigurationChangedEvent::Handler& configurationChangedHandler)
  454. {
  455. configurationChangedHandler.Connect(m_configurationChangedEvent);
  456. }
  457. const DirectionalLightComponentConfig& DirectionalLightComponentController::GetConfiguration() const
  458. {
  459. return m_configuration;
  460. }
  461. void DirectionalLightComponentController::OnTick(float, ScriptTimePoint)
  462. {
  463. if (!m_configuration.m_cameraEntityId.IsValid())
  464. {
  465. UpdateCameraTransform();
  466. }
  467. if (m_featureProcessor)
  468. {
  469. m_featureProcessor->SetCameraConfiguration(m_lightHandle, GetCameraConfiguration());
  470. }
  471. }
  472. void DirectionalLightComponentController::OnTransformChanged(const Transform&, const Transform&)
  473. {
  474. const EntityId* currentBusId = TransformNotificationBus::GetCurrentBusId();
  475. if (!currentBusId)
  476. {
  477. AZ_Assert(false, "Cannot get current Bus ID.");
  478. return;
  479. }
  480. if (*currentBusId == m_entityId)
  481. {
  482. UpdateLightTransform();
  483. }
  484. else if (*currentBusId == m_configuration.m_cameraEntityId)
  485. {
  486. UpdateCameraTransform();
  487. }
  488. }
  489. void DirectionalLightComponentController::OnCameraAdded(const AZ::EntityId& cameraId)
  490. {
  491. if (cameraId == m_configuration.m_cameraEntityId)
  492. {
  493. TransformNotificationBus::MultiHandler::BusConnect(cameraId);
  494. }
  495. }
  496. void DirectionalLightComponentController::OnCameraRemoved(const AZ::EntityId& cameraId)
  497. {
  498. if (cameraId == m_configuration.m_cameraEntityId)
  499. {
  500. TransformNotificationBus::MultiHandler::BusDisconnect(cameraId);
  501. m_configuration.m_cameraEntityId.SetInvalid();
  502. }
  503. }
  504. void DirectionalLightComponentController::ApplyConfiguration()
  505. {
  506. m_photometricValue = PhotometricValue(m_configuration.m_intensity, m_configuration.m_color, m_configuration.m_intensityMode);
  507. ColorIntensityChanged();
  508. SetAngularDiameter(m_configuration.m_angularDiameter);
  509. SetCameraEntityId(m_configuration.m_cameraEntityId);
  510. SetCascadeCount(m_configuration.m_cascadeCount);
  511. if (m_configuration.m_isShadowmapFrustumSplitAutomatic)
  512. {
  513. SetShadowmapFrustumSplitSchemeRatio(m_configuration.m_shadowmapFrustumSplitSchemeRatio);
  514. }
  515. else
  516. {
  517. SetCascadeFarDepth(m_configuration.m_cascadeFarDepths);
  518. }
  519. SetShadowmapSize(m_configuration.m_shadowmapSize);
  520. UpdateLightTransform();
  521. m_lastCameraTransform = Transform::CreateTranslation(AZ::Vector3(std::numeric_limits<float>::max())); // invalid value
  522. UpdateCameraTransform();
  523. if (m_featureProcessor)
  524. {
  525. m_featureProcessor->SetCameraConfiguration(m_lightHandle, GetCameraConfiguration());
  526. }
  527. SetShadowFarClipDistance(m_configuration.m_shadowFarClipDistance);
  528. SetGroundHeight(m_configuration.m_groundHeight);
  529. SetViewFrustumCorrectionEnabled(m_configuration.m_isCascadeCorrectionEnabled);
  530. SetDebugColoringEnabled(m_configuration.m_isDebugColoringEnabled);
  531. SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
  532. SetShadowBias(m_configuration.m_shadowBias);
  533. SetNormalShadowBias(m_configuration.m_normalShadowBias);
  534. SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
  535. SetShadowReceiverPlaneBiasEnabled(m_configuration.m_receiverPlaneBiasEnabled);
  536. SetCascadeBlendingEnabled(m_configuration.m_cascadeBlendingEnabled);
  537. SetFullscreenBlurEnabled(m_configuration.m_fullscreenBlurEnabled);
  538. SetFullscreenBlurConstFalloff(m_configuration.m_fullscreenBlurConstFalloff);
  539. SetFullscreenBlurDepthFalloffStrength(m_configuration.m_fullscreenBlurDepthFalloffStrength);
  540. SetAffectsGI(m_configuration.m_affectsGI);
  541. SetAffectsGIFactor(m_configuration.m_affectsGIFactor);
  542. // [GFX TODO][ATOM-1726] share config for multiple light (e.g., light ID).
  543. // [GFX TODO][ATOM-2416] adapt to multiple viewports.
  544. }
  545. Camera::Configuration DirectionalLightComponentController::GetCameraConfiguration() const
  546. {
  547. Camera::Configuration config;
  548. if (m_configuration.m_cameraEntityId.IsValid())
  549. {
  550. Camera::CameraRequestBus::EventResult(
  551. config,
  552. m_configuration.m_cameraEntityId,
  553. &Camera::CameraRequestBus::Events::GetCameraConfiguration);
  554. }
  555. else
  556. {
  557. Camera::ActiveCameraRequestBus::BroadcastResult(
  558. config,
  559. &Camera::ActiveCameraRequestBus::Events::GetActiveCameraConfiguration);
  560. }
  561. if (config.m_fovRadians == 0.f)
  562. {
  563. // When the entity does not have a camera component,
  564. // the config. get invalid. Then we use the default config.
  565. config.m_fovRadians = Constants::HalfPi;
  566. config.m_nearClipDistance = 0.1f;
  567. config.m_farClipDistance = 100.f;
  568. config.m_frustumWidth = 100.f;
  569. config.m_frustumHeight = 100.f;
  570. }
  571. return config;
  572. }
  573. void DirectionalLightComponentController::UpdateCameraTransform()
  574. {
  575. auto cameraTransform = Transform::CreateIdentity();
  576. if (m_configuration.m_cameraEntityId.IsValid())
  577. {
  578. TransformBus::EventResult(
  579. cameraTransform,
  580. m_configuration.m_cameraEntityId,
  581. &TransformBus::Events::GetWorldTM);
  582. }
  583. else
  584. {
  585. if (const auto& viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetDefaultViewportContext())
  586. {
  587. cameraTransform = viewportContext->GetCameraTransform();
  588. }
  589. }
  590. if (cameraTransform == m_lastCameraTransform)
  591. {
  592. return;
  593. }
  594. m_lastCameraTransform = cameraTransform;
  595. if (m_featureProcessor)
  596. {
  597. m_featureProcessor->SetCameraTransform(m_lightHandle, cameraTransform);
  598. }
  599. }
  600. void DirectionalLightComponentController::UpdateLightTransform()
  601. {
  602. auto lightTransform = Transform::CreateIdentity();
  603. TransformBus::EventResult(
  604. lightTransform,
  605. m_entityId,
  606. &TransformBus::Events::GetWorldTM);
  607. if (m_featureProcessor)
  608. {
  609. m_featureProcessor->SetDirection(m_lightHandle, lightTransform.GetBasisY());
  610. }
  611. }
  612. void DirectionalLightComponentController::ColorIntensityChanged()
  613. {
  614. m_photometricValue.SetChroma(m_configuration.m_color);
  615. m_photometricValue.SetIntensity(m_configuration.m_intensity);
  616. if (m_featureProcessor)
  617. {
  618. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<PhotometricUnit::Lux>());
  619. }
  620. }
  621. bool DirectionalLightComponentController::GetShadowReceiverPlaneBiasEnabled() const
  622. {
  623. return m_configuration.m_receiverPlaneBiasEnabled;
  624. }
  625. void DirectionalLightComponentController::SetShadowReceiverPlaneBiasEnabled(bool enable)
  626. {
  627. m_configuration.m_receiverPlaneBiasEnabled = enable;
  628. m_featureProcessor->SetShadowReceiverPlaneBiasEnabled(m_lightHandle, enable);
  629. }
  630. bool DirectionalLightComponentController::GetCascadeBlendingEnabled() const
  631. {
  632. return m_configuration.m_cascadeBlendingEnabled;
  633. }
  634. void DirectionalLightComponentController::SetCascadeBlendingEnabled(bool enable)
  635. {
  636. m_configuration.m_cascadeBlendingEnabled = enable;
  637. m_featureProcessor->SetCascadeBlendingEnabled(m_lightHandle, enable);
  638. }
  639. } // namespace Render
  640. } // namespace AZ