Alex Peterson 2 éve
szülő
commit
0f98ddfe98

+ 1 - 0
Project/Gem/CMakeLists.txt

@@ -51,6 +51,7 @@ ly_add_target(
             Include
     BUILD_DEPENDENCIES
         PRIVATE
+            Gem::Atom_AtomBridge.Static
             Gem::ROSConDemo.Static
             AZ::AzCore
 )

+ 25 - 0
Project/Gem/Source/ROSConDemoSystemComponent.cpp

@@ -2,13 +2,17 @@
 #include <AzCore/Serialization/SerializeContext.h>
 #include <AzCore/Serialization/EditContext.h>
 #include <AzCore/Serialization/EditContextConstants.inl>
+#include <Atom/RPI.Public/FeatureProcessorFactory.h>
 
 #include "ROSConDemoSystemComponent.h"
+#include "SunShaftsFeatureProcessor.h"
 
 namespace ROSConDemo
 {
     void ROSConDemoSystemComponent::Reflect(AZ::ReflectContext* context)
     {
+        SunShaftsFeatureProcessor::Reflect(context);
+
         if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
         {
             serialize->Class<ROSConDemoSystemComponent, AZ::Component>()
@@ -38,6 +42,7 @@ namespace ROSConDemo
 
     void ROSConDemoSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
     {
+        required.push_back(AZ_CRC("AtomBridgeService"));
     }
 
     void ROSConDemoSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
@@ -66,11 +71,31 @@ namespace ROSConDemo
 
     void ROSConDemoSystemComponent::Activate()
     {
+
         ROSConDemoRequestBus::Handler::BusConnect();
+
+        AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<SunShaftsFeatureProcessor>();
+
+        auto* passSystem = AZ::RPI::PassSystemInterface::Get();
+        AZ_Assert(passSystem, "Cannot get the pass system.");
+
+        // Setup handler for load pass templates mappings
+        m_loadTemplatesHandler = AZ::RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler(
+            [passSystem]()
+            {
+                const char* passTemplatesFile = "Passes/SunShaftsPassTemplates.azasset";
+                passSystem->LoadPassTemplateMappings(passTemplatesFile);
+            });
+        //passSystem->AddPassCreator(AZ::Name("SunShaftsFullScreenPass"), &SunShaftsFullScreenPass::Create);
+        passSystem->ConnectEvent(m_loadTemplatesHandler);
     }
 
     void ROSConDemoSystemComponent::Deactivate()
     {
+        AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<SunShaftsFeatureProcessor>();
+
+        m_loadTemplatesHandler.Disconnect();
+
         ROSConDemoRequestBus::Handler::BusDisconnect();
     }
 }

+ 5 - 0
Project/Gem/Source/ROSConDemoSystemComponent.h

@@ -2,6 +2,7 @@
 #pragma once
 
 #include <AzCore/Component/Component.h>
+#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
 
 #include <ROSConDemo/ROSConDemoBus.h>
 
@@ -36,5 +37,9 @@ namespace ROSConDemo
         void Activate() override;
         void Deactivate() override;
         ////////////////////////////////////////////////////////////////////////
+
+    private:
+        //! Used for loading the pass templates
+        AZ::RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler m_loadTemplatesHandler;
     };
 }

+ 134 - 0
Project/Gem/Source/SunShaftsFeatureProcessor.cpp

