SimpleSpotLightDelegate.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
  23. GetFeatureProcessor()->SetDirection(GetLightHandle(), GetTransform().GetBasisZ());
  24. }
  25. }
  26. float SimpleSpotLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
  27. {
  28. // Calculate the radius at which the irradiance will be equal to cutoffIntensity.
  29. float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
  30. return Sqrt(intensity / lightThreshold);
  31. }
  32. float SimpleSpotLightDelegate::GetSurfaceArea() const
  33. {
  34. return 0.0f;
  35. }
  36. void SimpleSpotLightDelegate::SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees)
  37. {
  38. if (GetLightHandle().IsValid())
  39. {
  40. GetFeatureProcessor()->SetConeAngles(GetLightHandle(), DegToRad(innerAngleDegrees), DegToRad(outerAngleDegrees));
  41. }
  42. }
  43. SimpleSpotLightDelegate::ConeVisualizationDimensions SimpleSpotLightDelegate::CalculateConeVisualizationDimensions(
  44. const float degrees) const
  45. {
  46. const float attenuationRadius = GetConfig()->m_attenuationRadius;
  47. const float shutterAngleRadians = DegToRad(degrees);
  48. const float coneRadius = Sin(shutterAngleRadians) * attenuationRadius;
  49. const float coneHeight = Cos(shutterAngleRadians) * attenuationRadius;
  50. return ConeVisualizationDimensions{ coneRadius, coneHeight };
  51. }
  52. void SimpleSpotLightDelegate::DrawDebugDisplay(
  53. const Transform& transform,
  54. [[maybe_unused]] const Color& color,
  55. AzFramework::DebugDisplayRequests& debugDisplay,
  56. [[maybe_unused]] bool isSelected) const
  57. {
  58. // Draw a cone using the cone angle and attenuation radius
  59. auto DrawCone = [&debugDisplay](uint32_t numRadiusLines, float radius, float height, const Color& color, float brightness)
  60. {
  61. const Color displayColor = Color(color.GetAsVector3() * brightness);
  62. debugDisplay.SetColor(displayColor);
  63. debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), radius);
  64. for (uint32_t i = 0; i < numRadiusLines; ++i)
  65. {
  66. float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
  67. debugDisplay.DrawLine(Vector3::CreateZero(), Vector3(Cos(radiusLineAngle) * radius, Sin(radiusLineAngle) * radius, height));
  68. }
  69. };
  70. debugDisplay.PushMatrix(transform);
  71. const auto innerCone =
  72. CalculateConeVisualizationDimensions(GetMin(GetConfig()->m_innerShutterAngleDegrees, GetConfig()->m_outerShutterAngleDegrees));
  73. const auto outerCone = CalculateConeVisualizationDimensions(GetConfig()->m_outerShutterAngleDegrees);
  74. const Color coneColor = isSelected ? Color::CreateOne() : Color(0.0f, 0.75f, 0.75f, 1.0f);
  75. DrawCone(16, innerCone.m_radius, innerCone.m_height, coneColor, 1.0f);
  76. DrawCone(16, outerCone.m_radius, outerCone.m_height, coneColor, 0.75f);
  77. debugDisplay.PopMatrix();
  78. }
  79. void SimpleSpotLightDelegate::SetAffectsGI(bool affectsGI)
  80. {
  81. if (GetLightHandle().IsValid())
  82. {
  83. GetFeatureProcessor()->SetAffectsGI(GetLightHandle(), affectsGI);
  84. }
  85. }
  86. void SimpleSpotLightDelegate::SetAffectsGIFactor(float affectsGIFactor)
  87. {
  88. if (GetLightHandle().IsValid())
  89. {
  90. GetFeatureProcessor()->SetAffectsGIFactor(GetLightHandle(), affectsGIFactor);
  91. }
  92. }
  93. Aabb SimpleSpotLightDelegate::GetLocalVisualizationBounds() const
  94. {
  95. const auto [radius, height] = [this]
  96. {
  97. const auto [innerRadius, innerHeight] = CalculateConeVisualizationDimensions(
  98. GetMin(GetConfig()->m_outerShutterAngleDegrees, GetConfig()->m_innerShutterAngleDegrees));
  99. const auto [outerRadius, outerHeight] = CalculateConeVisualizationDimensions(GetConfig()->m_outerShutterAngleDegrees);
  100. return AZStd::pair{ GetMax(innerRadius, outerRadius), GetMax(innerHeight, outerHeight) };
  101. }();
  102. return Aabb::CreateFromMinMax(Vector3(-radius, -radius, 0.0f), Vector3(radius, radius, height));
  103. }
  104. } // namespace AZ::Render