Merge pull request #7275 from aws-lumberyard-dev/Atom/dmcdiar/ATOM-13886
DiffuseProbeGrid Visualizationmonroegm-disable-blank-issue-2
commit
7413842227
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:18a2bfdeeabfbbf6397daab7c89f9f7321e4863b54a4669fa87e457cb113322c
|
||||
size 78256
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData":
|
||||
{
|
||||
"PassTemplate":
|
||||
{
|
||||
"Name": "DiffuseProbeGridVisualizationAccelerationStructurePassTemplate",
|
||||
"PassClass": "DiffuseProbeGridVisualizationAccelerationStructurePass"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "DiffuseProbeGridVisualizationCompositePassTemplate",
|
||||
"PassClass": "DiffuseProbeGridVisualizationCompositePass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "VisualizationInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "Depth",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader",
|
||||
"ImageViewDesc": {
|
||||
"AspectFlags": [
|
||||
"Depth"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "ColorInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "RenderTarget"
|
||||
}
|
||||
],
|
||||
"PassData": {
|
||||
"$type": "FullscreenTrianglePassData",
|
||||
"ShaderAsset": {
|
||||
"FilePath": "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationComposite.shader"
|
||||
},
|
||||
"PipelineViewTag": "MainCamera"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData":
|
||||
{
|
||||
"PassTemplate":
|
||||
{
|
||||
"Name": "DiffuseProbeGridVisualizationPreparePassTemplate",
|
||||
"PassClass": "DiffuseProbeGridVisualizationPreparePass"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "DiffuseProbeGridVisualizationRayTracingPassTemplate",
|
||||
"PassClass": "DiffuseProbeGridVisualizationRayTracingPass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "Output",
|
||||
"SlotType": "Output",
|
||||
"ShaderInputName": "m_output",
|
||||
"ScopeAttachmentUsage": "Shader",
|
||||
"LoadStoreAction": {
|
||||
"ClearValue": {
|
||||
"Value": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"LoadAction": "Clear"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ImageAttachments": [
|
||||
{
|
||||
"Name": "VisualizationImage",
|
||||
"SizeSource": {
|
||||
"Source": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "NormalInput"
|
||||
}
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R32G32B32A32_FLOAT",
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "Output",
|
||||
"AttachmentRef": {
|
||||
"Pass": "This",
|
||||
"Attachment": "VisualizationImage"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertexUtil.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertexInfo.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
|
||||
ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
{
|
||||
Texture2D<float4> m_visualization;
|
||||
Texture2D<float> m_depth;
|
||||
|
||||
Sampler LinearSampler
|
||||
{
|
||||
MinFilter = Linear;
|
||||
MagFilter = Linear;
|
||||
MipFilter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
}
|
||||
|
||||
// Vertex Shader
|
||||
VSOutput MainVS(VSInput input)
|
||||
{
|
||||
VSOutput OUT;
|
||||
|
||||
float4 posTex = GetVertexPositionAndTexCoords(input.m_vertexID);
|
||||
OUT.m_position = float4(posTex.x, posTex.y, 0.0, 1.0);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
uint2 screenCoords = IN.m_position.xy;
|
||||
float depth = PassSrg::m_depth.Load(uint3(screenCoords, 0)).r;
|
||||
float4 visualization = PassSrg::m_visualization.Load(uint3(screenCoords, 0));
|
||||
|
||||
if (!any(visualization))
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
if (depth > visualization.a)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color = float4(visualization.rgb, 1.0f);
|
||||
return OUT;
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
{
|
||||
"Source" : "DiffuseProbeGridVisualizationComposite.azsl",
|
||||
|
||||
"RasterState" :
|
||||
{
|
||||
"CullMode" : "Back"
|
||||
},
|
||||
|
||||
"DepthStencilState" :
|
||||
{
|
||||
"Depth" :
|
||||
{
|
||||
"Enable" : false
|
||||
}
|
||||
},
|
||||
|
||||
"DrawList" : "forward",
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"Supervariants":
|
||||
[
|
||||
{
|
||||
"Name": "NoMSAA",
|
||||
"PlusArguments": "--no-ms",
|
||||
"MinusArguments": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PrecompiledShaderAssetSourceData",
|
||||
"ClassData":
|
||||
{
|
||||
"ShaderAssetFileName": "diffuseprobegridvisualizationprepare.azshader",
|
||||
"PlatformIdentifiers": [
|
||||
"pc",
|
||||
"linux"
|
||||
],
|
||||
"Supervariants":
|
||||
[
|
||||
{
|
||||
"Name": "",
|
||||
"RootShaderVariantAssets":
|
||||
[
|
||||
{
|
||||
"APIName": "dx12",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationprepare_dx12_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "vulkan",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationprepare_vulkan_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "null",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationprepare_null_0.azshadervariant"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PrecompiledShaderAssetSourceData",
|
||||
"ClassData":
|
||||
{
|
||||
"ShaderAssetFileName": "diffuseprobegridvisualizationraytracing.azshader",
|
||||
"PlatformIdentifiers": [
|
||||
"pc",
|
||||
"linux"
|
||||
],
|
||||
"Supervariants":
|
||||
[
|
||||
{
|
||||
"Name": "",
|
||||
"RootShaderVariantAssets":
|
||||
[
|
||||
{
|
||||
"APIName": "dx12",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracing_dx12_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "vulkan",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracing_vulkan_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "null",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracing_null_0.azshadervariant"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PrecompiledShaderAssetSourceData",
|
||||
"ClassData":
|
||||
{
|
||||
"ShaderAssetFileName": "diffuseprobegridvisualizationraytracingclosesthit.azshader",
|
||||
"PlatformIdentifiers":
|
||||
[
|
||||
"pc",
|
||||
"linux"
|
||||
],
|
||||
"Supervariants":
|
||||
[
|
||||
{
|
||||
"Name": "",
|
||||
"RootShaderVariantAssets":
|
||||
[
|
||||
{
|
||||
"APIName": "dx12",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingclosesthit_dx12_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "vulkan",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingclosesthit_vulkan_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "null",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingclosesthit_null_0.azshadervariant"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PrecompiledShaderAssetSourceData",
|
||||
"ClassData":
|
||||
{
|
||||
"ShaderAssetFileName": "diffuseprobegridvisualizationraytracingmiss.azshader",
|
||||
"PlatformIdentifiers":
|
||||
[
|
||||
"pc",
|
||||
"linux"
|
||||
],
|
||||
"Supervariants":
|
||||
[
|
||||
{
|
||||
"Name": "",
|
||||
"RootShaderVariantAssets":
|
||||
[
|
||||
{
|
||||
"APIName": "dx12",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingmiss_dx12_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "vulkan",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingmiss_vulkan_0.azshadervariant"
|
||||
},
|
||||
{
|
||||
"APIName": "null",
|
||||
"RootShaderVariantAssetFileName": "diffuseprobegridvisualizationraytracingmiss_null_0.azshadervariant"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/FrameScheduler.h>
|
||||
#include <Atom/RHI/CommandList.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom_Feature_Traits_Platform.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridVisualizationAccelerationStructurePass.h>
|
||||
#include <RayTracing/RayTracingFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationAccelerationStructurePass> DiffuseProbeGridVisualizationAccelerationStructurePass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationAccelerationStructurePass> diffuseProbeGridVisualizationAccelerationStructurePass = aznew DiffuseProbeGridVisualizationAccelerationStructurePass(descriptor);
|
||||
return AZStd::move(diffuseProbeGridVisualizationAccelerationStructurePass);
|
||||
}
|
||||
|
||||
DiffuseProbeGridVisualizationAccelerationStructurePass::DiffuseProbeGridVisualizationAccelerationStructurePass(const RPI::PassDescriptor& descriptor)
|
||||
: Pass(descriptor)
|
||||
{
|
||||
// disable this pass if we're on a platform that doesn't support raytracing
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
if (device->GetFeatures().m_rayTracing == false || !AZ_TRAIT_DIFFUSE_GI_PASSES_SUPPORTED)
|
||||
{
|
||||
SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationAccelerationStructurePass::ShouldUpdate(const AZStd::shared_ptr<DiffuseProbeGrid>& diffuseProbeGrid) const
|
||||
{
|
||||
return (diffuseProbeGrid->GetVisualizationEnabled() && diffuseProbeGrid->GetVisualizationTlasUpdateRequired());
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationAccelerationStructurePass::IsEnabled() const
|
||||
{
|
||||
if (!Pass::IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
if (!scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
if (diffuseProbeGridFeatureProcessor)
|
||||
{
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationAccelerationStructurePass::BuildInternal()
|
||||
{
|
||||
SetScopeId(RHI::ScopeId(GetPathName()));
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationAccelerationStructurePass::FrameBeginInternal(FramePrepareParams params)
|
||||
{
|
||||
params.m_frameGraphBuilder->ImportScopeProducer(*this);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationAccelerationStructurePass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// import and attach the visualization TLAS buffers
|
||||
RHI::Ptr<RHI::RayTracingTlas>& visualizationTlas = diffuseProbeGrid->GetVisualizationTlas();
|
||||
const RHI::Ptr<RHI::Buffer>& tlasBuffer = visualizationTlas->GetTlasBuffer();
|
||||
const RHI::Ptr<RHI::Buffer>& tlasInstancesBuffer = visualizationTlas->GetTlasInstancesBuffer();
|
||||
if (tlasBuffer && tlasInstancesBuffer)
|
||||
{
|
||||
// TLAS buffer
|
||||
{
|
||||
AZ::RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeVisualizationTlasAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(attachmentId, tlasBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import DiffuseProbeGrid visualization TLAS buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t byteCount = aznumeric_cast<uint32_t>(tlasBuffer->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRayTracingTLAS(byteCount);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = attachmentId;
|
||||
desc.m_bufferViewDescriptor = bufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::DontCare;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Write);
|
||||
}
|
||||
|
||||
// TLAS Instances buffer
|
||||
{
|
||||
AZ::RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeVisualizationTlasInstancesAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(attachmentId, tlasInstancesBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import DiffuseProbeGrid visualization TLAS Instances buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t byteCount = aznumeric_cast<uint32_t>(tlasInstancesBuffer->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor bufferViewDescriptor = RHI::BufferViewDescriptor::CreateStructured(0, byteCount / RayTracingTlasInstanceElementSize, RayTracingTlasInstanceElementSize);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = attachmentId;
|
||||
desc.m_bufferViewDescriptor = bufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationAccelerationStructurePass::BuildCommandList(const RHI::FrameGraphExecuteContext& context)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
// build the visualization BLAS from the DiffuseProbeGridFeatureProcessor
|
||||
// Note: the BLAS is used by all DiffuseProbeGrid visualization TLAS objects
|
||||
if (m_visualizationBlasBuilt == false)
|
||||
{
|
||||
context.GetCommandList()->BuildBottomLevelAccelerationStructure(*diffuseProbeGridFeatureProcessor->GetVisualizationBlas());
|
||||
m_visualizationBlasBuilt = true;
|
||||
}
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!diffuseProbeGrid->GetVisualizationTlas()->GetTlasBuffer())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// build the TLAS object
|
||||
context.GetCommandList()->BuildTopLevelAccelerationStructure(*diffuseProbeGrid->GetVisualizationTlas());
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationAccelerationStructurePass::FrameEndInternal()
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// TLAS is now updated
|
||||
diffuseProbeGrid->ResetVisualizationTlasUpdateRequired();
|
||||
}
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RHI/ScopeProducer.h>
|
||||
#include <Atom/RPI.Public/Pass/Pass.h>
|
||||
#include <Atom/RPI.Public/Buffer/Buffer.h>
|
||||
#include <Atom/RHI/RayTracingBufferPools.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This pass builds the DiffuseProbeGrid visualization acceleration structure
|
||||
class DiffuseProbeGridVisualizationAccelerationStructurePass final
|
||||
: public RPI::Pass
|
||||
, public RHI::ScopeProducer
|
||||
{
|
||||
public:
|
||||
AZ_RPI_PASS(DiffuseProbeGridVisualizationAccelerationStructurePass);
|
||||
|
||||
AZ_RTTI(DiffuseProbeGridVisualizationAccelerationStructurePass, "{103D8917-D4DC-4CA3-BFB4-CD62846D282A}", Pass);
|
||||
AZ_CLASS_ALLOCATOR(DiffuseProbeGridVisualizationAccelerationStructurePass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a DiffuseProbeGridVisualizationAccelerationStructurePass
|
||||
static RPI::Ptr<DiffuseProbeGridVisualizationAccelerationStructurePass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
~DiffuseProbeGridVisualizationAccelerationStructurePass() = default;
|
||||
|
||||
private:
|
||||
explicit DiffuseProbeGridVisualizationAccelerationStructurePass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
bool ShouldUpdate(const AZStd::shared_ptr<DiffuseProbeGrid>& diffuseProbeGrid) const;
|
||||
|
||||
// Scope producer functions
|
||||
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
|
||||
void BuildCommandList(const RHI::FrameGraphExecuteContext& context) override;
|
||||
|
||||
// Pass overrides
|
||||
bool IsEnabled() const override;
|
||||
void BuildInternal() override;
|
||||
void FrameBeginInternal(FramePrepareParams params) override;
|
||||
void FrameEndInternal() override;
|
||||
|
||||
bool m_visualizationBlasBuilt = false;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom_Feature_Traits_Platform.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridVisualizationCompositePass.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationCompositePass> DiffuseProbeGridVisualizationCompositePass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationCompositePass> pass = aznew DiffuseProbeGridVisualizationCompositePass(descriptor);
|
||||
return AZStd::move(pass);
|
||||
}
|
||||
|
||||
DiffuseProbeGridVisualizationCompositePass::DiffuseProbeGridVisualizationCompositePass(const RPI::PassDescriptor& descriptor)
|
||||
: RPI::FullscreenTrianglePass(descriptor)
|
||||
{
|
||||
if (!AZ_TRAIT_DIFFUSE_GI_PASSES_SUPPORTED)
|
||||
{
|
||||
SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationCompositePass::IsEnabled() const
|
||||
{
|
||||
if (!FullscreenTrianglePass::IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
if (!scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
if (diffuseProbeGridFeatureProcessor)
|
||||
{
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (diffuseProbeGrid->GetVisualizationEnabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Pass/Pass.h>
|
||||
#include <Atom/RPI.Public/Pass/FullscreenTrianglePass.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This pass composites the DiffuseProbeGrid visualization image onto the main scene
|
||||
class DiffuseProbeGridVisualizationCompositePass
|
||||
: public RPI::FullscreenTrianglePass
|
||||
{
|
||||
public:
|
||||
AZ_RPI_PASS(DiffuseProbeGridVisualizationCompositePass);
|
||||
|
||||
AZ_RTTI(Render::DiffuseProbeGridVisualizationCompositePass, "{64BD5779-AB30-41C1-81B7-B93D864355E5}", RPI::FullscreenTrianglePass);
|
||||
AZ_CLASS_ALLOCATOR(Render::DiffuseProbeGridVisualizationCompositePass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a new pass without a PassTemplate
|
||||
static RPI::Ptr<DiffuseProbeGridVisualizationCompositePass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
~DiffuseProbeGridVisualizationCompositePass() = default;
|
||||
|
||||
private:
|
||||
explicit DiffuseProbeGridVisualizationCompositePass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
// Pass behavior overrides...
|
||||
bool IsEnabled() const override;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/CommandList.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom_Feature_Traits_Platform.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridVisualizationPreparePass.h>
|
||||
#include <RayTracing/RayTracingFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationPreparePass> DiffuseProbeGridVisualizationPreparePass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationPreparePass> diffuseProbeGridVisualizationPreparePass = aznew DiffuseProbeGridVisualizationPreparePass(descriptor);
|
||||
return AZStd::move(diffuseProbeGridVisualizationPreparePass);
|
||||
}
|
||||
|
||||
DiffuseProbeGridVisualizationPreparePass::DiffuseProbeGridVisualizationPreparePass(const RPI::PassDescriptor& descriptor)
|
||||
: RenderPass(descriptor)
|
||||
{
|
||||
// disable this pass if we're on a platform that doesn't support raytracing
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
if (device->GetFeatures().m_rayTracing == false || !AZ_TRAIT_DIFFUSE_GI_PASSES_SUPPORTED)
|
||||
{
|
||||
SetEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadShader();
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationPreparePass::LoadShader()
|
||||
{
|
||||
// load shaders
|
||||
// Note: the shader may not be available on all platforms
|
||||
AZStd::string shaderFilePath = "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationPrepare.azshader";
|
||||
m_shader = RPI::LoadCriticalShader(shaderFilePath);
|
||||
if (m_shader == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RHI::PipelineStateDescriptorForDispatch pipelineStateDescriptor;
|
||||
const auto& shaderVariant = m_shader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
shaderVariant.ConfigurePipelineState(pipelineStateDescriptor);
|
||||
m_pipelineState = m_shader->AcquirePipelineState(pipelineStateDescriptor);
|
||||
AZ_Assert(m_pipelineState, "Failed to acquire pipeline state");
|
||||
|
||||
m_srgLayout = m_shader->FindShaderResourceGroupLayout(RPI::SrgBindingSlot::Pass);
|
||||
AZ_Assert(m_srgLayout.get(), "Failed to find Srg layout");
|
||||
|
||||
const auto outcome = RPI::GetComputeShaderNumThreads(m_shader->GetAsset(), m_dispatchArgs);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
AZ_Error("PassSystem", false, "[DiffuseProbeGridVisualizationPreparePass '%s']: Shader '%s' contains invalid numthreads arguments:\n%s", GetPathName().GetCStr(), shaderFilePath.c_str(), outcome.GetError().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationPreparePass::ShouldUpdate(const AZStd::shared_ptr<DiffuseProbeGrid>& diffuseProbeGrid) const
|
||||
{
|
||||
return (diffuseProbeGrid->GetVisualizationEnabled() && diffuseProbeGrid->GetVisualizationTlasUpdateRequired());
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationPreparePass::IsEnabled() const
|
||||
{
|
||||
if (!RenderPass::IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
if (!scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
if (diffuseProbeGridFeatureProcessor)
|
||||
{
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationPreparePass::FrameBeginInternal(FramePrepareParams params)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// create the TLAS descriptor by adding an instance entry for each probe in the grid
|
||||
RHI::RayTracingTlasDescriptor tlasDescriptor;
|
||||
RHI::RayTracingTlasDescriptor* tlasDescriptorBuild = tlasDescriptor.Build();
|
||||
|
||||
// initialize the transform for each probe to Identity(), they will be updated by the compute shader
|
||||
AZ::Transform transform = AZ::Transform::Identity();
|
||||
|
||||
uint32_t probeCount = diffuseProbeGrid->GetTotalProbeCount();
|
||||
for (uint32_t index = 0; index < probeCount; ++index)
|
||||
{
|
||||
tlasDescriptorBuild->Instance()
|
||||
->InstanceID(index)
|
||||
->HitGroupIndex(0)
|
||||
->Blas(diffuseProbeGridFeatureProcessor->GetVisualizationBlas())
|
||||
->Transform(transform)
|
||||
;
|
||||
}
|
||||
|
||||
// create the TLAS buffers from on the descriptor
|
||||
RHI::Ptr<RHI::RayTracingTlas>& visualizationTlas = diffuseProbeGrid->GetVisualizationTlas();
|
||||
visualizationTlas->CreateBuffers(*device, &tlasDescriptor, diffuseProbeGridFeatureProcessor->GetVisualizationBufferPools());
|
||||
}
|
||||
|
||||
RenderPass::FrameBeginInternal(params);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationPreparePass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
|
||||
{
|
||||
RenderPass::SetupFrameGraphDependencies(frameGraph);
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// import and attach the visualization TLAS and probe data
|
||||
RHI::Ptr<RHI::RayTracingTlas>& visualizationTlas = diffuseProbeGrid->GetVisualizationTlas();
|
||||
const RHI::Ptr<RHI::Buffer>& tlasBuffer = visualizationTlas->GetTlasBuffer();
|
||||
const RHI::Ptr<RHI::Buffer>& tlasInstancesBuffer = visualizationTlas->GetTlasInstancesBuffer();
|
||||
if (tlasBuffer && tlasInstancesBuffer)
|
||||
{
|
||||
// TLAS buffer
|
||||
{
|
||||
AZ::RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeVisualizationTlasAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(attachmentId, tlasBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import DiffuseProbeGrid visualization TLAS buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t byteCount = aznumeric_cast<uint32_t>(tlasBuffer->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRayTracingTLAS(byteCount);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = attachmentId;
|
||||
desc.m_bufferViewDescriptor = bufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::DontCare;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Write);
|
||||
}
|
||||
|
||||
// TLAS Instances buffer
|
||||
{
|
||||
AZ::RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeVisualizationTlasInstancesAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(attachmentId, tlasInstancesBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import DiffuseProbeGrid visualization TLAS Instances buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t byteCount = aznumeric_cast<uint32_t>(tlasInstancesBuffer->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor bufferViewDescriptor = RHI::BufferViewDescriptor::CreateStructured(0, byteCount / RayTracingTlasInstanceElementSize, RayTracingTlasInstanceElementSize);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = attachmentId;
|
||||
desc.m_bufferViewDescriptor = bufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::DontCare;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Write);
|
||||
}
|
||||
|
||||
// probe data
|
||||
{
|
||||
AZ::RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(attachmentId, diffuseProbeGrid->GetProbeDataImage());
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import DiffuseProbeGrid probe data buffer with error %d", result);
|
||||
}
|
||||
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = attachmentId;
|
||||
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationPreparePass::CompileResources([[maybe_unused]] const RHI::FrameGraphCompileContext& context)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// the DiffuseProbeGrid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
|
||||
// (see ValidateSetImageView() in ShaderResourceGroupData.cpp)
|
||||
diffuseProbeGrid->UpdateVisualizationPrepareSrg(m_shader, m_srgLayout);
|
||||
diffuseProbeGrid->GetVisualizationPrepareSrg()->Compile();
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationPreparePass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
|
||||
{
|
||||
RHI::CommandList* commandList = context.GetCommandList();
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!ShouldUpdate(diffuseProbeGrid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetVisualizationPrepareSrg()->GetRHIShaderResourceGroup();
|
||||
commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup);
|
||||
|
||||
RHI::DispatchItem dispatchItem;
|
||||
dispatchItem.m_arguments = m_dispatchArgs;
|
||||
dispatchItem.m_pipelineState = m_pipelineState;
|
||||
dispatchItem.m_arguments.m_direct.m_totalNumberOfThreadsX = diffuseProbeGrid->GetTotalProbeCount();
|
||||
dispatchItem.m_arguments.m_direct.m_totalNumberOfThreadsY = 1;
|
||||
dispatchItem.m_arguments.m_direct.m_totalNumberOfThreadsZ = 1;
|
||||
|
||||
commandList->Submit(dispatchItem);
|
||||
}
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Pass/RenderPass.h>
|
||||
#include <Atom/RPI.Public/Shader/Shader.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This pass updates the DiffuseProbeGrid visualization TLAS instances buffer
|
||||
class DiffuseProbeGridVisualizationPreparePass final
|
||||
: public RPI::RenderPass
|
||||
{
|
||||
public:
|
||||
AZ_RPI_PASS(DiffuseProbeGridVisualizationPreparePass);
|
||||
|
||||
AZ_RTTI(DiffuseProbeGridVisualizationPreparePass, "{33BD769D-378B-4142-8C11-6A2ADA2BB095}", Pass);
|
||||
AZ_CLASS_ALLOCATOR(DiffuseProbeGridVisualizationPreparePass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a DiffuseProbeGridVisualizationPreparePass
|
||||
static RPI::Ptr<DiffuseProbeGridVisualizationPreparePass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
~DiffuseProbeGridVisualizationPreparePass() = default;
|
||||
|
||||
private:
|
||||
explicit DiffuseProbeGridVisualizationPreparePass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
void LoadShader();
|
||||
bool ShouldUpdate(const AZStd::shared_ptr<DiffuseProbeGrid>& diffuseProbeGrid) const;
|
||||
|
||||
// Pass overrides
|
||||
bool IsEnabled() const override;
|
||||
void FrameBeginInternal(FramePrepareParams params) override;
|
||||
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
|
||||
|
||||
// shader
|
||||
Data::Instance<RPI::Shader> m_shader;
|
||||
const RHI::PipelineState* m_pipelineState = nullptr;
|
||||
RHI::Ptr<RHI::ShaderResourceGroupLayout> m_srgLayout;
|
||||
RHI::DispatchDirect m_dispatchArgs;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/CommandList.h>
|
||||
#include <Atom/RHI/DispatchRaysItem.h>
|
||||
#include <Atom/RHI/Factory.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom_Feature_Traits_Platform.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridVisualizationRayTracingPass.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationRayTracingPass> DiffuseProbeGridVisualizationRayTracingPass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<DiffuseProbeGridVisualizationRayTracingPass> pass = aznew DiffuseProbeGridVisualizationRayTracingPass(descriptor);
|
||||
return AZStd::move(pass);
|
||||
}
|
||||
|
||||
DiffuseProbeGridVisualizationRayTracingPass::DiffuseProbeGridVisualizationRayTracingPass(const RPI::PassDescriptor& descriptor)
|
||||
: RPI::RenderPass(descriptor)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
if (device->GetFeatures().m_rayTracing == false || !AZ_TRAIT_DIFFUSE_GI_PASSES_SUPPORTED)
|
||||
{
|
||||
// raytracing or GI is not supported on this platform
|
||||
SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationRayTracingPass::CreateRayTracingPipelineState()
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
|
||||
// load the ray tracing shader
|
||||
// Note: the shader may not be available on all platforms
|
||||
AZStd::string shaderFilePath = "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationRayTracing.azshader";
|
||||
m_rayTracingShader = RPI::LoadCriticalShader(shaderFilePath);
|
||||
if (m_rayTracingShader == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto shaderVariant = m_rayTracingShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing rayGenerationShaderDescriptor;
|
||||
shaderVariant.ConfigurePipelineState(rayGenerationShaderDescriptor);
|
||||
|
||||
// closest hit shader
|
||||
AZStd::string closestHitShaderFilePath = "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationRayTracingClosestHit.azshader";
|
||||
m_closestHitShader = RPI::LoadCriticalShader(closestHitShaderFilePath);
|
||||
|
||||
auto closestHitShaderVariant = m_closestHitShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing closestHitShaderDescriptor;
|
||||
closestHitShaderVariant.ConfigurePipelineState(closestHitShaderDescriptor);
|
||||
|
||||
// miss shader
|
||||
AZStd::string missShaderFilePath = "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridVisualizationRayTracingMiss.azshader";
|
||||
m_missShader = RPI::LoadCriticalShader(missShaderFilePath);
|
||||
|
||||
auto missShaderVariant = m_missShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing missShaderDescriptor;
|
||||
missShaderVariant.ConfigurePipelineState(missShaderDescriptor);
|
||||
|
||||
// global pipeline state and Srg
|
||||
m_globalPipelineState = m_rayTracingShader->AcquirePipelineState(rayGenerationShaderDescriptor);
|
||||
AZ_Assert(m_globalPipelineState, "Failed to acquire ray tracing global pipeline state");
|
||||
|
||||
m_globalSrgLayout = m_rayTracingShader->FindShaderResourceGroupLayout(Name{ "RayTracingGlobalSrg" });
|
||||
AZ_Assert(m_globalSrgLayout != nullptr, "Failed to find RayTracingGlobalSrg layout for shader [%s]", shaderFilePath.c_str());
|
||||
|
||||
// build the ray tracing pipeline state descriptor
|
||||
RHI::RayTracingPipelineStateDescriptor descriptor;
|
||||
descriptor.Build()
|
||||
->PipelineState(m_globalPipelineState.get())
|
||||
->MaxPayloadSize(64)
|
||||
->MaxAttributeSize(32)
|
||||
->MaxRecursionDepth(2)
|
||||
->ShaderLibrary(rayGenerationShaderDescriptor)
|
||||
->RayGenerationShaderName(AZ::Name("RayGen"))
|
||||
->ShaderLibrary(missShaderDescriptor)
|
||||
->MissShaderName(AZ::Name("Miss"))
|
||||
->ShaderLibrary(closestHitShaderDescriptor)
|
||||
->ClosestHitShaderName(AZ::Name("ClosestHit"))
|
||||
->HitGroup(AZ::Name("HitGroup"))
|
||||
->ClosestHitShaderName(AZ::Name("ClosestHit"));
|
||||
|
||||
// create the ray tracing pipeline state object
|
||||
m_rayTracingPipelineState = RHI::Factory::Get().CreateRayTracingPipelineState();
|
||||
m_rayTracingPipelineState->Init(*device.get(), &descriptor);
|
||||
}
|
||||
|
||||
bool DiffuseProbeGridVisualizationRayTracingPass::IsEnabled() const
|
||||
{
|
||||
if (!RenderPass::IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
if (!scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
if (diffuseProbeGridFeatureProcessor)
|
||||
{
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (diffuseProbeGrid->GetVisualizationEnabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationRayTracingPass::FrameBeginInternal(FramePrepareParams params)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
if (!m_initialized)
|
||||
{
|
||||
CreateRayTracingPipelineState();
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
if (!m_rayTracingShaderTable)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
RHI::RayTracingBufferPools& rayTracingBufferPools = diffuseProbeGridFeatureProcessor->GetVisualizationBufferPools();
|
||||
|
||||
m_rayTracingShaderTable = RHI::Factory::Get().CreateRayTracingShaderTable();
|
||||
m_rayTracingShaderTable->Init(*device.get(), rayTracingBufferPools);
|
||||
|
||||
AZStd::shared_ptr<RHI::RayTracingShaderTableDescriptor> descriptor = AZStd::make_shared<RHI::RayTracingShaderTableDescriptor>();
|
||||
|
||||
// build the ray tracing shader table descriptor
|
||||
descriptor->Build(AZ::Name("RayTracingShaderTable"), m_rayTracingPipelineState)
|
||||
->RayGenerationRecord(AZ::Name("RayGen"))
|
||||
->MissRecord(AZ::Name("Miss"))
|
||||
->HitGroupRecord(AZ::Name("HitGroup"))
|
||||
;
|
||||
|
||||
m_rayTracingShaderTable->Build(descriptor);
|
||||
}
|
||||
|
||||
RenderPass::FrameBeginInternal(params);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationRayTracingPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
|
||||
{
|
||||
RenderPass::SetupFrameGraphDependencies(frameGraph);
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!diffuseProbeGrid->GetVisualizationEnabled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// TLAS
|
||||
{
|
||||
AZ::RHI::AttachmentId tlasAttachmentId = diffuseProbeGrid->GetProbeVisualizationTlasAttachmentId();
|
||||
const RHI::Ptr<RHI::Buffer>& visualizationTlasBuffer = diffuseProbeGrid->GetVisualizationTlas()->GetTlasBuffer();
|
||||
if (visualizationTlasBuffer)
|
||||
{
|
||||
if (!frameGraph.GetAttachmentDatabase().IsAttachmentValid(tlasAttachmentId))
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(tlasAttachmentId, visualizationTlasBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import ray tracing TLAS buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t tlasBufferByteCount = aznumeric_cast<uint32_t>(visualizationTlasBuffer->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor tlasBufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, tlasBufferByteCount);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = tlasAttachmentId;
|
||||
desc.m_bufferViewDescriptor = tlasBufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
|
||||
}
|
||||
}
|
||||
|
||||
// probe irradiance
|
||||
{
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = diffuseProbeGrid->GetIrradianceImageAttachmentId();
|
||||
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeIrradianceImageViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
|
||||
}
|
||||
|
||||
// probe distance
|
||||
{
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = diffuseProbeGrid->GetDistanceImageAttachmentId();
|
||||
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDistanceImageViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
|
||||
}
|
||||
|
||||
// probe data
|
||||
{
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
|
||||
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve the visualization image size, this will determine the number of rays to cast
|
||||
RPI::Ptr<RPI::PassAttachment> visualizationImageAttachment = m_ownedAttachments[0];
|
||||
AZ_Assert(visualizationImageAttachment.get(), "Invalid DiffuseProbeGrid Visualization image");
|
||||
|
||||
m_outputAttachmentSize = visualizationImageAttachment->GetTransientImageDescriptor().m_imageDescriptor.m_size;
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationRayTracingPass::CompileResources([[maybe_unused]] const RHI::FrameGraphCompileContext& context)
|
||||
{
|
||||
const RHI::ImageView* outputImageView = context.GetImageView(GetOutputBinding(0).m_attachment->GetAttachmentId());
|
||||
AZ_Assert(outputImageView, "Failed to retrieve output ImageView");
|
||||
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!diffuseProbeGrid->GetVisualizationEnabled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// the DiffuseProbeGridVisualization Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader
|
||||
// inputs (see line ValidateSetImageView() in ShaderResourceGroupData.cpp)
|
||||
diffuseProbeGrid->UpdateVisualizationRayTraceSrg(m_rayTracingShader, m_globalSrgLayout, outputImageView);
|
||||
diffuseProbeGrid->GetVisualizationRayTraceSrg()->Compile();
|
||||
}
|
||||
}
|
||||
|
||||
void DiffuseProbeGridVisualizationRayTracingPass::BuildCommandListInternal([[maybe_unused]] const RHI::FrameGraphExecuteContext& context)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
|
||||
const AZStd::vector<RPI::ViewPtr>& views = m_pipeline->GetViews(RPI::PipelineViewTag{ "MainCamera" });
|
||||
if (views.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleProbeGrids())
|
||||
{
|
||||
if (!diffuseProbeGrid->GetVisualizationEnabled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const RHI::ShaderResourceGroup* shaderResourceGroups[] = {
|
||||
diffuseProbeGrid->GetVisualizationRayTraceSrg()->GetRHIShaderResourceGroup(),
|
||||
views[0]->GetRHIShaderResourceGroup()
|
||||
};
|
||||
|
||||
RHI::DispatchRaysItem dispatchRaysItem;
|
||||
dispatchRaysItem.m_width = m_outputAttachmentSize.m_width;
|
||||
dispatchRaysItem.m_height = m_outputAttachmentSize.m_height;
|
||||
dispatchRaysItem.m_depth = 1;
|
||||
dispatchRaysItem.m_rayTracingPipelineState = m_rayTracingPipelineState.get();
|
||||
dispatchRaysItem.m_rayTracingShaderTable = m_rayTracingShaderTable.get();
|
||||
dispatchRaysItem.m_shaderResourceGroupCount = RHI::ArraySize(shaderResourceGroups);
|
||||
dispatchRaysItem.m_shaderResourceGroups = shaderResourceGroups;
|
||||
dispatchRaysItem.m_globalPipelineState = m_globalPipelineState.get();
|
||||
|
||||
// submit the DispatchRays item
|
||||
context.GetCommandList()->Submit(dispatchRaysItem);
|
||||
}
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Pass/RenderPass.h>
|
||||
#include <Atom/RHI/RayTracingPipelineState.h>
|
||||
#include <Atom/RHI/RayTracingShaderTable.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! Ray tracing shader that generates the probe visualization image for a DiffuseProbeGrid
|
||||
class DiffuseProbeGridVisualizationRayTracingPass final
|
||||
: public RPI::RenderPass
|
||||
{
|
||||
public:
|
||||
AZ_RPI_PASS(DiffuseProbeGridVisualizationRayTracingPass);
|
||||
|
||||
AZ_RTTI(DiffuseProbeGridVisualizationRayTracingPass, "{CDFB5C03-08D1-4FCA-8B63-2F8326E0DF1D}", RPI::RenderPass);
|
||||
AZ_CLASS_ALLOCATOR(DiffuseProbeGridVisualizationRayTracingPass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a DiffuseProbeGridVisualizationRayTracingPass
|
||||
static RPI::Ptr<DiffuseProbeGridVisualizationRayTracingPass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
~DiffuseProbeGridVisualizationRayTracingPass() = default;
|
||||
|
||||
private:
|
||||
explicit DiffuseProbeGridVisualizationRayTracingPass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
void CreateRayTracingPipelineState();
|
||||
|
||||
// Scope producer functions
|
||||
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
|
||||
|
||||
// Pass overrides
|
||||
bool IsEnabled() const override;
|
||||
void FrameBeginInternal(FramePrepareParams params) override;
|
||||
|
||||
// ray tracing shader and pipeline state
|
||||
Data::Instance<RPI::Shader> m_rayTracingShader;
|
||||
Data::Instance<RPI::Shader> m_missShader;
|
||||
Data::Instance<RPI::Shader> m_closestHitShader;
|
||||
RHI::Ptr<RHI::RayTracingPipelineState> m_rayTracingPipelineState;
|
||||
|
||||
// ray tracing shader table
|
||||
RHI::Ptr<RHI::RayTracingShaderTable> m_rayTracingShaderTable;
|
||||
|
||||
// current size of output attachment, updated every frame
|
||||
RHI::Size m_outputAttachmentSize;
|
||||
|
||||
// ray tracing global shader resource group layout and pipeline state
|
||||
RHI::Ptr<RHI::ShaderResourceGroupLayout> m_globalSrgLayout;
|
||||
RHI::ConstPtr<RHI::PipelineState> m_globalPipelineState;
|
||||
|
||||
bool m_initialized = false;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
Loading…
Reference in New Issue