@@ -0,0 +1,134 @@
+/*
+ * 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 <AzCore/Serialization/SerializeContext.h>
+#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
+#include <Atom/RPI.Public/RenderPipeline.h>
+#include <Atom/RPI.Public/Pass/PassFilter.h>
+#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
+
+#include "SunShaftsFeatureProcessor.h"
+
+namespace ROSConDemo
+{
+    SunShaftsFeatureProcessor::SunShaftsFeatureProcessor()
+    {
+    }
+
+    SunShaftsFeatureProcessor::~SunShaftsFeatureProcessor()
+    {
+    }
+
+    void SunShaftsFeatureProcessor::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext
+                ->Class<SunShaftsFeatureProcessor, AZ::RPI::FeatureProcessor>()
+                ->Version(1);
+        }
+    }
+
+    void SunShaftsFeatureProcessor::Activate()
+    {
+        EnableSceneNotification();
+    }
+
+    void SunShaftsFeatureProcessor::Deactivate()
+    {
+        DisableSceneNotification();
+    }
+
+    void AddPassRequestToRenderPipeline(
+        AZ::RPI::RenderPipeline* renderPipeline,
+        const char* passRequestAssetFilePath,
+        const char* referencePass, bool beforeReferencePass)
+    {
+        auto passRequestAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::AnyAsset>(
+            passRequestAssetFilePath, AZ::RPI::AssetUtils::TraceLevel::Warning);
+        const AZ::RPI::PassRequest* passRequest = nullptr;
+        if (!passRequestAsset)
+        {
+            AZ_Error("SunShafts", false, "Failed to load PassRequestAsset from %s", passRequestAssetFilePath);
+            return;
+        }
+        if (passRequestAsset->IsReady())
+        {
+            passRequest = passRequestAsset->GetDataAs<AZ::RPI::PassRequest>();
+        }
+        if (!passRequest)
+        {
+            AZ_Error("SunShafts", false, "Can't load PassRequest from %s", passRequestAssetFilePath);
+            return;
+        }
+
+        // Return if the pass to be created already exists
+        AZ::RPI::PassFilter passFilter = AZ::RPI::PassFilter::CreateWithPassName(passRequest->m_passName, renderPipeline);
+        AZ::RPI::Pass* existingPass = AZ::RPI::PassSystemInterface::Get()->FindFirstPass(passFilter);
+        if (existingPass)
+        {
+            return;
+        }
+
+        // Create the pass
+        AZ::RPI::Ptr<AZ::RPI::Pass> newPass = AZ::RPI::PassSystemInterface::Get()->CreatePassFromRequest(passRequest);
+        if (!newPass)
+        {
+            AZ_Error("SunShafts", false, "Failed to create the pass from pass request [%s].", passRequest->m_passName.GetCStr());
+            return;
+        }
+
+        // Add the pass to render pipeline
+        bool success;
+        if (beforeReferencePass)
+        {
+            success = renderPipeline->AddPassBefore(newPass, AZ::Name(referencePass));
+        }
+        else
+        {
+            success = renderPipeline->AddPassAfter(newPass, AZ::Name(referencePass));
+        }
+        // only create pass resources if it was success
+        if (!success)
+        {
+            AZ_Error(
+                "SunShafts", false, "Failed to add pass [%s] to render pipeline [%s].", newPass->GetName().GetCStr(),
+                renderPipeline->GetId().GetCStr());
+        }
+    }
+
+    void SunShaftsFeatureProcessor::ApplyRenderPipelineChange(AZ::RPI::RenderPipeline* renderPipeline)
+    {
+        AddPassRequestToRenderPipeline(renderPipeline, "Passes/SunShaftsFullScreenPassRequest.azasset", "SkyBoxPass", /*before*/ true);
+    }
+
+    void SunShaftsFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
+    {
+        AZ_PROFILE_FUNCTION(AzRender);
+        AZ_UNUSED(packet);
+    }
+
+    void SunShaftsFeatureProcessor::Render([[maybe_unused]] const FeatureProcessor::RenderPacket& packet)
+    {
+        AZ_PROFILE_FUNCTION(AzRender);
+    }
+
+    void SunShaftsFeatureProcessor::OnRenderPipelineAdded([[maybe_unused]] AZ::RPI::RenderPipelinePtr renderPipeline)
+    {
+    }
+
+    void SunShaftsFeatureProcessor::OnRenderPipelineRemoved([[maybe_unused]] AZ::RPI::RenderPipeline* renderPipeline)
+    {
+    }
+
+    void SunShaftsFeatureProcessor::OnRenderPipelinePassesChanged([[maybe_unused]] AZ::RPI::RenderPipeline* renderPipeline)
+    {
+    }
+
+} // namespace ROSConDemo
+
+//#pragma optimize("", on)

