TransparencyExampleComponent.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 <TransparencyExampleComponent.h>
  9. #include <Atom/Component/DebugCamera/ArcBallControllerComponent.h>
  10. #include <Atom/RPI.Public/RPISystemInterface.h>
  11. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  12. #include <Automation/ScriptRunnerBus.h>
  13. #include <RHI/BasicRHIComponent.h>
  14. namespace AtomSampleViewer
  15. {
  16. static const int NumOfMeshes = 10;
  17. static const float MeshSpacing = 1.0f;
  18. static const char* MeshPath = "objects/plane.azmodel";
  19. static const char* MaterialPath = "materials/transparentdoubleside.azmaterial";
  20. static const char* ColorPropertyName = "baseColor.color";
  21. static const float DefaultCameraDistance = 2.0f;
  22. static const float DefaultCameraHeading = AZ::DegToRad(30.0f);
  23. static const float DefaultCameraPitch = AZ::DegToRad(-30.0f);
  24. void TransparencyExampleComponent::Reflect(AZ::ReflectContext* context)
  25. {
  26. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  27. {
  28. serializeContext->Class<TransparencyExampleComponent, AZ::Component>()->Version(0);
  29. }
  30. }
  31. TransparencyExampleComponent::TransparencyExampleComponent()
  32. {
  33. }
  34. void TransparencyExampleComponent::Activate()
  35. {
  36. Prepare();
  37. // Mesh
  38. for (int i = 0; i < NumOfMeshes; ++i)
  39. {
  40. AZ::Transform transform = AZ::Transform::CreateRotationX(AZ::Constants::HalfPi);
  41. float pos = i / (NumOfMeshes - 1.0f); // range [0,1]
  42. pos = pos - 0.5f; // range [-0.5,0.5]
  43. pos *= MeshSpacing; // spaced out around 0
  44. transform.SetTranslation(AZ::Vector3(0, pos, 0));
  45. LoadMesh(transform);
  46. }
  47. // Give the models time to load before continuing scripts
  48. ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::PauseScript);
  49. m_waitingForMeshes = true;
  50. AZ::TickBus::Handler::BusConnect();
  51. }
  52. void TransparencyExampleComponent::Deactivate()
  53. {
  54. AZ::Debug::CameraControllerRequestBus::Event(
  55. GetCameraEntityId(),
  56. &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  57. m_defaultIbl.Reset();
  58. for (auto& meshHandle : m_meshHandles)
  59. {
  60. GetMeshFeatureProcessor()->ReleaseMesh(meshHandle);
  61. }
  62. m_meshHandles.clear();
  63. m_meshLoadEventHandlers.clear();
  64. AZ::TickBus::Handler::BusDisconnect();
  65. }
  66. void TransparencyExampleComponent::OnTick(float deltaTime, AZ::ScriptTimePoint scriptTime)
  67. {
  68. AZ_UNUSED(deltaTime);
  69. AZ_UNUSED(scriptTime);
  70. if (m_waitingForMeshes)
  71. {
  72. if (m_loadedMeshCounter == m_meshHandles.size())
  73. {
  74. static const AZ::Color colors[] = {
  75. AZ::Colors::White,
  76. AZ::Colors::Brown,
  77. AZ::Colors::Red,
  78. AZ::Colors::Orange,
  79. AZ::Colors::Yellow,
  80. AZ::Colors::Green,
  81. AZ::Colors::Blue,
  82. AZ::Colors::Indigo,
  83. AZ::Colors::Purple,
  84. AZ::Colors::White
  85. };
  86. AZ::RPI::MaterialPropertyIndex colorProperty = m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(AZ::Name(ColorPropertyName));
  87. uint32_t numMaterialsCompiled = 0;
  88. for (int i = 0; i < NumOfMeshes; ++i)
  89. {
  90. const AZ::Render::MaterialAssignmentMap& materials = GetMeshFeatureProcessor()->GetMaterialAssignmentMap(m_meshHandles[i]);
  91. const AZ::Render::MaterialAssignment defaultMaterial = AZ::Render::GetMaterialAssignmentFromMap(materials, AZ::Render::DefaultMaterialAssignmentId);
  92. AZ::Data::Instance<AZ::RPI::Material> material = defaultMaterial.m_materialInstance;
  93. material->SetPropertyValue(colorProperty, colors[i]);
  94. if (material->NeedsCompile())
  95. {
  96. bool thisMaterialsCompiled = material->Compile();
  97. numMaterialsCompiled += uint32_t(thisMaterialsCompiled);
  98. }
  99. else
  100. {
  101. // Material already compiled
  102. ++numMaterialsCompiled;
  103. }
  104. }
  105. // If all the materials didn't compile, then try again next tick. This can happen if material properties are set on the same frame as the material initialized.
  106. if (numMaterialsCompiled == NumOfMeshes)
  107. {
  108. m_waitingForMeshes = false;
  109. ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::ResumeScript);
  110. }
  111. }
  112. }
  113. }
  114. void TransparencyExampleComponent::LoadMesh(AZ::Transform transform)
  115. {
  116. AZ::Render::MaterialAssignmentMap materialMap;
  117. AZ::Render::MaterialAssignment& defaultMaterial = materialMap[AZ::Render::DefaultMaterialAssignmentId];
  118. defaultMaterial.m_materialAsset = m_materialAsset;
  119. defaultMaterial.m_materialInstance = AZ::RPI::Material::Create(m_materialAsset);
  120. AZ::Render::MeshFeatureProcessorInterface::MeshHandle meshHandle = GetMeshFeatureProcessor()->AcquireMesh(AZ::Render::MeshHandleDescriptor{ m_modelAsset }, materialMap);
  121. GetMeshFeatureProcessor()->SetTransform(meshHandle, transform);
  122. AZ::Data::Instance<AZ::RPI::Model> model = GetMeshFeatureProcessor()->GetModel(meshHandle);
  123. if (model)
  124. {
  125. m_loadedMeshCounter++;
  126. }
  127. else
  128. {
  129. m_meshLoadEventHandlers.push_back(AZ::Render::MeshFeatureProcessorInterface::ModelChangedEvent::Handler
  130. {
  131. [this](AZ::Data::Instance<AZ::RPI::Model> model) { m_loadedMeshCounter++; }
  132. });
  133. GetMeshFeatureProcessor()->ConnectModelChangeEventHandler(meshHandle, m_meshLoadEventHandlers.back());
  134. }
  135. m_meshHandles.push_back(std::move(meshHandle));
  136. }
  137. void TransparencyExampleComponent::Prepare()
  138. {
  139. // Camera
  140. AZ::Debug::CameraControllerRequestBus::Event(
  141. GetCameraEntityId(),
  142. &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  143. azrtti_typeid<AZ::Debug::ArcBallControllerComponent>());
  144. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetDistance, DefaultCameraDistance);
  145. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetHeading, DefaultCameraHeading);
  146. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetPitch, DefaultCameraPitch);
  147. // Lighting
  148. m_defaultIbl.Init(m_scene);
  149. // Model
  150. m_modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>(MeshPath, AZ::RPI::AssetUtils::TraceLevel::Assert);
  151. // Material
  152. m_materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>(MaterialPath, AZ::RPI::AssetUtils::TraceLevel::Assert);
  153. }
  154. }