瀏覽代碼

Initial checkin of work-in-progress proof-of-concept deferred render pipeline.

Signed-off-by: santorac <[email protected]>
santorac 2 年之前
父節點
當前提交
1fcea65317

+ 69 - 9
Gem/Code/Source/MeshExampleComponent.cpp

@@ -98,24 +98,67 @@ namespace AtomSampleViewer
         m_lowEndPipeline = nullptr;
     }
 
+    void MeshExampleComponent::CreateDeferredPipeline()
+    {
+        AZ::RPI::RenderPipelineDescriptor pipelineDesc;
+        pipelineDesc.m_mainViewTagName = "MainCamera";
+        pipelineDesc.m_name = "DeferredPipeline";
+        pipelineDesc.m_rootPassTemplate = "DeferredPipelineTemplate";
+        pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
+
+        m_deferredPipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineDesc, *m_windowContext);
+    }
+
+    void MeshExampleComponent::DestroyDeferredPipeline()
+    {
+        m_deferredPipeline = nullptr;
+    }
+
     void MeshExampleComponent::ActivateLowEndPipeline()
     {
-        m_originalPipeline = m_scene->GetDefaultRenderPipeline();
+        AZ::RPI::RenderPipelinePtr prevPipeline = m_scene->GetDefaultRenderPipeline();
+
+        if (!m_originalPipeline)
+        {
+            m_originalPipeline = prevPipeline;
+        }
+
         m_lowEndPipeline->GetRootPass()->SetEnabled(true); // PassSystem::RemoveRenderPipeline was calling SetEnabled(false)
         m_scene->AddRenderPipeline(m_lowEndPipeline);
-        m_lowEndPipeline->SetDefaultView(m_originalPipeline->GetDefaultView());
-        m_scene->RemoveRenderPipeline(m_originalPipeline->GetId());
+        m_lowEndPipeline->SetDefaultView(prevPipeline->GetDefaultView());
+        m_scene->RemoveRenderPipeline(prevPipeline->GetId());
 
+        m_imguiScope = {}; // I'm not sure why this is needed. Something must be wrong in the ImGuiActiveContextScope class
         m_imguiScope = AZ::Render::ImGuiActiveContextScope::FromPass({ m_lowEndPipeline->GetId().GetCStr(), "ImGuiPass" });
     }
 
-    void MeshExampleComponent::DeactivateLowEndPipeline()
+    void MeshExampleComponent::ActivateDeferredPipeline()
+    {
+        AZ::RPI::RenderPipelinePtr prevPipeline = m_scene->GetDefaultRenderPipeline();
+
+        if (!m_originalPipeline)
+        {
+            m_originalPipeline = prevPipeline;
+        }
+
+        m_deferredPipeline->GetRootPass()->SetEnabled(true); // PassSystem::RemoveRenderPipeline was calling SetEnabled(false)
+        m_scene->AddRenderPipeline(m_deferredPipeline);
+        m_deferredPipeline->SetDefaultView(prevPipeline->GetDefaultView());
+        m_scene->RemoveRenderPipeline(prevPipeline->GetId());
+
+        m_imguiScope = {}; // I'm not sure why this is needed. Something must be wrong in the ImGuiActiveContextScope class
+        m_imguiScope = AZ::Render::ImGuiActiveContextScope::FromPass({m_deferredPipeline->GetId().GetCStr(), "ImGuiPass"});
+    }
+
+    void MeshExampleComponent::ActivateOriginalPipeline()
     {
         m_imguiScope = {}; // restores previous ImGui context.
 
+        AZ::RPI::RenderPipelinePtr prevPipeline = m_scene->GetDefaultRenderPipeline();
+
         m_originalPipeline->GetRootPass()->SetEnabled(true); // PassSystem::RemoveRenderPipeline was calling SetEnabled(false)
         m_scene->AddRenderPipeline(m_originalPipeline);
-        m_scene->RemoveRenderPipeline(m_lowEndPipeline->GetId());
+        m_scene->RemoveRenderPipeline(prevPipeline->GetId());
     }
 
     void MeshExampleComponent::Activate()
@@ -157,15 +200,18 @@ namespace AtomSampleViewer
         AZ::TickBus::Handler::BusConnect();
         AZ::Render::Bootstrap::DefaultWindowNotificationBus::Handler::BusConnect();
         CreateLowEndPipeline();