+ 34 - 0
Project/Gem/Source/SunShaftsFeatureProcessor.h

@@ -0,0 +1,34 @@
+
+#pragma once
+
+#include <Atom/RPI.Public/FeatureProcessor.h>
+
+namespace ROSConDemo
+{
+    class SunShaftsFeatureProcessor final
+        : public AZ::RPI::FeatureProcessor
+    {
+    public:
+        AZ_RTTI(ROSConDemo::SunShaftsFeatureProcessor, "{C5775AB6-D38D-44C4-A526-A4F9E0BC7B8B}", AZ::RPI::FeatureProcessor);
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        SunShaftsFeatureProcessor();
+        virtual ~SunShaftsFeatureProcessor();
+
+        //! RPI::FeatureProcessor
+        void Activate() override;
+        void Deactivate() override;
+        void ApplyRenderPipelineChange(AZ::RPI::RenderPipeline* renderPipeline) override;
+        void Simulate(const FeatureProcessor::SimulatePacket& packet) override;
+        void Render(const FeatureProcessor::RenderPacket& packet) override;
+
+        //! RPI::SceneNotificationBus
+        void OnRenderPipelineAdded(AZ::RPI::RenderPipelinePtr renderPipeline) override;
+        void OnRenderPipelineRemoved(AZ::RPI::RenderPipeline* renderPipeline) override;
+        void OnRenderPipelinePassesChanged(AZ::RPI::RenderPipeline* renderPipeline) override;
+
+    private:
+        AZ_DISABLE_COPY_MOVE(SunShaftsFeatureProcessor);
+    };
+}

+ 2 - 0
Project/Gem/roscondemo_files.cmake

@@ -3,5 +3,7 @@ set(FILES
     Include/ROSConDemo/ROSConDemoBus.h
     Source/ROSConDemoSystemComponent.cpp
     Source/ROSConDemoSystemComponent.h
+    Source/SunShaftsFeatureProcessor.cpp
+    Source/SunShaftsFeatureProcessor.h
     enabled_gems.cmake
 )

+ 36 - 0
Project/Passes/SunShaftsFullScreenPass.pass

@@ -0,0 +1,36 @@
+{
+    "Type": "JsonSerialization",
+    "Description" : "This is the pass template that renders a full screen triangle",
+    "Version": 1,
+    "ClassName": "PassAsset",
+    "ClassData": {
+        "PassTemplate": {
+            "Name": "SunShaftsFullScreenPassTemplate",
+            "PassClass": "FullScreenTriangle",
+            "Slots": [
+                {
+                    "Name": "SpecularInputOutput",
+                    "SlotType": "InputOutput",
+                    "ScopeAttachmentUsage": "RenderTarget"
+                },
+                {
+                    "Name": "ReflectionInputOutput",
+                    "SlotType": "InputOutput",
+                    "ScopeAttachmentUsage": "RenderTarget"
+                },
+                {
+                    "Name": "DepthStencilInputOutput",
+                    "SlotType": "InputOutput",
+                    "ScopeAttachmentUsage": "DepthStencil"
+                }
+            ],
+            "PassData": {
+                "$type": "FullscreenTrianglePassData",
+                "ShaderAsset": {
+                    "FilePath": "Shaders/SunShaftsFullScreen.shader"
+                },
+                "PipelineViewTag": "MainCamera"
+            }
+        }
+    }
+}

+ 33 - 0
Project/Passes/SunShaftsFullScreenPassRequest.azasset

