RayTracingIntersectionShaderExampleComponent.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 <RayTracingIntersectionShaderExampleComponent.h>
  9. #include <Atom/Bootstrap/BootstrapNotificationBus.h>
  10. #include <Atom/Component/DebugCamera/ArcBallControllerComponent.h>
  11. #include <Atom/Feature/SpecularReflections/SpecularReflectionsFeatureProcessorInterface.h>
  12. #include <Atom/RPI.Public/Scene.h>
  13. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  14. #include <AzCore/Math/Random.h>
  15. #include <AzFramework/Components/TransformComponent.h>
  16. #include <DebugDraw/DebugDrawBus.h>
  17. #include <EntityUtilityFunctions.h>
  18. namespace AtomSampleViewer
  19. {
  20. using namespace AZ;
  21. namespace
  22. {
  23. struct UniformRandomFloat
  24. {
  25. SimpleLcgRandom m_rng;
  26. float m_min;
  27. float m_max;
  28. UniformRandomFloat(SimpleLcgRandom& rng, float min, float max)
  29. : m_rng(rng)
  30. , m_min(min)
  31. , m_max(max)
  32. {
  33. }
  34. float operator()()
  35. {
  36. return m_rng.GetRandomFloat() * (m_max - m_min) + m_min;
  37. }
  38. };
  39. } // namespace
  40. static const char* PlaneMeshPath{ "objects/plane.fbx.azmodel" };
  41. static const char* MirrorMaterialPath{ "materials/SSRExample/GroundPlaneMirror.azmaterial" };
  42. static const float DefaultCameraHeadingDegrees{ 93.f };
  43. static const float DefaultCameraPitchDegrees{ -30.f };
  44. static const float DefaultCameraDistance{ 10.0f };
  45. static const Vector3 DefaultCameraPan{ 0.8f, -0.4f, -1.f };
  46. void RayTracingIntersectionShaderExampleComponent::Reflect(AZ::ReflectContext* context)
  47. {
  48. if (AZ::SerializeContext * serializeContext{ azrtti_cast<AZ::SerializeContext*>(context) })
  49. {
  50. serializeContext->Class<RayTracingIntersectionShaderExampleComponent, AZ::Component>()->Version(0);
  51. }
  52. }
  53. void RayTracingIntersectionShaderExampleComponent::Activate()
  54. {
  55. m_mirrorplaneModelAsset =
  56. RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(PlaneMeshPath, RPI::AssetUtils::TraceLevel::Assert);
  57. m_mirrorMaterialAsset =
  58. RPI::AssetUtils::GetAssetByProductPath<RPI::MaterialAsset>(MirrorMaterialPath, RPI::AssetUtils::TraceLevel::Assert);
  59. m_mirrorMaterialInstance = RPI::Material::Create(m_mirrorMaterialAsset);
  60. m_mirrorplaneMeshHandle =
  61. GetMeshFeatureProcessor()->AcquireMesh(Render::MeshHandleDescriptor(m_mirrorplaneModelAsset, m_mirrorMaterialInstance));
  62. GetMeshFeatureProcessor()->SetTransform(
  63. m_mirrorplaneMeshHandle, Transform{ Vector3{ 0, 0, -1 }, Quaternion::CreateIdentity(), 14 });
  64. Debug::CameraControllerRequestBus::Event(
  65. GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Enable, azrtti_typeid<Debug::ArcBallControllerComponent>());
  66. using ArcBallBus = Debug::ArcBallControllerRequestBus;
  67. ArcBallBus::Event(GetCameraEntityId(), &ArcBallBus::Events::SetDistance, DefaultCameraDistance);
  68. ArcBallBus::Event(GetCameraEntityId(), &ArcBallBus::Events::SetHeading, DegToRad(DefaultCameraHeadingDegrees));
  69. ArcBallBus::Event(GetCameraEntityId(), &ArcBallBus::Events::SetPitch, DegToRad(DefaultCameraPitchDegrees));
  70. ArcBallBus::Event(GetCameraEntityId(), &ArcBallBus::Events::SetPan, DefaultCameraPan);
  71. InitLightingPresets(true);
  72. SimpleLcgRandom rng;
  73. UniformRandomFloat sphereRadiusRng{ rng, 0.2f, 0.8f };
  74. UniformRandomFloat obbSizeRng{ rng, 0.2f, 0.6f };
  75. UniformRandomFloat obbRotationRng{ rng, 0.f, Constants::TwoPi };
  76. for (int i{ 0 }; i < 100; i++)
  77. {
  78. float x{ aznumeric_cast<float>(i % 10) - 5 };
  79. float y{ aznumeric_cast<float>(i / 10) - 5 };
  80. Entity* entity{ CreateEntity(AZStd::string::format("Procedural mesh %i", i), GetEntityContextId()) };
  81. Component* transformComponent{ nullptr };
  82. ComponentDescriptorBus::EventResult(
  83. transformComponent, azrtti_typeid<AzFramework::TransformComponent>(), &ComponentDescriptorBus::Events::CreateComponent);
  84. azrtti_cast<AzFramework::TransformComponent*>(transformComponent)->SetLocalTM(Transform::CreateTranslation(Vector3{ x, y, 0 }));
  85. entity->AddComponent(transformComponent);
  86. Color color{ rng.GetRandomFloat(), rng.GetRandomFloat(), rng.GetRandomFloat(), 1.f };
  87. bool drawSphere{ rng.GetRandomFloat() < 0.5f };
  88. if (drawSphere)
  89. {
  90. float sphereRadius{ sphereRadiusRng() };
  91. DebugDraw::DebugDrawRequestBus::Broadcast(
  92. &DebugDraw::DebugDrawRequests::DrawSphereOnEntity, entity->GetId(), sphereRadius, color, true, -1.f);
  93. }
  94. else // Draw obb
  95. {
  96. Obb obb{ Obb::CreateFromPositionRotationAndHalfLengths(
  97. Vector3{ x, y, 0 }, Quaternion::CreateRotationX(obbRotationRng()) * Quaternion::CreateRotationY(obbRotationRng()),
  98. AZ::Vector3{ obbSizeRng(), obbSizeRng(), obbSizeRng() }) };
  99. DebugDraw::DebugDrawRequestBus::Broadcast(
  100. &DebugDraw::DebugDrawRequests::DrawObbOnEntity, entity->GetId(), obb, color, true, -1.f);
  101. }
  102. DebugDraw::DebugDrawInternalRequestBus::Broadcast(
  103. &DebugDraw::DebugDrawInternalRequestBus::Events::RegisterDebugDrawComponent, transformComponent);
  104. entity->Activate();
  105. m_entities.push_back(entity);
  106. }
  107. Render::SpecularReflectionsFeatureProcessorInterface* specularReflectionsFeatureProcessor{
  108. m_scene->GetFeatureProcessorForEntityContextId<Render::SpecularReflectionsFeatureProcessorInterface>(GetEntityContextId())
  109. };
  110. AZ_Assert(specularReflectionsFeatureProcessor, "SpecularReflectionsFeatureProcessor not available.");
  111. Render::SSROptions ssrOptions;
  112. ssrOptions.m_enable = true;
  113. ssrOptions.m_reflectionMethod = Render::SSROptions::ReflectionMethod::RayTracing;
  114. ssrOptions.m_temporalFiltering = false;
  115. specularReflectionsFeatureProcessor->SetSSROptions(ssrOptions);
  116. Render::Bootstrap::NotificationBus::Broadcast(&Render::Bootstrap::NotificationBus::Handler::OnBootstrapSceneReady, m_scene);
  117. };
  118. void RayTracingIntersectionShaderExampleComponent::Deactivate()
  119. {
  120. GetMeshFeatureProcessor()->ReleaseMesh(m_mirrorplaneMeshHandle);
  121. for (Entity* entity : m_entities)
  122. {
  123. DestroyEntity(entity);
  124. }
  125. Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Disable);
  126. }
  127. } // namespace AtomSampleViewer