TransparencyExampleComponent.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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.fbx.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. AZ::TickBus::Handler::BusDisconnect();
  64. }
  65. void TransparencyExampleComponent::OnTick(float deltaTime, AZ::ScriptTimePoint scriptTime)
  66. {
  67. AZ_UNUSED(deltaTime);
  68. AZ_UNUSED(scriptTime);
  69. if (m_waitingForMeshes)
  70. {
  71. if (m_loadedMeshCounter == m_meshHandles.size())
  72. {
  73. static const AZ::Color colors[] = {
  74. AZ::Colors::White,
  75. AZ::Colors::Brown,
  76. AZ::Colors::Red,
  77. AZ::Colors::Orange,
  78. AZ::Colors::Yellow,
  79. AZ::Colors::Green,
  80. AZ::Colors::Blue,
  81. AZ::Colors::Indigo,
  82. AZ::Colors::Purple,
  83. AZ::Colors::White
  84. };
  85. AZ::RPI::MaterialPropertyIndex colorProperty = m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(AZ::Name(ColorPropertyName));
  86. uint32_t numMaterialsCompiled = 0;
  87. for (int i = 0; i < NumOfMeshes; ++i)
  88. {
  89. for (auto& customMaterial : GetMeshFeatureProcessor()->GetCustomMaterials(m_meshHandles[i]))
  90. {
  91. if (AZ::Data::Instance<AZ::RPI::Material> material = customMaterial.second.m_material)
  92. {
  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. }
  106. }
  107. // 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.
  108. if (numMaterialsCompiled == NumOfMeshes)
  109. {
  110. m_waitingForMeshes = false;
  111. ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::ResumeScript);
  112. }
  113. }
  114. }
  115. }
  116. void TransparencyExampleComponent::LoadMesh(AZ::Transform transform)
  117. {
  118. auto materialInstance = AZ::RPI::Material::Create(m_materialAsset);
  119. AZ::Render::MeshHandleDescriptor descriptor(m_modelAsset, materialInstance);
  120. descriptor.m_modelChangedEventHandler =
  121. AZ::Render::MeshHandleDescriptor::ModelChangedEvent::Handler{ [this](const AZ::Data::Instance<AZ::RPI::Model>& /*model*/)
  122. {
  123. m_loadedMeshCounter++;
  124. } };
  125. AZ::Render::MeshFeatureProcessorInterface::MeshHandle meshHandle = GetMeshFeatureProcessor()->AcquireMesh(descriptor);
  126. GetMeshFeatureProcessor()->SetTransform(meshHandle, transform);
  127. m_meshHandles.push_back(std::move(meshHandle));
  128. }
  129. void TransparencyExampleComponent::Prepare()
  130. {
  131. // Camera
  132. AZ::Debug::CameraControllerRequestBus::Event(
  133. GetCameraEntityId(),
  134. &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  135. azrtti_typeid<AZ::Debug::ArcBallControllerComponent>());
  136. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetDistance, DefaultCameraDistance);
  137. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetHeading, DefaultCameraHeading);
  138. AZ::Debug::ArcBallControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::ArcBallControllerRequestBus::Events::SetPitch, DefaultCameraPitch);
  139. // Lighting
  140. m_defaultIbl.Init(m_scene);
  141. // Model
  142. m_modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>(MeshPath, AZ::RPI::AssetUtils::TraceLevel::Assert);
  143. // Material
  144. m_materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>(MaterialPath, AZ::RPI::AssetUtils::TraceLevel::Assert);
  145. }
  146. }