@@ -0,0 +1,33 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "PassRequest",
+    "ClassData": {
+        "Name": "SunShaftsFullscreenPass",
+        "TemplateName": "SunShaftsFullScreenPassTemplate",
+        "Enabled": true,
+        "Connections": [
+            {
+                "LocalSlot": "SpecularInputOutput",
+                "AttachmentRef": {
+                    "Pass": "ReflectionsPass",
+                    "Attachment": "SpecularInputOutput"
+                }
+            },
+            {
+                "LocalSlot": "ReflectionInputOutput",
+                "AttachmentRef": {
+                    "Pass": "ReflectionsPass",
+                    "Attachment": "ReflectionOutput"
+                }
+            },
+            {
+                "LocalSlot": "DepthStencilInputOutput",
+                "AttachmentRef": {
+                    "Pass": "ReflectionsPass",
+                    "Attachment": "DepthStencilInputOutput"
+                }
+            }
+        ]
+    }
+}

+ 13 - 0
Project/Passes/SunShaftsPassTemplates.azasset

@@ -0,0 +1,13 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "AssetAliasesSourceData",
+    "ClassData": {
+        "AssetPaths": [
+            {
+                "Name": "SunShaftsFullScreenPassTemplate",
+                "Path": "Passes/SunShaftsFullScreenPass.pass"
+            }
+        ]
+    }
+}

+ 6 - 1
Project/Registry/assetprocessor_settings.setreg

@@ -16,7 +16,12 @@
                     "watch": "@PROJECTROOT@/Registry",
                     "recursive": 1,
                     "order": 3
-                }
+                },
+                "ScanFolder Project/Passes": {
+                    "watch": "@PROJECTROOT@/Passes",
+                    "recurisve": 1,
+                    "order": 4
+                },
             }
         }
     }

+ 51 - 0
Project/Shaders/SunShaftsFullScreen.azsl

@@ -0,0 +1,51 @@
+/*
+* Modifications 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) AND MIT
+*
+*/
+
+#include <viewsrg.srgi>
+#include <Atom/Features/SrgSemantics.azsli>
+#include <Atom/Features/ColorManagement/TransformColor.azsli>
+#include <Atom/RPI/Math.azsli>
+
+ShaderResourceGroup PassSrg : SRG_PerPass
+{
+    Sampler LinearSampler
+    {
+        MinFilter = Linear;
+        MagFilter = Linear;
+        MipFilter = Linear;
+        AddressU = Clamp;
+        AddressV = Clamp;
+        AddressW = Clamp;
+    };
+
+    // TODO add texture inputs
+}
+
+#include <Atom/Features/PostProcessing/FullscreenVertex.azsli> // provides MainVS vertex shader
+
+struct PSOutput
+{
+    float4 m_specular : SV_Target0;
+    float4 m_reflection : SV_Target1;
+};
+
+
+PSOutput MainPS(VSOutput IN)
+{
+    PSOutput OUT = (PSOutput)0;
+
+    const float depth = 1.f; // PassSrg::m_depth.Load(Input.m_position.xy, sampleIndex).r;
+
+    OUT.m_specular = float4(1.0,0.0,0.0,1.0);
+    OUT.m_reflection = float4(1.0,0.0,0.0,1.0);
+
+    OUT.m_specular = float4(0.0,0.0,0.0,0.0);
+    OUT.m_reflection = float4(0.0,0.0,0.0,0.0);
+
+    return OUT;
+}

+ 30 - 0
Project/Shaders/SunShaftsFullScreen.shader

@@ -0,0 +1,30 @@
+{ 
+    "Source" : "SunShaftsFullScreen.azsl",
+
+    "DepthStencilState" : 
+    {
+        "Depth" : 
+        { 
+            "Enable" : false
+        },
+        "Stencil" :
+        {
+            "Enable" : false
+        }
+    },
+
+    "ProgramSettings":
+    {
+      "EntryPoints":
+      [
+        {
+          "name": "MainVS",
+          "type": "Vertex"
+        },
+        {
+          "name": "MainPS",
+          "type": "Fragment"
+        }
+      ]
+    }
+}