SimpleSpotLightDelegate.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 <Atom/RPI.Public/Scene.h>
  9. #include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
  10. #include <CoreLights/SimpleSpotLightDelegate.h>
  11. namespace AZ::Render
  12. {
  13. SimpleSpotLightDelegate::SimpleSpotLightDelegate(EntityId entityId, bool isVisible)
  14. : LightDelegateBase<SimpleSpotLightFeatureProcessorInterface>(entityId, isVisible)
  15. {
  16. InitBase(entityId);
  17. }
  18. void SimpleSpotLightDelegate::HandleShapeChanged()
  19. {
  20. if (GetLightHandle().IsValid())
  21. {
  22. GetFeatureProcessor()->SetTransform(GetLightHandle(), GetTransform());
  23. }
  24. }
  25. float SimpleSpotLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
  26. {
  27. // Calculate the radius at which the irradiance will be equal to cutoffIntensity.
  28. float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
  29. return Sqrt(intensity / lightThreshold);
  30. }
  31. float SimpleSpotLightDelegate::GetSurfaceArea() const
  32. {
  33. return 0.0f;
  34. }
  35. void SimpleSpotLightDelegate::SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees)
  36. {
  37. if (GetLightHandle().IsValid())
  38. {
  39. GetFeatureProcessor()->SetConeAngles(GetLightHandle(), DegToRad(innerAngleDegrees), DegToRad(outerAngleDegrees));
  40. }
  41. }
  42. SimpleSpotLightDelegate::ConeVisualizationDimensions SimpleSpotLightDelegate::CalculateConeVisualizationDimensions(
  43. const float degrees) const
  44. {
  45. const float attenuationRadius = GetConfig()->m_attenuationRadius;
  46. const float shutterAngleRadians = DegToRad(degrees);
  47. const float coneRadius = Sin(shutterAngleRadians) * attenuationRadius;
  48. const float coneHeight = Cos(shutterAngleRadians) * attenuationRadius;
  49. return ConeVisualizationDimensions{ coneRadius, coneHeight };
  50. }
  51. void SimpleSpotLightDelegate::DrawDebugDisplay(
  52. const Transform& transform,
  53. [[maybe_unused]] const Color& color,
  54. AzFramework::DebugDisplayRequests& debugDisplay,
  55. [[maybe_unused]] bool isSelected) const
  56. {
  57. // Draw a cone using the cone angle and attenuation radius
  58. auto DrawCone = [&debugDisplay](uint32_t numRadiusLines, float radius, float height, const Color& color, float brightness)
  59. {
  60. const Color displayColor = Color(color.GetAsVector3() * brightness);
  61. debugDisplay.SetColor(displayColor);
  62. debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), radius);
  63. for (uint32_t i = 0; i < numRadiusLines; ++i)
  64. {
  65. float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
  66. debugDisplay.DrawLine(Vector3::CreateZero(), Vector3(Cos(radiusLineAngle) * radius, Sin(radiusLineAngle) * radius, height));
  67. }
  68. };
  69. debugDisplay.PushMatrix(transform);
  70. const auto innerCone =
  71. CalculateConeVisualizationDimensions(GetMin(GetConfig()->m_innerShutterAngleDegrees, GetConfig()->m_outerShutterAngleDegrees));
  72. const auto outerCone = CalculateConeVisualizationDimensions(GetConfig()->m_outerShutterAngleDegrees);
  73. const Color coneColor = isSelected ? Color::CreateOne() : Color(0.0f, 0.75f, 0.75f, 1.0f);
  74. DrawCone(16, innerCone.m_radius, innerCone.m_height, coneColor, 1.0f);
  75. DrawCone(16, outerCone.m_radius, outerCone.m_height, coneColor, 0.75f);
  76. debugDisplay.PopMatrix();
  77. }
  78. void SimpleSpotLightDelegate::SetAffectsGI(bool affectsGI)
  79. {
  80. if (GetLightHandle().IsValid())
  81. {
  82. GetFeatureProcessor()->SetAffectsGI(GetLightHandle(), affectsGI);
  83. }
  84. }
  85. void SimpleSpotLightDelegate::SetAffectsGIFactor(float affectsGIFactor)
  86. {
  87. if (GetLightHandle().IsValid())
  88. {
  89. GetFeatureProcessor()->SetAffectsGIFactor(GetLightHandle(), affectsGIFactor);
  90. }
  91. }
  92. Aabb SimpleSpotLightDelegate::GetLocalVisualizationBounds() const
  93. {
  94. const auto [radius, height] = [this]
  95. {
  96. const auto [innerRadius, innerHeight] = CalculateConeVisualizationDimensions(
  97. GetMin(GetConfig()->m_outerShutterAngleDegrees, GetConfig()->m_innerShutterAngleDegrees));
  98. const auto [outerRadius, outerHeight] = CalculateConeVisualizationDimensions(GetConfig()->m_outerShutterAngleDegrees);
  99. return AZStd::pair{ GetMax(innerRadius, outerRadius), GetMax(innerHeight, outerHeight) };
  100. }();
  101. return Aabb::CreateFromMinMax(Vector3(-radius, -radius, 0.0f), Vector3(radius, radius, height));
  102. }
  103. void SimpleSpotLightDelegate::SetEnableShadow(bool enabled)
  104. {
  105. Base::SetEnableShadow(enabled);
  106. if (GetLightHandle().IsValid())
  107. {
  108. GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled);
  109. }
  110. }
  111. void SimpleSpotLightDelegate::SetShadowBias(float bias)
  112. {
  113. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  114. {
  115. GetFeatureProcessor()->SetShadowBias(GetLightHandle(), bias);
  116. }
  117. }
  118. void SimpleSpotLightDelegate::SetNormalShadowBias(float bias)
  119. {
  120. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  121. {
  122. GetFeatureProcessor()->SetNormalShadowBias(GetLightHandle(), bias);
  123. }
  124. }
  125. void SimpleSpotLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
  126. {
  127. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  128. {
  129. GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size);
  130. }
  131. }
  132. void SimpleSpotLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method)
  133. {
  134. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  135. {
  136. GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method);
  137. }
  138. }
  139. void SimpleSpotLightDelegate::SetFilteringSampleCount(uint32_t count)
  140. {
  141. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  142. {
  143. GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), static_cast<uint16_t>(count));
  144. }
  145. }
  146. void SimpleSpotLightDelegate::SetEsmExponent(float exponent)
  147. {
  148. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  149. {
  150. GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), exponent);
  151. }
  152. }
  153. void SimpleSpotLightDelegate::SetShadowCachingMode(AreaLightComponentConfig::ShadowCachingMode cachingMode)
  154. {
  155. if (GetShadowsEnabled() && GetLightHandle().IsValid())
  156. {
  157. GetFeatureProcessor()->SetUseCachedShadows(
  158. GetLightHandle(), cachingMode == AreaLightComponentConfig::ShadowCachingMode::UpdateOnChange);
  159. }
  160. }
  161. void SimpleSpotLightDelegate::SetGoboTexture(AZ::Data::Instance<AZ::RPI::Image> goboTexture)
  162. {
  163. if (GetLightHandle().IsValid())
  164. {
  165. GetFeatureProcessor()->SetGoboTexture(GetLightHandle(), goboTexture);
  166. }
  167. }
  168. } // namespace AZ::Render