+        CreateDeferredPipeline();
     }
 
     void MeshExampleComponent::Deactivate()
     {
-        if (m_useLowEndPipeline)
+        if (m_useLowEndPipeline || m_useDeferredPipeline)
         {
-            DeactivateLowEndPipeline();
+            ActivateOriginalPipeline();
         }
         DestroyLowEndPipeline();
+        DestroyDeferredPipeline();
+
         AZ::Render::Bootstrap::DefaultWindowNotificationBus::Handler::BusDisconnect();
         AZ::TickBus::Handler::BusDisconnect();
 
@@ -198,9 +244,13 @@ namespace AtomSampleViewer
             {
                 ActivateLowEndPipeline();
             }
+            else if (m_useDeferredPipeline)
+            {
+                ActivateDeferredPipeline();
+            }
             else
             {
-                DeactivateLowEndPipeline();
+                ActivateOriginalPipeline();
             }
 
             m_switchPipeline = false;
@@ -212,7 +262,17 @@ namespace AtomSampleViewer
 
             ImGuiAssetBrowser::WidgetSettings assetBrowserSettings;
 
-            m_switchPipeline = ScriptableImGui::Checkbox("Use Low End Pipeline", &m_useLowEndPipeline) || m_switchPipeline;
+            if (ScriptableImGui::Checkbox("Use Low End Pipeline", &m_useLowEndPipeline))
+            {
+                m_switchPipeline = true;
+                m_useDeferredPipeline = false;
+            }
+
+            if (ScriptableImGui::Checkbox("Use Deferred Pipeline", &m_useDeferredPipeline))
+            {
+                m_switchPipeline = true;
+                m_useLowEndPipeline = false;
+            }
 
             modelNeedsUpdate |= ScriptableImGui::Checkbox("Enable Material Override", &m_enableMaterialOverride);
            

+ 15 - 1
Gem/Code/Source/MeshExampleComponent.h

@@ -67,10 +67,23 @@ namespace AtomSampleViewer
         void CreateLowEndPipeline();
         void DestroyLowEndPipeline();
 
+        void CreateDeferredPipeline();
+        void DestroyDeferredPipeline();
+
         void ActivateLowEndPipeline();
-        void DeactivateLowEndPipeline();
+        void ActivateDeferredPipeline();
+        void ActivateOriginalPipeline();
+
+        enum class Pipeline
+        {
+            Original,
+            LowEnd,
+            Deferred
+        };
+        Pipeline m_currentPipeline = Pipeline::Original;
 
         AZ::RPI::RenderPipelinePtr m_lowEndPipeline;
+        AZ::RPI::RenderPipelinePtr m_deferredPipeline;
         AZ::RPI::RenderPipelinePtr m_originalPipeline;
 
         AZStd::shared_ptr<AZ::RPI::WindowContext> m_windowContext;
@@ -106,6 +119,7 @@ namespace AtomSampleViewer
         bool m_cameraControllerDisabled = false;
 
         bool m_useLowEndPipeline = false;
+        bool m_useDeferredPipeline = false;
         bool m_switchPipeline = false;
 
         AZ::Data::Instance<AZ::RPI::Material> m_materialOverrideInstance; //< Holds a copy of the material instance being used when m_enableMaterialOverride is true.

+ 104 - 0
Materials/Pipelines/PrototypeDeferredPipeline/DeferredMaterialPass.azsli

@@ -0,0 +1,104 @@
+/*
+ * 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 <viewsrg.srgi>
+#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
+//#include <Atom/Features/Pipeline/Forward/ForwardPassSrg.azsli>
+//#include <Atom/Features/Pipeline/Forward/ForwardPassOutput.azsli>
+//#include <Atom/Features/PBR/AlphaUtils.azsli>
+#include <Atom/Features/ColorManagement/TransformColor.azsli>
+//#include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
+#include <Atom/Features/PBR/Surfaces/StandardSurface.azsli>
+//#include <Atom/Features/PBR/Decals.azsli>
+
+struct VSInput
+{
+    float3 m_position : POSITION;
+    float3 m_normal : NORMAL;
+    float4 m_tangent : TANGENT; 
+    float3 m_bitangent : BITANGENT; 
+};
+
+struct VSOutput
+{
+    precise linear centroid float4 m_position : SV_Position;
+    float3 m_normal: NORMAL;
+    float3 m_tangent : TANGENT; 
+    float3 m_bitangent : BITANGENT; 
+    float3 m_worldPosition : UV0;
+};
+
+#include <Atom/Features/Vertex/VertexHelper.azsli>
+
+void MaterialFunction_AdjustLocalPosition(inout float3 localPosition);
+void MaterialFunction_AdjustWorldPosition(inout float3 worldPosition);
+void MaterialFunction_AdjustSurface(inout Surface outSurface);
+
+VSOutput MaterialVS(VSInput IN)
+{
+    VSOutput OUT;
+ 
+    MaterialFunction_AdjustLocalPosition(IN.m_position);
+
+    float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz;
+ 
+    MaterialFunction_AdjustWorldPosition(worldPosition);
+
+    VertexHelper(IN, OUT, worldPosition);
+
+    return OUT;
+}
+
+struct DeferredMaterialOutput
+{
+    float4 m_baseColor  : SV_Target0;
+    float4 m_roughnessMetal : SV_Target1; 
+    float4 m_normal : SV_Target2;
+};
+
+#define MATERIALPIPELINE_SHADER_HAS_PIXEL_STAGE 1
+
+DeferredMaterialOutput MaterialPS(VSOutput IN)
+{
+    // ------- Surface -------
+
+    // Note, some of the data being set up in this "Surface" section isn't necessary for the deferred material pass,
+    // we are just doing it for consistency with how the same code is structured in the other material pipelines.
+
+    Surface surface;
+    surface.position = IN.m_worldPosition.xyz;
+    surface.vertexNormal = normalize(IN.m_normal);
+
+    // These are the values we expect MaterialFunction_EvaluateSurface to potentially replace.
+    surface.normal = surface.vertexNormal;
+    surface.roughnessLinear = 0.0;
+    float3 baseColor = float3(0.5, 0.5, 0.5);
+    float metallic = 0.0;
+    float specularF0Factor = 0.5f;
+    surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
+    surface.clearCoat.InitializeToZero();
+
+    MaterialFunction_AdjustSurface(surface);
+    
+    surface.CalculateRoughnessA();
+
+    // ------- Output -------
+
+    DeferredMaterialOutput OUT;
+
+    OUT.m_baseColor = float4(surface.baseColor, 1);
+    OUT.m_roughnessMetal = float4(surface.roughnessLinear, surface.metallic, 0, 0);
+    OUT.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
+    
+    //TODO: switch this after o_enableIBL is hooked up
+    //OUT.m_normal.a = EncodeUnorm2BitFlags(o_enableIBL, o_specularF0_enableMultiScatterCompensation);
+    OUT.m_normal.a = EncodeUnorm2BitFlags(true, o_specularF0_enableMultiScatterCompensation);
+
+    return OUT;
+}
+

+ 43 - 0
Materials/Pipelines/PrototypeDeferredPipeline/DeferredMaterialPass.shader.template

@@ -0,0 +1,43 @@
+{
+    "Source" : "INSERT_AZSL_HERE",
+
+    "DepthStencilState" :
+    {
+        "Depth" :
+        {
+            "Enable" : true,
+            "CompareFunc" : "GreaterEqual"
+        },
+        "Stencil" :
+        {
+            "Enable" : true,
+            "ReadMask" : "0x00",
+            "WriteMask" : "0xFF",
+            "FrontFace" :
+            {
+                "Func" : "Always",
+                "DepthFailOp" : "Keep",
+                "FailOp" : "Keep",
+                "PassOp" : "Replace"
+            }
+        }
+    },
+
+    "ProgramSettings":
+    {
+      "EntryPoints":
+      [
+        {
+          "name": "MaterialVS",
+          "type": "Vertex"
+        },
+        {
+          "name": "MaterialPS",
+          "type": "Fragment"
+        }
+      ]
+    },
+
+    "DrawList" : "deferredMaterial"
+}
+

+ 16 - 0
Materials/Pipelines/PrototypeDeferredPipeline/DeferredPipeline.materialpipeline

@@ -0,0 +1,16 @@
+{
+    "shaderTemplates": [
+        {
+            "shader": "./DeferredMaterialPass.shader.template",
+            "azsli": "Materials/Pipelines/PrototypeDeferredPipeline/DeferredMaterialPass.azsli"
+        },
+        {
+            "shader": "./DepthPass.shader.template",
+            "azsli": "Materials/Pipelines/PrototypeDeferredPipeline/DepthPass.azsli"
+        },
+        {
+            "shader": "./ShadowmapPass.shader.template",
+            "azsli": "Materials/Pipelines/PrototypeDeferredPipeline/ShadowmapPass.azsli"
+        }
+    ]
+}

+ 41 - 0
Materials/Pipelines/PrototypeDeferredPipeline/DepthPass.azsli

@@ -0,0 +1,41 @@
+/*
+ * 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/Features/PBR/DefaultObjectSrg.azsli>
+#include <viewsrg.srgi>
+
+struct VSInput
+{
+    float3 m_position : POSITION;
+};
+ 
+struct VSDepthOutput
+{
+    precise float4 m_position : SV_Position;
+};
+
+void MaterialFunction_AdjustLocalPosition(inout float3 localPosition);
+void MaterialFunction_AdjustWorldPosition(inout float3 worldPosition);
+
+VSDepthOutput DepthPassVS(VSInput IN)
+{
+    VSDepthOutput OUT;
+ 
+    MaterialFunction_AdjustLocalPosition(IN.m_position);
+
+    float4x4 objectToWorld = ObjectSrg::GetWorldMatrix();
+    float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz;
+    
+    MaterialFunction_AdjustWorldPosition(worldPosition);
+
+    OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0));
+
+    return OUT;
+}
+
+

+ 20 - 0
Materials/Pipelines/PrototypeDeferredPipeline/DepthPass.shader.template

@@ -0,0 +1,20 @@
+{
+    "Source" : "INSERT_AZSL_HERE",
+
+    "DepthStencilState" : { 
+        "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" }
+    },
+
+    "ProgramSettings" : 
+    {
+        "EntryPoints":
+        [
+            {
+                "name": "DepthPassVS",
+                "type" : "Vertex"
+            }
+        ] 
+    },
+
+    "DrawList" : "depth"
+}

+ 40 - 0
Materials/Pipelines/PrototypeDeferredPipeline/ShadowmapPass.azsli

@@ -0,0 +1,40 @@
+/*
+ * 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/Features/PBR/DefaultObjectSrg.azsli>
+#include <scenesrg.srgi>
+#include <viewsrg.srgi>
+
+struct VertexInput
+{
+    float3 m_position : POSITION;
+};
+
+struct VertexOutput
+{
+    float4 m_position : SV_Position;
+};
+
+void MaterialFunction_AdjustLocalPosition(inout float3 localPosition);
+void MaterialFunction_AdjustWorldPosition(inout float3 worldPosition);
+
+VertexOutput MainVS(VertexInput input)
+{
+    const float4x4 worldMatrix = ObjectSrg::GetWorldMatrix();
+    VertexOutput output;
+    
+    MaterialFunction_AdjustLocalPosition(input.m_position);
+
+    float3 worldPosition = mul(worldMatrix, float4(input.m_position, 1.0)).xyz;
+    
+    MaterialFunction_AdjustWorldPosition(worldPosition);
+
+    output.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0));
+
+    return output;
+}

+ 28 - 0
Materials/Pipelines/PrototypeDeferredPipeline/ShadowmapPass.shader.template

@@ -0,0 +1,28 @@
+{
+    "Source" : "INSERT_AZSL_HERE",
+
+    "DepthStencilState" : { 
+        "Depth" : { "Enable" : true, "CompareFunc" : "LessEqual" }
+    },
+
+    "DrawList" : "shadow",
+
+    // Note that lights now expose their own bias controls.
+    // It may be worth increasing their default values in the future and reducing the depthBias values encoded here.
+    "RasterState" :
+    {
+        "depthBias" : "10",
+        "depthBiasSlopeScale" : "4"        
+    },
+
+    "ProgramSettings":
+    {
+      "EntryPoints":
+      [
+        {
+          "name": "MainVS",
+          "type": "Vertex"
+        }
+      ]
+    }
+}

+ 16 - 0
Passes/ASV/PassTemplates.azasset

@@ -75,6 +75,22 @@
             {
                 "Name": "ReadbackPipelineTemplate",
                 "Path": "Passes/ReadbackPipeline.pass"
+            },
+            {
+                "Name": "DeferredPipelineTemplate",
+                "Path": "Passes/PrototypeDeferredPipeline/DeferredPipeline.pass"
+            },
+            {
+                "Name": "DeferredOpaqueParentTemplate",
+                "Path": "Passes/PrototypeDeferredPipeline/DeferredOpaqueParent.pass"
+            },
+            {
+                "Name": "DeferredMaterialPassTemplate",
+                "Path": "Passes/PrototypeDeferredPipeline/DeferredMaterial.pass"
+            },
+            {
+                "Name": "DeferredLightingPassTemplate",
+                "Path": "Passes/PrototypeDeferredPipeline/DeferredLighting.pass"
             }
         ]
     }

+ 146 - 0
Passes/PrototypeDeferredPipeline/DeferredLighting.azsl

@@ -0,0 +1,146 @@
+/*
+ * 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 <viewsrg.srgi>
+
+#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
+#include <Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli>
+#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
+
+ShaderResourceGroup PassSrg : SRG_PerPass
+{
+    Texture2DArray<float> m_directionalLightShadowmap;
+    Texture2DArray<float> m_directionalLightExponentialShadowmap;
+    Texture2DArray<float> m_projectedShadowmaps;
+    Texture2DArray<float> m_projectedExponentialShadowmap;
+    Texture2D m_brdfMap;
+    Texture2D<float> m_fullscreenShadow;
+
+    Sampler LinearSampler
+    {
+        MinFilter = Linear;
+        MagFilter = Linear;
+        MipFilter = Linear;
+        AddressU = Clamp;
+        AddressV = Clamp;
+        AddressW = Clamp;
+    };
+    
+    Texture2D<uint4> m_tileLightData;
+    StructuredBuffer<uint> m_lightListRemapped;
+    //Texture2D<float> m_linearDepthTexture;
+    
+    Texture2DMS<float2>   m_depthStencilTexture;
+
+    Texture2DMS<float4> m_baseColor;
+    Texture2DMS<float4> m_roughnessMetal;
+    Texture2DMS<float4> m_normal;
+}
+
+#define FORCE_OPAQUE 1 // Because there is no transparency in deferred, so we don't want the o_opacity_mode shader option
+
+// TODO: Figure out how to support different lighting models.
+#include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
+#include <Atom/Features/PBR/Lights/Ibl.azsli>
+#include <Atom/Features/PBR/Decals.azsli>
+
+// Copied from ForwardPassOutput
+struct PSOutput
+{
+    float4 m_diffuseColor  : SV_Target0;     //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
+    float4 m_specularColor : SV_Target1;     //!< RGB = Specular Lighting, A = Unused
+    float4 m_albedo : SV_Target2;            //!< RGB = Surface albedo pre-multiplied by other factors that will be multiplied later by diffuse GI, A = specularOcclusion
+    float4 m_specularF0 : SV_Target3;        //!< RGB = Specular F0, A = roughness
+
+    //float4 m_normal : SV_Target4;            //!< RGB10 = EncodeNormalSignedOctahedron(worldNormal), A2 = Flags (IBL/Multiscatter enabled)
+};
+
+PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
+{
+    uint2 screenCoords = IN.m_position.xy;
+
+    // ------- Unpack G-Buffers -------
+
+    float zDepth = PassSrg::m_depthStencilTexture.Load(screenCoords, sampleIndex).r;
+    float3 surfacePosWS = WorldPositionFromDepthBufferMS(PassSrg::m_depthStencilTexture, zDepth, IN.m_position.xy).xyz;
+    float3 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex).xyz;
+    float3 normal = DecodeNormalSignedOctahedron(encodedNormal.xyz);
+    float2 roughnessMetallic = PassSrg::m_roughnessMetal.Load(screenCoords, sampleIndex).rg;
+    float3 baseColor = PassSrg::m_baseColor.Load(screenCoords, sampleIndex).rgb;
+    
+    // TODO: Remove this, it's temporary to help confirm the deferred pipeline is running.
+    if(abs(IN.m_texCoord.x-0.5) < 0.01 || abs(IN.m_texCoord.y-0.5) < 0.01) 
+    {
+        baseColor *= float3(1,0,1); 
+    }
+
+    // Copied from Gems\Atom\Feature\Common\Assets\Materials\Pipelines\MainPipeline\ForwardPass.azsli
+
+    // ------- Surface -------
+
+    Surface surface;
+    surface.position = surfacePosWS;
+
+    // TODO: We don't actually have the vertex normal right now
+    surface.vertexNormal = normal;
+    surface.normal = normal;
+    surface.roughnessLinear = roughnessMetallic.x;
+    float specularF0Factor = 0.5f; // TODO
+    surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, roughnessMetallic.y);
+    surface.clearCoat.InitializeToZero();
+        
+    surface.CalculateRoughnessA();
+
+    // ------- LightingData -------
+
+    LightingData lightingData;
+
+    // Light iterator
+    lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData);
+    lightingData.Init(surface.position, surface.normal, surface.roughnessLinear);
+
+
+    // Diffuse and Specular response
+    lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear);
+    lightingData.diffuseResponse = 1.0f - lightingData.specularResponse;
+
+    const float alpha = 1.0f;
+
+    // ------- Lighting Calculation -------
+
+    // Apply Decals
+    ApplyDecals(lightingData.tileIterator, surface);
+
+    // Apply Direct Lighting
+    ApplyDirectLighting(surface, lightingData, IN.m_position);
+
+    // Apply Image Based Lighting (IBL)
+    // TODO: how can we support a reflection probe in deferred?
+    ReflectionProbeData unusedReflectionProbe; 
+    TextureCube unusedReflectionProbeCubeMap;
+    ApplyIBL(surface, lightingData, true, false, unusedReflectionProbe, unusedReflectionProbeCubeMap);
+
+    // Finalize Lighting
+    lightingData.FinalizeLighting();
+
+    PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
+
+    // ------- Output -------
+
+    PSOutput OUT;
+
+    OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
+    OUT.m_diffuseColor.w = -1; // Subsurface scattering is disabled
+    OUT.m_specularColor = lightingOutput.m_specularColor;
+    OUT.m_specularF0 = lightingOutput.m_specularF0;
+    OUT.m_albedo = lightingOutput.m_albedo;
+
+    //OUT.m_diffuseColor.xyz = float3(1,1,0); 
+
+    return OUT;
+}

+ 302 - 0
Passes/PrototypeDeferredPipeline/DeferredLighting.pass

@@ -0,0 +1,302 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "PassAsset",
+    "ClassData": {
+        "PassTemplate": {
+            "Name": "DeferredLightingPassTemplate",
+            "PassClass": "FullScreenTriangle",
+            "Slots": [
+                // Inputs...
+                {
+                    "Name": "BRDFTextureInput",
+                    "ShaderInputName": "m_brdfMap",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader"
+                },
+                {
+                    "Name": "FullscreenShadow",
+                    "ShaderInputName": "m_fullscreenShadow",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader"
+                },
+                {
+                    "Name": "DirectionalLightShadowmap",
+                    "ShaderInputName": "m_directionalLightShadowmap",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ImageViewDesc": {
+                        "IsArray": 1
+                    }
+                },
+                {
+                    "Name": "ExponentialShadowmapDirectional",
+                    "ShaderInputName": "m_directionalLightExponentialShadowmap",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ImageViewDesc": {
+                        "IsArray": 1
+                    }
+                },
+                {
+                    "Name": "ProjectedShadowmap",
+                    "ShaderInputName": "m_projectedShadowmaps",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ImageViewDesc": {
+                        "IsArray": 1
+                    }
+                },
+                {
+                    "Name": "ExponentialShadowmapProjected",
+                    "ShaderInputName": "m_projectedExponentialShadowmap",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ImageViewDesc": {
+                        "IsArray": 1
+                    }
+                },
+                {
+                    "Name": "TileLightData",
+                    "SlotType": "Input",
+                    "ShaderInputName": "m_tileLightData",
+                    "ScopeAttachmentUsage": "Shader"
+                },
+                {
+                    "Name": "LightListRemapped",
+                    "SlotType": "Input",
+                    "ShaderInputName": "m_lightListRemapped",
+                    "ScopeAttachmentUsage": "Shader"
+                },
+                {
+                    "Name": "BaseColor",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ShaderInputName": "m_baseColor"
+                },
+                {
+                    "Name": "RoughnessMetal",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ShaderInputName": "m_roughnessMetal"
+                },
+                {
+                    "Name": "Normal",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ShaderInputName": "m_normal"
+                },
+                {
+                    "Name": "DepthStencil",
+                    "SlotType": "Input",
+                    "ScopeAttachmentUsage": "DepthStencil"
+                },
+                {
+                    "Name": "InputDepthStencil",
+                    "SlotType": "Input",
+                    "ShaderInputName": "m_depthStencilTexture",
+                    "ScopeAttachmentUsage": "Shader",
+                    "ImageViewDesc": {
+                        "AspectFlags": [
+                            "Depth"
+                        ]
+                    }
+                },
+                // Outputs...
+                {
+                    "Name": "DiffuseOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                },
+                {
+                    "Name": "SpecularOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.4000000059604645,
+                                0.4000000059604645,
+                                0.4000000059604645,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                },
+                {
+                    "Name": "AlbedoOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                },
+                {
+                    "Name": "SpecularF0Output",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                }
+            ],
+            "ImageAttachments": [
+                {
+                    "Name": "DiffuseImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencil"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R16G16B16A16_FLOAT",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "SpecularImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencil"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R16G16B16A16_FLOAT",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "AlbedoImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencil"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R8G8B8A8_UNORM",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "SpecularF0Image",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencil"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R8G8B8A8_UNORM",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "BRDFTexture",
+                    "Lifetime": "Imported",
+                    "AssetRef": {
+                        "FilePath": "Textures/BRDFTexture.attimage"
+                    }
+                }
+            ],
+            "Connections": [
+                {
+                    "LocalSlot": "DiffuseOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "DiffuseImage"
+                    }
+                },
+                {
+                    "LocalSlot": "SpecularOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "SpecularImage"
+                    }
+                },
+                {
+                    "LocalSlot": "AlbedoOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "AlbedoImage"
+                    }
+                },
+                {
+                    "LocalSlot": "SpecularF0Output",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "SpecularF0Image"
+                    }
+                },
+                {
+                    "LocalSlot": "BRDFTextureInput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "BRDFTexture"
+                    }
+                },
+                {
+                    "LocalSlot": "FullscreenShadow",
+                    "AttachmentRef": {
+                        "Pass": "PipelineGlobal",
+                        "Attachment": "FullscreenShadowBuffer"
+                    }
+                }
+            ],
+            "PassData": {
+                "$type": "FullscreenTrianglePassData",
+                "ShaderAsset": {
+                    // TODO: Make the pass system support source-relative paths
+                    "FilePath": "Passes/PrototypeDeferredPipeline/DeferredLighting.shader"
+                },
+                "PipelineViewTag": "MainCamera"
+            }
+        }
+    }
+}

+ 32 - 0
Passes/PrototypeDeferredPipeline/DeferredLighting.shader

@@ -0,0 +1,32 @@
+{ 
+    "Source" : "DeferredLighting.azsl",
+
+    "DepthStencilState" : {
+        "Depth" : { "Enable" : false }
+    },
+
+    "ProgramSettings":
+    {
+      "EntryPoints":
+      [
+        {
+          "name": "MainVS",
+          "type": "Vertex"
+        },
+        {
+          "name": "MainPS",
+          "type": "Fragment"
+        }
+      ]
+    },
+
+    "Supervariants":
+    [
+        {
+            "Name": "NoMSAA",
+                "AddBuildArguments" : {
+                "azslc": ["--no-ms"]
+            }
+        }
+    ]
+}

+ 145 - 0
Passes/PrototypeDeferredPipeline/DeferredMaterial.pass

@@ -0,0 +1,145 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "PassAsset",
+    "ClassData": {
+        "PassTemplate": {
+            "Name": "DeferredMaterialPassTemplate",
+            "PassClass": "RasterPass",
+            "Slots": [
+                // Inputs...
+                {
+                    "Name": "DepthStencilInputOutput",
+                    // TODO: I don't think this needs to be InputOutput, I think it can just be an Input.
+                    "SlotType": "InputOutput",
+                    "ScopeAttachmentUsage": "DepthStencil"
+                },
+                // Outputs...
+                {
+                    "Name": "BaseColorOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                },
+                {
+                    "Name": "RoughnessMetalOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                },
+                {
+                    "Name": "NormalOutput",
+                    "SlotType": "Output",
+                    "ScopeAttachmentUsage": "RenderTarget",
+                    "LoadStoreAction": {
+                        "ClearValue": {
+                            "Value": [
+                                0.0,
+                                0.0,
+                                0.0,
+                                0.0
+                            ]
+                        },
+                        "LoadAction": "Clear"
+                    }
+                }
+            ],
+            "ImageAttachments": [
+                {
+                    "Name": "BaseColorImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencilInputOutput"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R16G16B16A16_FLOAT",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "RoughnessMetalImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencilInputOutput"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R16G16B16A16_FLOAT",
+                        "SharedQueueMask": "Graphics"
+                    }
+                },
+                {
+                    "Name": "NormalImage",
+                    "SizeSource": {
+                        "Source": {
+                            "Pass": "Parent",
+                            "Attachment": "PipelineOutput"
+                        }
+                    },
+                    "MultisampleSource": {
+                        "Pass": "This",
+                        "Attachment": "DepthStencilInputOutput"
+                    },
+                    "ImageDescriptor": {
+                        "Format": "R10G10B10A2_UNORM",
+                        "SharedQueueMask": "Graphics"
+                    }
+                }
+            ],
+            "Connections": [
+                {
+                    "LocalSlot": "BaseColorOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "BaseColorImage"
+                    }
+                },
+                {
+                    "LocalSlot": "RoughnessMetalOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "RoughnessMetalImage"
+                    }
+                },
+                {
+                    "LocalSlot": "NormalOutput",
+                    "AttachmentRef": {
+                        "Pass": "This",
+                        "Attachment": "NormalImage"
+                    }
+                }
+            ]
+        }
+    }
+}

+ 14 - 0
Passes/PrototypeDeferredPipeline/DeferredMaterialPassSrg.azsl

@@ -0,0 +1,14 @@
+/*
+ * 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
+ *
+ */
+
+// This shader is not used for rendering.
+// The only purpose of this shader is to have a shader asset that can be used
+// at runtime to find the PassSrg required by most Passes.
+
+#include <Atom/Features/Pipeline/Forward/ForwardPassSrg.azsli>
+#include <Atom/RPI/DummyEntryFunctions.azsli>

+ 40 - 0
Passes/PrototypeDeferredPipeline/DeferredMaterialPassSrg.shader

@@ -0,0 +1,40 @@
+{ 
+    "Source" : "DeferredMaterialPassSrg.azsl",
+
+    "DepthStencilState" : 
+    {
+        "Depth" : 
+        { 
+            "Enable" : false 
+        },
+        "Stencil" :
+        {
+            "Enable" : false
+        }
+    },
+
+    "ProgramSettings":
+    {
+      "EntryPoints":
+      [
+        {
+          "name": "MainVS",
+          "type": "Vertex"
+        },
+        {
+          "name": "MainPS",
+          "type": "Fragment"
+        }
+      ]
+    },
+    
+    "Supervariants":
+    [
+        {
+            "Name": "",
+            "RemoveBuildArguments": {
+                "azslc": ["--strip-unused-srgs"]
+            }
+        }
+    ]
+}

+ 500 - 0
Passes/PrototypeDeferredPipeline/DeferredOpaqueParent.pass

@@ -0,0 +1,500 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "PassAsset",
+    "ClassData": {
+        "PassTemplate": {
+            "Name": "DeferredOpaqueParentTemplate",
+            "PassClass": "ParentPass",
+            "Slots": [
+                // Inputs...
+                {
+                    "Name": "DirectionalShadowmap",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "DirectionalESM",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "ProjectedShadowmap",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "ProjectedESM",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "TileLightData",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "LightListRemapped",
+                    "SlotType": "Input"
+                },
+                {
+                    "Name": "DepthLinear",
+                    "SlotType": "Input"
+                },
+                // Input/Outputs...
+                {
+                    "Name": "DepthStencil",
+                    "SlotType": "InputOutput"
+                },
+                // Outputs...
+                {
+                    "Name": "Output",
+                    "SlotType": "Output"
+                },
+                {
+                    "Name": "DiffuseProbeGridVisualization",
+                    "SlotType": "Output"
+                },
+                // SwapChain here is only used to reference the frame height and format
+                {
+                    "Name": "PipelineOutput",
+                    "SlotType": "InputOutput"
+                }
+            ],
+            "Connections": [
+                {
+                    "LocalSlot": "Output",
+                    "AttachmentRef": {
+                        "Pass": "DiffuseSpecularMergePass",
+                        "Attachment": "Output"
+                    }
+                }
+            ],
+            "PassRequests": [
+                {
+                    "Name": "DeferredMaterial",
+                    "TemplateName": "DeferredMaterialPassTemplate",
+                    "Connections": [
+                        // Inputs...
+                        // Input/Outputs...
+                        {
+                            "LocalSlot": "DepthStencilInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DepthStencil"
+                            }
+                        }
+                    ],
+                    "PassData": {
+                        "$type": "RasterPassData",
+                        "DrawListTag": "deferredMaterial",
+                        "PipelineViewTag": "MainCamera"//,
+                        //"PassSrgShaderAsset": {
+                        //    "FilePath": "Passes/PrototypeDeferredPipeline/DeferredMaterialPassSrg.shader"
+                        //}
+                    }
+                },
+                {
+                    "Name": "DeferredLighting",
+                    "TemplateName": "DeferredLightingPassTemplate",
+                    "Connections": [
+                        // Inputs...
+                        {
+                            "LocalSlot": "DirectionalLightShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DirectionalShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ExponentialShadowmapDirectional",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DirectionalESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ProjectedShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "ProjectedShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ExponentialShadowmapProjected",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "ProjectedESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "TileLightData",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "TileLightData"
+                            }
+                        },
+                        {
+                            "LocalSlot": "LightListRemapped",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "LightListRemapped"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencil",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DepthStencil"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputDepthStencil",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DepthStencil"
+                            }
+                        },
+                        {
+                            "LocalSlot": "BaseColor",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "BaseColorOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "RoughnessMetal",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "RoughnessMetalOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "Normal",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "NormalOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "DiffuseGlobalFullscreenPass",
+                    "TemplateName": "DiffuseGlobalFullscreenPassTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "DiffuseInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredLighting",
+                                "Attachment": "DiffuseOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "AlbedoInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredLighting",
+                                "Attachment": "AlbedoOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "NormalInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "NormalOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencilTextureInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "DepthStencilInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencilInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "DepthStencilInputOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "ReflectionsPass",
+                    "TemplateName": "ReflectionsParentPassTemplate",
+                    "Enabled": true,
+                    "Connections": [
+                        {
+                            "LocalSlot": "NormalInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "NormalOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "SpecularF0Input",
+                            "AttachmentRef": {
+                                "Pass": "DeferredLighting",
+                                "Attachment": "SpecularF0Output"
+                            }
+                        },
+                        {
+                            "LocalSlot": "AlbedoInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredLighting",
+                                "Attachment": "AlbedoOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencilInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredMaterial",
+                                "Attachment": "DepthStencilInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "SpecularInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredLighting",
+                                "Attachment": "SpecularOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "SkyBoxPass",
+                    "TemplateName": "SkyBoxTwoOutputsTemplate",
+                    "Enabled": true,
+                    "Connections": [
+                        {
+                            "LocalSlot": "SpecularInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "ReflectionsPass",
+                                "Attachment": "SpecularInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ReflectionInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "ReflectionsPass",
+                                "Attachment": "ReflectionOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "SkyBoxDepth",
+                            "AttachmentRef": {
+                                "Pass": "ReflectionsPass",
+                                "Attachment": "DepthStencilInputOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "SkyAtmosphereParentPass",
+                    "TemplateName": "SkyAtmosphereParentTemplate",
+                    "Enabled": true,
+                    "Connections": [
+                        {
+                            "LocalSlot": "SpecularInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "SkyBoxPass",
+                                "Attachment": "SpecularInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ReflectionInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "SkyBoxPass",
+                                "Attachment": "ReflectionInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "SkyBoxDepth",
+                            "AttachmentRef": {
+                                "Pass": "SkyBoxPass",
+                                "Attachment": "SkyBoxDepth"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DirectionalShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DirectionalShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DirectionalESM",
+                            "AttachmentRef": {
+                                "Pass": "Parent",
+                                "Attachment": "DirectionalESM"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "ReflectionCompositePass",
+                    "TemplateName": "ReflectionCompositePassTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "ReflectionInput",
+                            "AttachmentRef": {
+                                "Pass": "SkyAtmosphereParentPass",
+                                "Attachment": "ReflectionInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "SpecularInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "SkyAtmosphereParentPass",
+                                "Attachment": "SpecularInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencilInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "SkyBoxPass",
+                                "Attachment": "SkyBoxDepth"
+                            }
+                        }
+                    ],
+                    "PassData": {
+                        "$type": "FullscreenTrianglePassData",
+                        "ShaderAsset": {
+                            "FilePath": "Shaders/Reflections/ReflectionComposite.shader"
+                        },
+                        "StencilRef": 1, // See RenderCommon.h and ReflectionComposite.shader
+                        "PipelineViewTag": "MainCamera"
+                    }
+                },
+                {
+                    "Name": "MSAAResolveDiffusePass",
+                    "TemplateName": "MSAAResolveColorTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "Input",
+                            "AttachmentRef": {
+                                "Pass": "DiffuseGlobalFullscreenPass",
+                                "Attachment": "DiffuseInputOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "MSAAResolveSpecularPass",
+                    "TemplateName": "MSAAResolveCustomTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "Input",
+                            "AttachmentRef": {
+                                "Pass": "ReflectionCompositePass",
+                                "Attachment": "SpecularInputOutput"
+                            }
+                        }
+                    ],
+                    "PassData": {
+                        "$type": "FullscreenTrianglePassData",
+                        "ShaderAsset": {
+                            "FilePath": "Shaders/PostProcessing/MSAAResolveCustom.shader"
+                        },
+                        "PipelineViewTag": "MainCamera",
+                        "ShaderDataMappings": {
+                            "UintMappings": [
+                                {
+                                    "Name": "enableNeighborClamping",
+                                    "Value": 1
+                                }
+                            ],
+                            "FloatMappings": [
+                                {
+                                    "Name": "maxNeighborContrast",
+                                    "Value": 1.5
+                                }
+                            ]
+                        }
+                    }
+                },
+                //{
+                //    "Name": "MSAAResolveScatterDistancePass",
+                //    "TemplateName": "MSAAResolveColorTemplate",
+                //    "Connections": [
+                //        {
+                //            "LocalSlot": "Input",
+                //            "AttachmentRef": {
+                //                "Pass": "ForwardSubsurface",
+                //                "Attachment": "ScatterDistanceOutput"
+                //            }
+                //        }
+                //    ]
+                //},
+                //{
+                //    "Name": "SubsurfaceScatteringPass",
+                //    "TemplateName": "SubsurfaceScatteringPassTemplate",
+                //    "Enabled": true,
+                //    "Connections": [
+                //        {
+                //            "LocalSlot": "InputDiffuse",
+                //            "AttachmentRef": {
+                //                "Pass": "MSAAResolveDiffusePass",
+                //                "Attachment": "Output"
+                //            }
+                //        },
+                //        {
+                //            "LocalSlot": "InputLinearDepth",
+                //            "AttachmentRef": {
+                //                "Pass": "Parent",
+                //                "Attachment": "DepthLinear"
+                //            }
+                //        },
+                //        {
+                //            "LocalSlot": "InputScatterDistance",
+                //            "AttachmentRef": {
+                //                "Pass": "MSAAResolveScatterDistancePass",
+                //                "Attachment": "Output"
+                //            }
+                //        }
+                //    ],
+                //    "PassData": {
+                //        "$type": "ComputePassData",
+                //        "ShaderAsset": {
+                //            "FilePath": "Shaders/PostProcessing/ScreenSpaceSubsurfaceScatteringCS.shader"
+                //        },
+                //        "Make Fullscreen Pass": true,
+                //        "PipelineViewTag": "MainCamera"
+                //    }
+                //},
+                {
+                    "Name": "Ssao",
+                    "TemplateName": "SsaoParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "Modulate",
+                            "AttachmentRef": {
+                                "Pass": "MSAAResolveDiffusePass",
+                                "Attachment": "Output"
+                            }
+                            //"AttachmentRef": {
+                            //    "Pass": "SubsurfaceScatteringPass",
+                            //    "Attachment": "Output"
+                            //}
+                        }
+                    ]
+                },
+                {
+                    "Name": "DiffuseSpecularMergePass",
+                    "TemplateName": "DiffuseSpecularMergeTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "InputDiffuse",
+                            "AttachmentRef": {
+                                "Pass": "Ssao",
+                                "Attachment": "Output"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputSpecular",
+                            "AttachmentRef": {
+                                "Pass": "MSAAResolveSpecularPass",
+                                "Attachment": "Output"
+                            }
+                        }
+                    ]
+                }
+            ]
+        }
+    }
+}

+ 471 - 0
Passes/PrototypeDeferredPipeline/DeferredPipeline.pass

@@ -0,0 +1,471 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "PassAsset",
+    "ClassData": {
+        "PassTemplate": {
+            "Name": "DeferredPipelineTemplate",
+            "PassClass": "ParentPass",
+            "Slots": [
+                {
+                    "Name": "PipelineOutput",
+                    "SlotType": "InputOutput"
+                }
+            ],
+            "PassData": {
+                "$type": "PassData",
+                "PipelineGlobalConnections": [
+                    {
+                        "GlobalName": "PipelineOutput",
+                        "Slot": "PipelineOutput"
+                    }
+                ]
+            },
+            "PassRequests": [
+                {
+                    "Name": "MorphTargetPass",
+                    "TemplateName": "MorphTargetPassTemplate"
+                },
+                {
+                    "Name": "SkinningPass",
+                    "TemplateName": "SkinningPassTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "SkinnedMeshOutputStream",
+                            "AttachmentRef": {
+                                "Pass": "MorphTargetPass",
+                                "Attachment": "MorphTargetDeltaOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "RayTracingAccelerationStructurePass",
+                    "TemplateName": "RayTracingAccelerationStructurePassTemplate"
+                },
+                {
+                    "Name": "DepthPrePass",
+                    "TemplateName": "DepthParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "SkinnedMeshes",
+                            "AttachmentRef": {
+                                "Pass": "SkinningPass",
+                                "Attachment": "SkinnedMeshOutputStream"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "MotionVectorPass",
+                    "TemplateName": "MotionVectorParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "SkinnedMeshes",
+                            "AttachmentRef": {
+                                "Pass": "SkinningPass",
+                                "Attachment": "SkinnedMeshOutputStream"
+                            }
+                        },
+                        {
+                            "LocalSlot": "Depth",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "LightCullingPass",
+                    "TemplateName": "LightCullingParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "SkinnedMeshes",
+                            "AttachmentRef": {
+                                "Pass": "SkinningPass",
+                                "Attachment": "SkinnedMeshOutputStream"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthMSAA",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthMSAA"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "Shadows",
+                    "TemplateName": "ShadowParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "SkinnedMeshes",
+                            "AttachmentRef": {
+                                "Pass": "SkinningPass",
+                                "Attachment": "SkinnedMeshOutputStream"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "Depth",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthMSAA" 
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "OpaquePass",
+                    "TemplateName": "DeferredOpaqueParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "DirectionalShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "DirectionalShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DirectionalESM",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "DirectionalESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ProjectedShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "ProjectedShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ProjectedESM",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "ProjectedESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "TileLightData",
+                            "AttachmentRef": {
+                                "Pass": "LightCullingPass",
+                                "Attachment": "TileLightData"
+                            }
+                        },
+                        {
+                            "LocalSlot": "LightListRemapped",
+                            "AttachmentRef": {
+                                "Pass": "LightCullingPass",
+                                "Attachment": "LightListRemapped"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthLinear",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthLinear"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencil",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthMSAA"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "TransparentPass",
+                    "TemplateName": "TransparentParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "DirectionalShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "DirectionalShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DirectionalESM",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "DirectionalESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ProjectedShadowmap",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "ProjectedShadowmap"
+                            }
+                        },
+                        {
+                            "LocalSlot": "ProjectedESM",
+                            "AttachmentRef": {
+                                "Pass": "Shadows",
+                                "Attachment": "ProjectedESM"
+                            }
+                        },
+                        {
+                            "LocalSlot": "TileLightData",
+                            "AttachmentRef": {
+                                "Pass": "LightCullingPass",
+                                "Attachment": "TileLightData"
+                            }
+                        },
+                        {
+                            "LocalSlot": "LightListRemapped",
+                            "AttachmentRef": {
+                                "Pass": "LightCullingPass",
+                                "Attachment": "LightListRemapped"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputLinearDepth",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthLinear"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthStencil",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputOutput",
+                            "AttachmentRef": {
+                                "Pass": "OpaquePass",
+                                "Attachment": "Output"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "DeferredFogPass",
+                    "TemplateName": "DeferredFogPassTemplate",
+                    "Enabled": false,
+                    "Connections": [
+                        {
+                            "LocalSlot": "InputLinearDepth",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "DepthLinear"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputDepthStencil",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        },
+                        {
+                            "LocalSlot": "RenderTargetInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "TransparentPass",
+                                "Attachment": "InputOutput"
+                            }
+                        }
+                    ],
+                    "PassData": {
+                        "$type": "FullscreenTrianglePassData",
+                        "ShaderAsset": {
+                            "FilePath": "Shaders/ScreenSpace/DeferredFog.shader"
+                        },
+                        "PipelineViewTag": "MainCamera"
+                    }
+                },
+                {
+                    "Name": "ReflectionCopyFrameBufferPass",
+                    "TemplateName": "ReflectionCopyFrameBufferPassTemplate",
+                    "Enabled": false,
+                    "Connections": [
+                        {
+                            "LocalSlot": "Input",
+                            "AttachmentRef": {
+                                "Pass": "DeferredFogPass",
+                                "Attachment": "RenderTargetInputOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "PostProcessPass",
+                    "TemplateName": "PostProcessParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "LightingInput",
+                            "AttachmentRef": {
+                                "Pass": "DeferredFogPass",
+                                "Attachment": "RenderTargetInputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "Depth",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        },
+                        {
+                            "LocalSlot": "MotionVectors",
+                            "AttachmentRef": {
+                                "Pass": "MotionVectorPass",
+                                "Attachment": "MotionVectorOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "PipelineOutput",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "AuxGeomPass",
+                    "TemplateName": "AuxGeomPassTemplate",
+                    "Enabled": true,
+                    "Connections": [
+                        {
+                            "LocalSlot": "ColorInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "PostProcessPass",
+                                "Attachment": "Output"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        }
+                    ],
+                    "PassData": {
+                        "$type": "RasterPassData",
+                        "DrawListTag": "auxgeom",
+                        "PipelineViewTag": "MainCamera"
+                    }
+                },
+                {
+                    "Name": "DebugOverlayPass",
+                    "TemplateName": "DebugOverlayParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "TileLightData",
+                            "AttachmentRef": {
+                                "Pass": "LightCullingPass",
+                                "Attachment": "TileLightData"
+                            }
+                        },
+                        {
+                            "LocalSlot": "RawLightingInput",
+                            "AttachmentRef": {
+                                "Pass": "PostProcessPass",
+                                "Attachment": "RawLightingOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "LuminanceMipChainInput",
+                            "AttachmentRef": {
+                                "Pass": "PostProcessPass",
+                                "Attachment": "LuminanceMipChainOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "InputOutput",
+                            "AttachmentRef": {
+                                "Pass": "AuxGeomPass",
+                                "Attachment": "ColorInputOutput"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "UIPass",
+                    "TemplateName": "UIParentTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "InputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DebugOverlayPass",
+                                "Attachment": "InputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "DepthInputOutput",
+                            "AttachmentRef": {
+                                "Pass": "DepthPrePass",
+                                "Attachment": "Depth"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "Name": "CopyToSwapChain",
+                    "TemplateName": "FullscreenCopyTemplate",
+                    "Connections": [
+                        {
+                            "LocalSlot": "Input",
+                            "AttachmentRef": {
+                                "Pass": "UIPass",
+                                "Attachment": "InputOutput"
+                            }
+                        },
+                        {
+                            "LocalSlot": "Output",
+                            "AttachmentRef": {
+                                "Pass": "PipelineGlobal",
+                                "Attachment": "PipelineOutput"
+                            }
+                        }
+                    ]
+                }
+            ]
+        }
+    }
+}

+ 3 - 1
Registry/material_pipelines.setreg

@@ -4,7 +4,9 @@
             "RPI": {
                 "MaterialPipelineFiles": [
                     "@gemroot:Atom_Feature_Common@/Assets/Materials/Pipelines/MainPipeline/MainPipeline.materialpipeline",
-                    "@gemroot:Atom_Feature_Common@/Assets/Materials/Pipelines/LowEndPipeline/LowEndPipeline.materialpipeline"
+                    "@gemroot:Atom_Feature_Common@/Assets/Materials/Pipelines/LowEndPipeline/LowEndPipeline.materialpipeline",
+                    // TODO: Figure out how to better support relative paths
+                    "@projectroot@/Materials/Pipelines/PrototypeDeferredPipeline/DeferredPipeline.materialpipeline"
                 ]
             }
         }