MultipleViewsComponent.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  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 <RHI/MultipleViewsComponent.h>
  9. #include <AzCore/Math/MatrixUtils.h>
  10. #include <Atom/RHI/BufferPool.h>
  11. #include <Atom/RHI/Factory.h>
  12. #include <Atom/RHI/FrameAttachment.h>
  13. #include <Atom/RHI.Reflect/InputStreamLayoutBuilder.h>
  14. #include <Atom/RHI.Reflect/RenderAttachmentLayoutBuilder.h>
  15. #include <Atom/RPI.Public/Image/AttachmentImagePool.h>
  16. #include <Atom/RPI.Public/Shader/Shader.h>
  17. #include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
  18. #include <SampleComponentManager.h>
  19. #include <Utils/Utils.h>
  20. namespace AtomSampleViewer
  21. {
  22. namespace ShaderInputs
  23. {
  24. static const char* const ShaderInputImageWorldMatrix{ "m_worldMatrix" };
  25. static const char* const ShaderInputImageViewProjectionMatrix{ "m_viewProjectionMatrix" };
  26. static const char* const ShaderInputImageLightViewProjectionMatrix{ "m_lightViewProjectionMatrix" };
  27. static const char* const ShaderInputImageLightPosition{ "m_lightPosition" };
  28. static const char* const ShaderInputImageAmbientColor{ "m_ambientColor" };
  29. static const char* const ShaderInputImageDiffuseColor{ "m_diffuseColor" };
  30. static const char* const ShaderInputImageDepthMapTexture{ "m_depthMapTexture" };
  31. }
  32. const AZ::Vector3 MultipleViewsComponent::m_up = AZ::Vector3(0.0f, 1.0f, 0.0f);
  33. const AZ::Vector3 MultipleViewsComponent::m_lookAt = AZ::Vector3(0.0f, 0.0f, 0.0f);
  34. void MultipleViewsComponent::Reflect(AZ::ReflectContext* context)
  35. {
  36. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  37. {
  38. serializeContext->Class<MultipleViewsComponent, AZ::Component>()
  39. ->Version(0)
  40. ;
  41. }
  42. }
  43. MultipleViewsComponent::MultipleViewsComponent()
  44. {
  45. m_depthMapID = AZ::RHI::AttachmentId("DepthMapAttachmentID");
  46. m_depthStencilID = AZ::RHI::AttachmentId{ "DepthStencilID" };
  47. m_depthClearValue = AZ::RHI::ClearValue::CreateDepthStencil(1.0f, 0);
  48. m_supportRHISamplePipeline = true;
  49. }
  50. void MultipleViewsComponent::OnFramePrepare(AZ::RHI::FrameGraphBuilder& frameGraphBuilder)
  51. {
  52. static float time = 0.0f;
  53. time += 0.005f;
  54. //Update light position and light view matrix
  55. m_lightPosition.SetX(12.0f*cosf(time));
  56. m_lightPosition.SetZ(12.0f*sinf(time));
  57. m_lightViewProjectionMatrix = m_lightProjectionMatrix * CreateViewMatrix(m_lightPosition.GetAsVector3(), m_up, m_lookAt);
  58. if (m_shaderResourceGroups[0])
  59. {
  60. m_shaderResourceGroups[0]->SetConstant(m_shaderInputConstantIndices[0], m_worldMatrix);
  61. m_shaderResourceGroups[0]->SetConstant(m_shaderInputConstantIndices[1], m_lightViewProjectionMatrix);
  62. m_shaderResourceGroups[0]->Compile();
  63. }
  64. if (m_shaderResourceGroups[1])
  65. {
  66. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[0], m_worldMatrix);
  67. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[1], m_viewProjectionMatrix);
  68. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[2], m_lightViewProjectionMatrix);
  69. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[3], m_lightPosition);
  70. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[4], m_ambientColor);
  71. m_shaderResourceGroups[1]->SetConstant(m_shaderInputConstantIndices[5], m_diffuseColor);
  72. }
  73. BasicRHIComponent::OnFramePrepare(frameGraphBuilder);
  74. }
  75. void MultipleViewsComponent::Activate()
  76. {
  77. CreateInputAssemblyBuffersAndViews();
  78. SetupScene();
  79. InitRenderTarget();
  80. ReadDepthShader();
  81. ReadMainShader();
  82. CreateDepthScope();
  83. CreateMainScope();
  84. AZ::RHI::RHISystemNotificationBus::Handler::BusConnect();
  85. }
  86. void MultipleViewsComponent::Deactivate()
  87. {
  88. AZ::RHI::RHISystemNotificationBus::Handler::BusDisconnect();
  89. m_windowContext = nullptr;
  90. m_bufferPool = nullptr;
  91. m_inputAssemblyBuffer = nullptr;
  92. m_shaderResourceGroups.fill(nullptr);
  93. m_pipelineStates.fill(nullptr);
  94. m_scopeProducers.clear();
  95. }
  96. void MultipleViewsComponent::SetupScene()
  97. {
  98. m_ambientColor = AZ::Vector4(0.15f, 0.15f, 0.15f, 1.0f);
  99. m_diffuseColor = AZ::Vector4(1.0f, 1.0f, 1.0f, 1.0f);
  100. // World
  101. float fieldOfView = AZ::Constants::Pi / 4.0f;
  102. float screenAspect = GetViewportWidth() / GetViewportHeight();
  103. m_worldPosition = AZ::Vector3(0.0f, 5.0f, 20.0f);
  104. m_worldMatrix = AZ::Matrix4x4::CreateIdentity();
  105. MakePerspectiveFovMatrixRH(m_viewProjectionMatrix, fieldOfView, screenAspect, m_zNear, m_zFar);
  106. m_viewProjectionMatrix = m_viewProjectionMatrix *CreateViewMatrix(m_worldPosition, m_up, m_lookAt);
  107. // Light
  108. float fovY = AZ::Constants::Pi / 2.0f;
  109. float aspectRatio = 1.0f;
  110. m_lightPosition = AZ::Vector4(-12.0, 8.0f, -12.0f, 1.0f);
  111. MakePerspectiveFovMatrixRH(m_lightProjectionMatrix, fovY, aspectRatio, m_zNear, m_zFar);
  112. m_lightViewProjectionMatrix = m_lightProjectionMatrix * CreateViewMatrix(m_lightPosition.GetAsVector3(), m_up, m_lookAt);
  113. }
  114. MultipleViewsComponent::BufferData MultipleViewsComponent::CreateBufferData()
  115. {
  116. // Create vertices, colors and normals for a cube and a plane
  117. BufferData bufferData;
  118. {
  119. AZStd::vector<AZ::Vector3> vertices =
  120. {
  121. //Front Face
  122. AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(1.0, -1.0, 1.0),
  123. //Back Face
  124. AZ::Vector3(1.0, 1.0, -1.0), AZ::Vector3(-1.0, 1.0, -1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(1.0, -1.0, -1.0),
  125. //Left Face
  126. AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(-1.0, 1.0, -1.0),
  127. //Right Face
  128. AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(1.0, -1.0, 1.0), AZ::Vector3(1.0, -1.0, -1.0), AZ::Vector3(1.0, 1.0, -1.0),
  129. //Top Face
  130. AZ::Vector3(1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, 1.0), AZ::Vector3(-1.0, 1.0, -1.0), AZ::Vector3(1.0, 1.0, -1.0),
  131. //Bottom Face
  132. AZ::Vector3(1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, 1.0), AZ::Vector3(-1.0, -1.0, -1.0), AZ::Vector3(1.0, -1.0, -1.0),
  133. //Plane
  134. AZ::Vector3(-10.0, -1.0, -10.0), AZ::Vector3(10.0, -1.0, -10.0), AZ::Vector3(10.0, -1.0, 10.0), AZ::Vector3(-10.0, -1.0, 10.0),
  135. };
  136. AZStd::vector<AZ::Vector4> colors =
  137. {
  138. //Front Face
  139. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  140. //Back Face
  141. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  142. //Left Face
  143. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  144. //Right Face
  145. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  146. //Top Face
  147. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  148. //Bottom Face
  149. AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0), AZ::Vector4(0.0, 0.0, 1.0, 1.0),
  150. //Plane
  151. AZ::Vector4(1.0, 0.0, 0.0, 1.0), AZ::Vector4(1.0, 0.0, 0.0, 1.0), AZ::Vector4(1.0, 0.0, 0.0, 1.0), AZ::Vector4(1.0, 0.0, 0.0, 1.0),
  152. };
  153. AZStd::vector<AZ::Vector3> normals =
  154. {
  155. //Front Face
  156. AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0), AZ::Vector3(0.0, 0.0, 1.0),
  157. //Back Face
  158. AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0), AZ::Vector3(0.0, 0.0,-1.0),
  159. //Left Face
  160. AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0), AZ::Vector3(-1.0, 0.0, 0.0),
  161. //Right Face
  162. AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0), AZ::Vector3(1.0, 0.0, 0.0),
  163. //Top Face
  164. AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0),
  165. //Bottom Face
  166. AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0), AZ::Vector3(0.0, -1.0, 0.0),
  167. //Plane
  168. AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0), AZ::Vector3(0.0, 1.0, 0.0),
  169. };
  170. for (int i = 0; i < geometryVertexCount; ++i)
  171. {
  172. SetVertexPosition(bufferData.m_positions.data(), i, vertices[i]);
  173. SetVertexColor(bufferData.m_colors.data(), i, colors[i]);
  174. SetVertexNormal(bufferData.m_normals.data(), i, normals[i]);
  175. }
  176. bufferData.m_indices =
  177. {
  178. {
  179. //Back
  180. 2, 0, 1,
  181. 0, 2, 3,
  182. //Front
  183. 4, 6, 5,
  184. 6, 4, 7,
  185. //Left
  186. 8, 10, 9,
  187. 10, 8, 11,
  188. //Right
  189. 14, 12, 13,
  190. 15, 12, 14,
  191. //Top
  192. 16, 18, 17,
  193. 18, 16, 19,
  194. //Bottom
  195. 22, 20, 21,
  196. 23, 20, 22,
  197. //Plane Top
  198. 24, 26, 25,
  199. 26, 24, 27,
  200. }
  201. };
  202. }
  203. return bufferData;
  204. }
  205. void MultipleViewsComponent::CreateInputAssemblyBuffersAndViews()
  206. {
  207. using namespace AZ;
  208. const AZ::RHI::Ptr<AZ::RHI::Device> device = Utils::GetRHIDevice();
  209. m_bufferPool = aznew AZ::RHI::BufferPool();
  210. AZ::RHI::BufferPoolDescriptor bufferPoolDesc;
  211. bufferPoolDesc.m_bindFlags = AZ::RHI::BufferBindFlags::InputAssembly;
  212. bufferPoolDesc.m_heapMemoryLevel = AZ::RHI::HeapMemoryLevel::Device;
  213. m_bufferPool->Init(bufferPoolDesc);
  214. BufferData bufferData = CreateBufferData();
  215. m_inputAssemblyBuffer = aznew AZ::RHI::Buffer();
  216. AZ::RHI::ResultCode result = AZ::RHI::ResultCode::Success;
  217. AZ::RHI::BufferInitRequest request;
  218. request.m_buffer = m_inputAssemblyBuffer.get();
  219. request.m_descriptor = AZ::RHI::BufferDescriptor{ AZ::RHI::BufferBindFlags::InputAssembly, sizeof(bufferData) };
  220. request.m_initialData = &bufferData;
  221. result = m_bufferPool->InitBuffer(request);
  222. if (result != AZ::RHI::ResultCode::Success)
  223. {
  224. AZ_Error("MultipleViewsComponent", false, "Failed to initialize buffer with error code %d", result);
  225. return;
  226. }
  227. m_streamBufferViews[0] =
  228. {
  229. *m_inputAssemblyBuffer,
  230. offsetof(BufferData, m_positions),
  231. sizeof(BufferData::m_positions),
  232. sizeof(VertexPosition)
  233. };
  234. m_streamBufferViews[1] =
  235. {
  236. *m_inputAssemblyBuffer,
  237. offsetof(BufferData, m_colors),
  238. sizeof(BufferData::m_colors),
  239. sizeof(VertexColor)
  240. };
  241. m_streamBufferViews[2] =
  242. {
  243. *m_inputAssemblyBuffer,
  244. offsetof(BufferData, m_normals),
  245. sizeof(BufferData::m_normals),
  246. sizeof(VertexNormal)
  247. };
  248. m_indexBufferView =
  249. {
  250. *m_inputAssemblyBuffer,
  251. offsetof(BufferData, m_indices),
  252. sizeof(BufferData::m_indices),
  253. AZ::RHI::IndexFormat::Uint16
  254. };
  255. RHI::InputStreamLayoutBuilder layoutBuilder;
  256. layoutBuilder.AddBuffer()->Channel("POSITION", RHI::Format::R32G32B32_FLOAT);
  257. layoutBuilder.AddBuffer()->Channel("COLOR", RHI::Format::R32G32B32A32_FLOAT);
  258. layoutBuilder.AddBuffer()->Channel("NORMAL", RHI::Format::R32G32B32_FLOAT);
  259. m_inputStreamLayout = layoutBuilder.End();
  260. AZ::RHI::ValidateStreamBufferViews(m_inputStreamLayout, m_streamBufferViews);
  261. }
  262. void MultipleViewsComponent::InitRenderTarget()
  263. {
  264. const AZ::RHI::ImageDescriptor imageDescriptor = AZ::RHI::ImageDescriptor::Create2D(
  265. AZ::RHI::ImageBindFlags::DepthStencil | AZ::RHI::ImageBindFlags::ShaderRead,
  266. s_shadowMapSize,
  267. s_shadowMapSize,
  268. AZ::RHI::Format::D32_FLOAT);
  269. m_transientImageDescriptor = AZ::RHI::TransientImageDescriptor(m_depthMapID, imageDescriptor);
  270. }
  271. void MultipleViewsComponent::ReadDepthShader()
  272. {
  273. using namespace AZ;
  274. const char* depthShaderFilePath = "Shaders/RHI/MultipleViewsDepth.azshader";
  275. const char* sampleName = "MultipleViewsComponent";
  276. auto shader = LoadShader(depthShaderFilePath, sampleName);
  277. if (shader == nullptr)
  278. return;
  279. AZ::RHI::PipelineStateDescriptorForDraw pipelineDesc;
  280. shader->GetVariant(AZ::RPI::ShaderAsset::RootShaderVariantStableId).ConfigurePipelineState(pipelineDesc);
  281. pipelineDesc.m_inputStreamLayout = m_inputStreamLayout;
  282. pipelineDesc.m_renderStates.m_depthStencilState.m_depth.m_enable = 1;
  283. pipelineDesc.m_renderStates.m_depthStencilState.m_depth.m_func = AZ::RHI::ComparisonFunc::LessEqual;
  284. RHI::RenderAttachmentLayoutBuilder attachmentsBuilder;
  285. attachmentsBuilder.AddSubpass()
  286. ->DepthStencilAttachment(AZ::RHI::Format::D32_FLOAT);
  287. [[maybe_unused]] RHI::ResultCode result = attachmentsBuilder.End(pipelineDesc.m_renderAttachmentConfiguration.m_renderAttachmentLayout);
  288. AZ_Assert(result == RHI::ResultCode::Success, "Failed to create render attachment layout");
  289. m_pipelineStates[0] = shader->AcquirePipelineState(pipelineDesc);
  290. if (!m_pipelineStates[0])
  291. {
  292. AZ_Error(sampleName, false, "Failed to acquire default pipeline state for shader '%s'", depthShaderFilePath);
  293. return;
  294. }
  295. m_shaderResourceGroups[0] = CreateShaderResourceGroup(shader, "DepthViewSrg", sampleName);
  296. FindShaderInputIndex(&m_shaderInputConstantIndices[0], m_shaderResourceGroups[0], AZ::Name{ShaderInputs::ShaderInputImageWorldMatrix}, sampleName);
  297. FindShaderInputIndex(&m_shaderInputConstantIndices[1], m_shaderResourceGroups[0], AZ::Name{ShaderInputs::ShaderInputImageViewProjectionMatrix}, sampleName);
  298. }
  299. void MultipleViewsComponent::ReadMainShader()
  300. {
  301. const char* shadowShaderFilePath = "Shaders/RHI/MultipleViewsShadow.azshader";
  302. const char* sampleName = "MultipleViewsComponent";
  303. auto shader = LoadShader(shadowShaderFilePath, sampleName);
  304. if (shader == nullptr)
  305. return;
  306. AZ::RHI::PipelineStateDescriptorForDraw pipelineDesc;
  307. shader->GetVariant(AZ::RPI::ShaderAsset::RootShaderVariantStableId).ConfigurePipelineState(pipelineDesc);
  308. pipelineDesc.m_inputStreamLayout = m_inputStreamLayout;
  309. pipelineDesc.m_renderStates.m_depthStencilState.m_depth.m_enable = 1;
  310. pipelineDesc.m_renderStates.m_depthStencilState.m_depth.m_func = AZ::RHI::ComparisonFunc::LessEqual;
  311. AZ::RHI::Ptr<AZ::RHI::Device> device = Utils::GetRHIDevice();
  312. AZ::RHI::Format depthStencilFormat = device->GetNearestSupportedFormat(AZ::RHI::Format::D24_UNORM_S8_UINT, AZ::RHI::FormatCapabilities::DepthStencil);
  313. AZ::RHI::RenderAttachmentLayoutBuilder attachmentsBuilder;
  314. attachmentsBuilder.AddSubpass()
  315. ->RenderTargetAttachment(m_outputFormat)
  316. ->DepthStencilAttachment(depthStencilFormat);
  317. [[maybe_unused]] AZ::RHI::ResultCode result = attachmentsBuilder.End(pipelineDesc.m_renderAttachmentConfiguration.m_renderAttachmentLayout);
  318. AZ_Assert(result == AZ::RHI::ResultCode::Success, "Failed to create render attachment layout");
  319. m_pipelineStates[1] = shader->AcquirePipelineState(pipelineDesc);
  320. if (!m_pipelineStates[1])
  321. {
  322. AZ_Error(sampleName, false, "Failed to acquire default pipeline state for shader '%s'", shadowShaderFilePath);
  323. return;
  324. }
  325. m_shaderResourceGroups[1] = CreateShaderResourceGroup(shader, "ShadowViewSrg", sampleName);
  326. FindShaderInputIndex(&m_shaderInputConstantIndices[0], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageWorldMatrix}, sampleName);
  327. FindShaderInputIndex(&m_shaderInputConstantIndices[1], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageViewProjectionMatrix}, sampleName);
  328. FindShaderInputIndex(&m_shaderInputConstantIndices[2], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageLightViewProjectionMatrix}, sampleName);
  329. FindShaderInputIndex(&m_shaderInputConstantIndices[3], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageLightPosition}, sampleName);
  330. FindShaderInputIndex(&m_shaderInputConstantIndices[4], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageAmbientColor}, sampleName);
  331. FindShaderInputIndex(&m_shaderInputConstantIndices[5], m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageDiffuseColor}, sampleName);
  332. FindShaderInputIndex(&m_shaderInputImageIndex, m_shaderResourceGroups[1], AZ::Name{ShaderInputs::ShaderInputImageDepthMapTexture}, sampleName);
  333. }
  334. void MultipleViewsComponent::CreateDepthScope()
  335. {
  336. const auto prepareFunctionLightView = [this](AZ::RHI::FrameGraphInterface frameGraph, [[maybe_unused]] ScopeData& scopeData)
  337. {
  338. // Create & Binds DepthStencil image
  339. {
  340. frameGraph.GetAttachmentDatabase().CreateTransientImage(m_transientImageDescriptor);
  341. AZ::RHI::ImageScopeAttachmentDescriptor dsDesc;
  342. dsDesc.m_attachmentId = m_depthMapID;
  343. dsDesc.m_imageViewDescriptor.m_overrideFormat = AZ::RHI::Format::D32_FLOAT;
  344. dsDesc.m_loadStoreAction.m_clearValue = m_depthClearValue;
  345. dsDesc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Clear;
  346. frameGraph.UseDepthStencilAttachment(
  347. dsDesc, AZ::RHI::ScopeAttachmentAccess::ReadWrite,
  348. AZ::RHI::ScopeAttachmentStage::EarlyFragmentTest | AZ::RHI::ScopeAttachmentStage::LateFragmentTest);
  349. }
  350. frameGraph.SetEstimatedItemCount(1);
  351. };
  352. AZ::RHI::EmptyCompileFunction<ScopeData> compileFunctionLightView;
  353. const auto executeFunctionLightView = [this](const AZ::RHI::FrameGraphExecuteContext& context, [[maybe_unused]] const ScopeData& scopeData)
  354. {
  355. AZ::RHI::CommandList* commandList = context.GetCommandList();
  356. AZ::RHI::Viewport viewport = AZ::RHI::Viewport(0, static_cast<float>(s_shadowMapSize), 0, static_cast<float>(s_shadowMapSize));
  357. AZ::RHI::Scissor scissor = AZ::RHI::Scissor(0, 0, static_cast<int32_t>(s_shadowMapSize), static_cast<int32_t>(s_shadowMapSize));
  358. commandList->SetViewports(&viewport, 1);
  359. commandList->SetScissors(&scissor, 1);
  360. AZ::RHI::DrawIndexed drawIndexed;
  361. drawIndexed.m_indexCount = geometryIndexCount;
  362. drawIndexed.m_instanceCount = 1;
  363. const AZ::RHI::DeviceShaderResourceGroup* shaderResourceGroups[] = {
  364. m_shaderResourceGroups[0]->GetRHIShaderResourceGroup()->GetDeviceShaderResourceGroup(context.GetDeviceIndex()).get()
  365. };
  366. AZ::RHI::DeviceDrawItem drawItem;
  367. drawItem.m_arguments = drawIndexed;
  368. drawItem.m_pipelineState = m_pipelineStates[0]->GetDevicePipelineState(context.GetDeviceIndex()).get();
  369. auto deviceIndexBufferView{m_indexBufferView.GetDeviceIndexBufferView(context.GetDeviceIndex())};
  370. drawItem.m_indexBufferView = &deviceIndexBufferView;
  371. drawItem.m_shaderResourceGroupCount = static_cast<uint8_t>(AZ::RHI::ArraySize(shaderResourceGroups));
  372. drawItem.m_shaderResourceGroups = shaderResourceGroups;
  373. drawItem.m_streamBufferViewCount = static_cast<uint8_t>(m_streamBufferViews.size());
  374. AZStd::array<AZ::RHI::DeviceStreamBufferView, 3> deviceStreamBufferViews{
  375. m_streamBufferViews[0].GetDeviceStreamBufferView(context.GetDeviceIndex()),
  376. m_streamBufferViews[1].GetDeviceStreamBufferView(context.GetDeviceIndex()),
  377. m_streamBufferViews[2].GetDeviceStreamBufferView(context.GetDeviceIndex())
  378. };
  379. drawItem.m_streamBufferViews = deviceStreamBufferViews.data();
  380. commandList->Submit(drawItem);
  381. };
  382. m_scopeProducers.emplace_back(aznew AZ::RHI::ScopeProducerFunction<
  383. ScopeData,
  384. decltype(prepareFunctionLightView),
  385. decltype(compileFunctionLightView),
  386. decltype(executeFunctionLightView)>(
  387. AZ::RHI::ScopeId{"MultipleViewsDepth"},
  388. ScopeData{},
  389. prepareFunctionLightView,
  390. compileFunctionLightView,
  391. executeFunctionLightView));
  392. }
  393. void MultipleViewsComponent::CreateMainScope()
  394. {
  395. const auto prepareFunctionMainView = [this](AZ::RHI::FrameGraphInterface frameGraph, [[maybe_unused]] ScopeData& scopeData)
  396. {
  397. // Binds the swap chain as a color attachment. Clears it to black.
  398. {
  399. AZ::RHI::ImageScopeAttachmentDescriptor descriptor;
  400. descriptor.m_attachmentId = m_outputAttachmentId;
  401. descriptor.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
  402. frameGraph.UseColorAttachment(descriptor);
  403. }
  404. // Binds depth buffer from depth pass
  405. {
  406. frameGraph.UseShaderAttachment(
  407. AZ::RHI::ImageScopeAttachmentDescriptor(m_transientImageDescriptor.m_attachmentId),
  408. AZ::RHI::ScopeAttachmentAccess::Read, AZ::RHI::ScopeAttachmentStage::FragmentShader);
  409. }
  410. // Create & Binds DepthStencil image
  411. {
  412. AZ::RHI::Ptr<AZ::RHI::Device> device = Utils::GetRHIDevice();
  413. AZ::RHI::Format depthStencilFormat = device->GetNearestSupportedFormat(AZ::RHI::Format::D24_UNORM_S8_UINT, AZ::RHI::FormatCapabilities::DepthStencil);
  414. const AZ::RHI::ImageDescriptor imageDescriptor = AZ::RHI::ImageDescriptor::Create2D(
  415. AZ::RHI::ImageBindFlags::DepthStencil,
  416. m_outputWidth,
  417. m_outputHeight,
  418. depthStencilFormat);
  419. const AZ::RHI::TransientImageDescriptor transientImageDescriptor(m_depthStencilID, imageDescriptor);
  420. frameGraph.GetAttachmentDatabase().CreateTransientImage(transientImageDescriptor);
  421. AZ::RHI::ImageScopeAttachmentDescriptor dsDesc;
  422. dsDesc.m_attachmentId = m_depthStencilID;
  423. dsDesc.m_imageViewDescriptor.m_overrideFormat = depthStencilFormat;
  424. dsDesc.m_loadStoreAction.m_clearValue = m_depthClearValue;
  425. dsDesc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Clear;
  426. frameGraph.UseDepthStencilAttachment(
  427. dsDesc, AZ::RHI::ScopeAttachmentAccess::Write,
  428. AZ::RHI::ScopeAttachmentStage::EarlyFragmentTest | AZ::RHI::ScopeAttachmentStage::LateFragmentTest);
  429. }
  430. // We will submit a single draw item.
  431. frameGraph.SetEstimatedItemCount(1);
  432. };
  433. const auto compileFunctionMainView = [this](const AZ::RHI::FrameGraphCompileContext& context, [[maybe_unused]] const ScopeData& scopeData)
  434. {
  435. const auto* imageView = context.GetImageView(m_transientImageDescriptor.m_attachmentId);
  436. m_shaderResourceGroups[1]->SetImageView(m_shaderInputImageIndex, imageView);
  437. m_shaderResourceGroups[1]->Compile();
  438. };
  439. const auto executeFunctionMainView = [this](const AZ::RHI::FrameGraphExecuteContext& context, [[maybe_unused]] const ScopeData& scopeData)
  440. {
  441. AZ::RHI::CommandList* commandList = context.GetCommandList();
  442. // Set persistent viewport and scissor state.
  443. commandList->SetViewports(&m_viewport, 1);
  444. commandList->SetScissors(&m_scissor, 1);
  445. AZ::RHI::DrawIndexed drawIndexed;
  446. drawIndexed.m_indexCount = geometryIndexCount;
  447. drawIndexed.m_instanceCount = 1;
  448. const AZ::RHI::DeviceShaderResourceGroup* shaderResourceGroups[] = {
  449. m_shaderResourceGroups[1]->GetRHIShaderResourceGroup()->GetDeviceShaderResourceGroup(context.GetDeviceIndex()).get()
  450. };
  451. AZ::RHI::DeviceDrawItem drawItem;
  452. drawItem.m_arguments = drawIndexed;
  453. drawItem.m_pipelineState = m_pipelineStates[1]->GetDevicePipelineState(context.GetDeviceIndex()).get();
  454. auto deviceIndexBufferView{m_indexBufferView.GetDeviceIndexBufferView(context.GetDeviceIndex())};
  455. drawItem.m_indexBufferView = &deviceIndexBufferView;
  456. drawItem.m_shaderResourceGroupCount = static_cast<uint8_t>(AZ::RHI::ArraySize(shaderResourceGroups));
  457. drawItem.m_shaderResourceGroups = shaderResourceGroups;
  458. drawItem.m_streamBufferViewCount = static_cast<uint8_t>(m_streamBufferViews.size());
  459. AZStd::array<AZ::RHI::DeviceStreamBufferView, 3> deviceStreamBufferViews{
  460. m_streamBufferViews[0].GetDeviceStreamBufferView(context.GetDeviceIndex()),
  461. m_streamBufferViews[1].GetDeviceStreamBufferView(context.GetDeviceIndex()),
  462. m_streamBufferViews[2].GetDeviceStreamBufferView(context.GetDeviceIndex())
  463. };
  464. drawItem.m_streamBufferViews = deviceStreamBufferViews.data();
  465. commandList->Submit(drawItem);
  466. };
  467. m_scopeProducers.emplace_back(
  468. aznew AZ::RHI::ScopeProducerFunction<
  469. ScopeData,
  470. decltype(prepareFunctionMainView),
  471. decltype(compileFunctionMainView),
  472. decltype(executeFunctionMainView)>(
  473. AZ::RHI::ScopeId{"MultipleViewsShadow"},
  474. ScopeData{},
  475. prepareFunctionMainView,
  476. compileFunctionMainView,
  477. executeFunctionMainView));
  478. }
  479. }