diff --git a/Assets/Shaders/Trajectory_FS.glsl b/Assets/Shaders/Trajectory_FS.glsl new file mode 100644 index 00000000..4e36dfd9 --- /dev/null +++ b/Assets/Shaders/Trajectory_FS.glsl @@ -0,0 +1,22 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable +#extension GL_EXT_nonuniform_qualifier : require + + +layout(location = 0) in struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 color; // location = 2 + +} In; + +layout(location = 0) out vec4 fragColor; + + +void main() +{ + // default red first + fragColor = In.color; +} \ No newline at end of file diff --git a/Assets/Shaders/Trajectory_VS.glsl b/Assets/Shaders/Trajectory_VS.glsl new file mode 100644 index 00000000..6d932734 --- /dev/null +++ b/Assets/Shaders/Trajectory_VS.glsl @@ -0,0 +1,36 @@ +#version 450 +#extension GL_KHR_vulkan_glsl : enable + +// vertex inputs +layout(location = 0) in vec4 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec2 aColor; +layout(location = 3) in mat4 aTransform; + +// between shader stages +layout(location = 0) out struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 color; // location = 2 + +} Out; + + +// Camera data +layout(set = 1, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; + mat4 viewMat; + mat4 projMat; +} cameraData; + + +void main() +{ + Out.uv = aUV; + Out.color = aColor; + + gl_Position = cameraData.projMat * aTransform * vec4(aPos, 1.0f); +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index e65f5c8f..63b39c9f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -52,6 +52,12 @@ namespace SHADE {SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3}, {SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE, 4}, }); + + perSystemData[SHUtilities::ConvertEnum(SystemType::TRAJECTORY_RENDERING)].descMappings.AddMappings + ({ + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::CAMERA, 1}, + }); } void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle logicalDevice) noexcept @@ -222,6 +228,12 @@ namespace SHADE SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA | SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS ); + + perSystemData[SHUtilities::ConvertEnum(SystemType::TRAJECTORY_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts + ( + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA + ); } void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h index 43a4a55c..77307f57 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h @@ -38,6 +38,7 @@ namespace SHADE BATCHING_ANIM, TEXT_RENDERING, RENDER_GRAPH_NODE_COMPUTE, + TRAJECTORY_RENDERING, NUM_TYPES }; static constexpr int SYSTEM_TYPE_COUNT = static_cast(SystemType::NUM_TYPES); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index fdad3584..569818b9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -282,6 +282,13 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8; + /***************************************************************************/ + /*! + \brief + Vertex buffer bindings for color + */ + /***************************************************************************/ + static constexpr uint32_t TRAJECTORY_COLOR = 2; static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0; static constexpr uint32_t GLYPH_INDEX = 1; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index ef68a356..7d783490 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -433,6 +433,11 @@ namespace SHADE auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data()); textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::UI_SUBPASS), descPool, textVS, textFS); + trajectoryRenderingSubSystem = resourceManager.Create(); + + //auto gBufferNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data()); + //trajectoryRenderingSubSystem->Init(device, ) + SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem); } @@ -589,19 +594,19 @@ namespace SHADE static bool shadowAdded = false; - if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)) - { - shadowAdded = true; - auto& lightComps = SHComponentManager::GetDense(); - //if (lightComps.size() > 2) - //{ - // lightComps[2].SetEnableShadow(true); - //} - for (auto& comp : lightComps) - { - comp.SetEnableShadow(true); - } - } + //if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)) + //{ + // shadowAdded = true; + // auto& lightComps = SHComponentManager::GetDense(); + // //if (lightComps.size() > 2) + // //{ + // // lightComps[2].SetEnableShadow(true); + // //} + // for (auto& comp : lightComps) + // { + // comp.SetEnableShadow(true); + // } + //} renderGraph->Begin(frameIndex); auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index a35065bd..0576233f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -36,6 +36,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h" #include "Graphics/MiddleEnd/Interface/SHRenderer.h" #include "Graphics/Events/SHGraphicsEvents.h" +#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h" namespace SHADE { @@ -505,6 +506,7 @@ namespace SHADE Handle postOffscreenRenderSubSystem; Handle lightingSubSystem; Handle textRenderingSubSystem; + Handle trajectoryRenderingSubSystem; Handle ssaoStorage; uint32_t resizeWidth = 1; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp new file mode 100644 index 00000000..9401d076 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp @@ -0,0 +1,91 @@ +#include "SHpch.h" +#include "SHTrajectoryRenderableComponent.h" + +namespace SHADE +{ + + /***************************************************************************/ + /*! + + \brief + On create the text has nothing. + + */ + /***************************************************************************/ + void SHTrajectoryRenderableComponent::OnCreate(void) + { + } + + void SHTrajectoryRenderableComponent::OnDestroy(void) + { + + } + + + void SHTrajectoryRenderableComponent::ClearPositions(void) noexcept + { + positions.clear(); + } + + bool SHTrajectoryRenderableComponent::HasPositions(void) const noexcept + { + return !positions.empty(); + } + + std::vector SHTrajectoryRenderableComponent::GetPositions(void) const noexcept + { + return positions; + } + + Handle SHTrajectoryRenderableComponent::GetMesh(void) const noexcept + { + return mesh; + } + + SHVec4 const& SHTrajectoryRenderableComponent::GetStartColor(void) const noexcept + { + return startColor; + } + + SHVec4 const& SHTrajectoryRenderableComponent::GetEndColor(void) const noexcept + { + return endColor; + } + + float SHTrajectoryRenderableComponent::GetColorEvolveRate(void) const noexcept + { + return colorEvolveRate; + } + + void SHTrajectoryRenderableComponent::SetMesh(Handle newMesh) noexcept + { + mesh = newMesh; + } + + void SHTrajectoryRenderableComponent::SetStartColor(SHVec4 color) noexcept + { + startColor = color; + } + + void SHTrajectoryRenderableComponent::SetEndColor(SHVec4 color) noexcept + { + endColor = color; + + } + + void SHTrajectoryRenderableComponent::SetColorEvolveRate(float rate) noexcept + { + colorEvolveRate = rate; + } + +} + +namespace rttr +{ + RTTR_REGISTRATION + { + using namespace SHADE; + + registration::class_("Trajectory Renderer Component"); + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h new file mode 100644 index 00000000..ac0343d4 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Math/Vector/SHVec3.h" +#include "Math/Vector/SHVec4.h" +#include "Resource/SHHandle.h" +#include "ECS_Base/Components/SHComponent.h" +#include + +namespace SHADE +{ + class SHMesh; + + class SHTrajectoryRenderableComponent : public SHComponent + { + private: + + //! Mesh used to render the trajectory + Handle mesh; + + //! positions to plot for rendering. Will be cleared every frame. + std::vector positions; + + //! Starting color of the trajectory + SHVec4 startColor; + + //! Color the trajectory should evolve to the longer it is + SHVec4 endColor; + + //! evolving rate of the color (with respect to dt) + float colorEvolveRate; + + public: + /*-----------------------------------------------------------------------*/ + /* PRIVATE MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void SetMesh(Handle newMesh) noexcept; + void SetStartColor(SHVec4 startColor) noexcept; + void SetEndColor (SHVec4 endColor) noexcept; + void SetColorEvolveRate (float rate) noexcept; + + std::vector GetPositions (void) const noexcept; + Handle GetMesh (void) const noexcept; + SHVec4 const& GetStartColor (void) const noexcept; + SHVec4 const& GetEndColor (void) const noexcept; + float GetColorEvolveRate (void) const noexcept; + + void OnCreate(void) override final; + void OnDestroy(void) override final; + + void ClearPositions(void) noexcept; + bool HasPositions(void) const noexcept; + + + RTTR_ENABLE() + + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp new file mode 100644 index 00000000..9eaca200 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp @@ -0,0 +1,179 @@ +#include "SHpch.h" +#include "SHTrajectoryRenderingSubSystem.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Graphics\MiddleEnd\Interface\SHMeshLibrary.h" +#include "Graphics/SHVkUtil.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "Graphics/RenderGraph/SHSubpass.h" +#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" + +namespace SHADE +{ + + + void SHTrajectoryRenderingSubSystem::Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle trajectoryVS, Handle trajectoryFS) noexcept + { + logicalDevice = device; + + SHComponentManager::CreateComponentSparseSet(); + + // prepare pipeline layout params + SHPipelineLayoutParams plParams + { + .shaderModules = {trajectoryVS, trajectoryFS}, + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::TRAJECTORY_RENDERING).descSetLayouts + }; + + pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); + + // Create pipeline + pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, compatibleRenderpass, subpass); + + // vertex input state of the pipeline + SHVertexInputState vertexInputState; + vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute positions at binding 0 + vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // Attribute uv at binding 1 + vertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Instanced attribute color at binding 2 + vertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Instanced Transform at binding 3 - 6 (4 slots) + + pipeline->GetPipelineState().SetVertexInputState(vertexInputState); + + SHColorBlendState colorBlendState{}; + colorBlendState.logic_op_enable = VK_FALSE; + colorBlendState.logic_op = vk::LogicOp::eCopy; + + + auto const& subpassColorReferences = subpass->GetColorAttachmentReferences(); + colorBlendState.attachments.reserve(static_cast(subpassColorReferences.size())); + + for (auto& att : subpassColorReferences) + { + colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState + { + .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, + .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, + .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, + .colorBlendOp = vk::BlendOp::eAdd, + .srcAlphaBlendFactor = vk::BlendFactor::eOne, + .dstAlphaBlendFactor = vk::BlendFactor::eZero, + .alphaBlendOp = vk::BlendOp::eAdd, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, + } + ); + } + + pipeline->GetPipelineState().SetColorBlenState(colorBlendState); + } + + void SHTrajectoryRenderingSubSystem::Run(uint32_t frameIndex, float dt) noexcept + { + auto& comps = SHComponentManager::GetDense(); + for (auto& comp : comps) + { + // If has positions, feed data to buffer. + if (comp.HasPositions()) + { + SHTransformComponent* transform = SHComponentManager::GetComponent_s(comp.GetEID()); + if (transform) + { + // convenient variable + SHVec4 const& startColor = comp.GetStartColor(); + SHVec4 const& endColor = comp.GetEndColor(); + float colorEvolveRate = comp.GetColorEvolveRate(); + + // trs to be reused + SHMatrix trs = transform->GetTRS(); + + // starting color of trajectory + SHVec4 currentColor = comp.GetStartColor(); + + // Start from 0 and slowly evolve to 1 + float lerpValue = 0.0f; + + // Will be used for baseInstance later + uint32_t oldTransformDataSize = transformData.size(); + + auto meshHandle = comp.GetMesh(); + + auto const& positions = comp.GetPositions(); + for (auto& pos : positions) + { + // modify position and reuse matrix + trs.m[3][0] = pos.x; + trs.m[3][1] = pos.y; + trs.m[3][2] = pos.z; + + transformData.push_back(trs); + colorData.push_back(currentColor); + + // evolve color + currentColor = SHVec4::Lerp(startColor, endColor, lerpValue); + + // evolve lerp value and clamp to 1 + lerpValue = std::max (1.0f, lerpValue + (colorEvolveRate * dt)); + } + + // add draw data for this trajectory + drawData.push_back(vk::DrawIndexedIndirectCommand + { + .indexCount = meshHandle->IndexCount, + .instanceCount = static_cast(transformData.size()) - oldTransformDataSize, + .firstIndex = meshHandle->FirstIndex, + .vertexOffset = meshHandle->FirstVertex, + .firstInstance = oldTransformDataSize + }); + } + } + + // clear at the end of every frame since data is already in buffers + comp.ClearPositions(); + } + + // read transform data to buffer + // read draw data to buffer + SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, transformBuffer, transformData.data(), sizeof (SHMatrix) * transformData.size(), vk::BufferUsageFlagBits::eVertexBuffer, "Trajectory System Transform Buffer"); + + SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, drawDataBuffer, drawData.data(), sizeof(vk::DrawIndexedIndirectCommand) * drawData.size(), vk::BufferUsageFlagBits::eIndirectBuffer, "Trajectory System Draw Data Buffer"); + + SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, colorBuffer, colorData.data(), sizeof(SHVec4) * colorData.size(), vk::BufferUsageFlagBits::eVertexBuffer, "Trajectory System Color Data Buffer"); + + } + + void SHTrajectoryRenderingSubSystem::Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept + { + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::TRAJECTORY_RENDERING); + uint32_t staticGlobalSetIndex = mappings.at(SHPredefinedDescriptorTypes::STATIC_DATA); + uint32_t cameraSetIndex = mappings.at(SHPredefinedDescriptorTypes::CAMERA); + + cmdBuffer->BindPipeline(pipeline); + + // Bind global data + SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex); + + // Bind camera data + renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex); + + // Bind color vertex buffer + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRAJECTORY_COLOR, colorBuffer, 0); + + // call draw call + cmdBuffer->DrawMultiIndirect(drawDataBuffer, drawData.size()); + + // clear CPU transform and draw data + transformData.clear(); + drawData.clear(); + colorData.clear(); + + } + + void SHTrajectoryRenderingSubSystem::Exit(void) noexcept + { + + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h new file mode 100644 index 00000000..2bba5703 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h @@ -0,0 +1,66 @@ +#pragma once + +#include "Resource/SHHandle.h" +#include "Graphics/Pipeline/SHPipelineState.h" +#include "Math/SHMatrix.h" + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkDescriptorPool; + class SHVkDescriptorSetGroup; + class SHVkDescriptorSetLayout; + class SHVkBuffer; + class SHLightComponent; + class SHVkCommandBuffer; + class SHVkPipeline; + class SHVkPipelineLayout; + class SHVkRenderpass; + class SHSubpass; + class SHVkShaderModule; + class SHRenderer; + + + + class SHTrajectoryRenderingSubSystem + { + private: + + Handle logicalDevice; + + //! Every trajectory renderable will have one of these + std::vector drawData; + + //! For the MDI call + Handle drawDataBuffer; + + //! matrix data to copy into buffer + std::vector transformData; + + //! All trajectory renderables will use this transform buffer + Handle transformBuffer; + + //! Each object will have their own color data + std::vector colorData; + + //! buffer to hold color data for objects + Handle colorBuffer; + + //! Pipeline for rendering the trajectories + Handle pipeline; + + //! Pipeline layout for the pipeline + Handle pipelineLayout; + + + + public: + void Init (Handle device, Handle compatibleRenderpass, Handle subpass, Handle textVS, Handle textFS) noexcept; + + void Run(uint32_t frameIndex, float dt) noexcept; + + void Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept; + void Exit(void) noexcept; + + }; +}