diff --git a/Assets/Materials/Silhouette.shmat b/Assets/Materials/Silhouette.shmat new file mode 100644 index 00000000..912775f0 --- /dev/null +++ b/Assets/Materials/Silhouette.shmat @@ -0,0 +1,8 @@ +- VertexShader: 38847805 + FragmentShader: 42962441 + SubPass: Object VFX Subpass No Depth + Properties: + data.color: {x: 1, y: 1, z: 1, w: 1} + data.textureIndex: 0 + data.alpha: 0 + data.beta: {x: 1, y: 1, z: 1} \ No newline at end of file diff --git a/Assets/Materials/Silhouette.shmat.shmeta b/Assets/Materials/Silhouette.shmat.shmeta new file mode 100644 index 00000000..be1f7bde --- /dev/null +++ b/Assets/Materials/Silhouette.shmat.shmeta @@ -0,0 +1,3 @@ +Name: Silhouette +ID: 126391182 +Type: 7 diff --git a/Assets/Shaders/Silhouette_FS.glsl b/Assets/Shaders/Silhouette_FS.glsl new file mode 100644 index 00000000..292bdfe7 --- /dev/null +++ b/Assets/Shaders/Silhouette_FS.glsl @@ -0,0 +1,67 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable +#extension GL_EXT_nonuniform_qualifier : require + +struct MatPropData +{ + vec4 color; +}; + +struct GenericData +{ + //! Delta time + float dt; + + //! Elapsed time of the application + float elapsedTime; + + //! Viewport width of the scene (excluding imgui, that means smaller than window) + uint viewportWidth; + + //! Ditto but for height + uint viewportHeight; +}; + +layout(location = 0) in struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 normal; // location = 2 + vec4 worldPos; // location = 3 +} In; + +// material stuff +layout(location = 4) flat in struct +{ + int materialIndex; + uint eid; + uint lightLayerIndex; +} In2; + +layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials +{ + MatPropData data[]; +} MatProp; + +layout (set = 0, binding = 0) uniform GenericDataBuffer +{ + GenericData data; +} genericDataBuffer; + +layout(location = 0) out vec4 objectVFX; +layout(input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput depthBuffer; + +void main() +{ + // Sample depth buffer using UV and save it + float currentDepth = subpassLoad (depthBuffer).r; + + // Use depth buffer to check against current fragment's depth. If fragment is behind depth buffer, render fragment. + if (currentDepth > gl_FragCoord.z) + discard; + + objectVFX = MatProp.data[In2.materialIndex].color; + +} \ No newline at end of file diff --git a/Assets/Shaders/Silhouette_FS.shshaderb b/Assets/Shaders/Silhouette_FS.shshaderb new file mode 100644 index 00000000..4710b8a6 Binary files /dev/null and b/Assets/Shaders/Silhouette_FS.shshaderb differ diff --git a/Assets/Shaders/Silhouette_FS.shshaderb.shmeta b/Assets/Shaders/Silhouette_FS.shshaderb.shmeta new file mode 100644 index 00000000..e094c1d6 --- /dev/null +++ b/Assets/Shaders/Silhouette_FS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: Silhouette_FS +ID: 42962441 +Type: 2 diff --git a/Assets/Shaders/Silhouette_VS.glsl b/Assets/Shaders/Silhouette_VS.glsl new file mode 100644 index 00000000..1b45c333 --- /dev/null +++ b/Assets/Shaders/Silhouette_VS.glsl @@ -0,0 +1,68 @@ +#version 450 +#extension GL_KHR_vulkan_glsl : enable + +//#include "ShaderDescriptorDefinitions.glsl" + + +layout(location = 0) in vec3 aVertexPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec3 aNormal; +layout(location = 3) in vec3 aTangent; +layout(location = 4) in mat4 worldTransform; +layout(location = 8) in uvec2 integerData; +layout(location = 9) in uvec4 aBoneIndices; +layout(location = 10) in vec4 aBoneWeights; +layout(location = 11) in uint firstBoneIndex; + +layout(location = 0) out struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 normal; // location = 2 + vec4 worldPos; // location = 3 + +} Out; + +// material stuff +layout(location = 4) out struct +{ + int materialIndex; + uint eid; + uint lightLayerIndex; + +} Out2; + +layout(set = 1, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; + mat4 viewMat; + mat4 projMat; +} cameraData; + +void main() +{ + Out2.materialIndex = gl_InstanceIndex; + Out2.eid = integerData[0]; + Out2.lightLayerIndex = integerData[1]; + + // for transforming gBuffer position and normal data + mat4 modelViewMat = cameraData.viewMat * worldTransform; + + // gBuffer position will be in view space + Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f); + + Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f); + + // uvs for texturing in fragment shader + Out.uv = aUV; + + mat3 transposeInv = mat3 (transpose(inverse(modelViewMat))); + + // normals are also in view space + Out.normal.rgb = transposeInv * aNormal.rgb; + Out.normal.rgb = normalize (Out.normal.rgb); + + // clip space for rendering + gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); +} \ No newline at end of file diff --git a/Assets/Shaders/Silhouette_VS.shshaderb b/Assets/Shaders/Silhouette_VS.shshaderb new file mode 100644 index 00000000..1bb76ec4 Binary files /dev/null and b/Assets/Shaders/Silhouette_VS.shshaderb differ diff --git a/Assets/Shaders/Silhouette_VS.shshaderb.shmeta b/Assets/Shaders/Silhouette_VS.shshaderb.shmeta new file mode 100644 index 00000000..508a8788 --- /dev/null +++ b/Assets/Shaders/Silhouette_VS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: Silhouette_VS +ID: 38847805 +Type: 2 diff --git a/Assets/Shaders/ToSwapchain_FS.glsl b/Assets/Shaders/ToSwapchain_FS.glsl index 3cf1752f..d353c15f 100644 --- a/Assets/Shaders/ToSwapchain_FS.glsl +++ b/Assets/Shaders/ToSwapchain_FS.glsl @@ -3,7 +3,7 @@ #extension GL_ARB_shading_language_420pack : enable #extension GL_EXT_nonuniform_qualifier : require -layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput sceneTexture; +layout (input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput sceneTexture; layout(location = 0) out vec4 fragColor; diff --git a/Assets/Shaders/ToSwapchain_FS.shshaderb b/Assets/Shaders/ToSwapchain_FS.shshaderb index 0bee0ac6..24cb54fe 100644 Binary files a/Assets/Shaders/ToSwapchain_FS.shshaderb and b/Assets/Shaders/ToSwapchain_FS.shshaderb differ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index 63b39c9f..85559bc7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -25,9 +25,10 @@ namespace SHADE { perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings ({ - {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, - {SHPredefinedDescriptorTypes::CAMERA, 1}, - {SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2}, + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::CAMERA, 1}, + {SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2}, + {SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3}, }); perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index 38fe9aa3..54b02608 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -129,11 +129,13 @@ namespace SHADE static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write"; static constexpr std::string_view UI_SUBPASS = "UI"; static constexpr std::string_view VFX_SUBPASS = "VFX"; + static constexpr std::string_view OBJ_VFX_SUBPASS = "Object VFX Subpass No Depth"; static constexpr std::array USABLE_SUBPASSES = { GBUFFER_WRITE_SUBPASS, - UI_SUBPASS + UI_SUBPASS, + OBJ_VFX_SUBPASS }; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 70a7d34f..ebd9ba8c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -215,7 +215,7 @@ namespace SHADE renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second); - renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second); @@ -255,7 +255,13 @@ namespace SHADE gBufferSubpass->AddColorOutput("Object VFX"); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); - usableSubpassesMapping.emplace (std::string (SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass); + // We add the object VFX render target and depth buffer as input just in case we want to make comparisons + auto objectVfxSubpassNoDepth = gBufferNode->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data(), worldViewport, worldRenderer); + objectVfxSubpassNoDepth->AddColorOutput("Object VFX"); + objectVfxSubpassNoDepth->AddInput ("Depth Buffer"); + + usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass); + usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data()), objectVfxSubpassNoDepth); /*-----------------------------------------------------------------------*/ /* SSAO PASS AND DATA INIT */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 654cae77..ea650274 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -512,8 +512,9 @@ namespace SHADE uint32_t h = static_cast(resource->GetHeight()); cmdBuffer->SetViewportScissor(static_cast(w), static_cast(h), w, h); - static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0; - newSubpass->BindInputDescriptorSets (cmdBuffer, INPUT_IMAGE_SET_INDEX, frameIndex); + //static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0; + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + newSubpass->BindInputDescriptorSets (cmdBuffer, mappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex); // draw a quad. cmdBuffer->DrawArrays(4, 1, 0, 0); @@ -570,9 +571,10 @@ namespace SHADE auto cmdBuffer = commandBuffers[frameIndex]; cmdBuffer->BeginLabeledSegment(name); - auto batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING); + auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING); - // Force bind pipeline layout + + // Force bind pipeline layout cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS); cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index b032ca1e..e5cc231c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -184,12 +184,13 @@ namespace SHADE for (auto& inputAtt : subpass->inputReferences) { auto resource = attResources[inputAtt.attachment]; - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) + auto typeFlags = resource->resourceTypeFlags; + if (typeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) { - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || - resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) + if (typeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || + typeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) colorRead |= (1 << i); - else if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL)) + else if (typeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL) || typeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH)) depthRead |= (1 << i); } else @@ -265,6 +266,7 @@ namespace SHADE // initialize input descriptors subpasses[i]->CreateInputDescriptors(); + subpasses[i]->GenerateDummyPipielineLayout(); ++i; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 96207d7a..d45789ce 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -226,11 +226,15 @@ namespace SHADE commandBuffer->SetViewportScissor(static_cast(w), static_cast(h), w, h); } + commandBuffer->ForceSetPipelineLayout(dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS); + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); if (renderer) renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); + BindInputDescriptorSets (commandBuffer, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex); + // If companion subpass is not a valid handle, render super batch normally if (!companionSubpass.companion) { @@ -439,6 +443,33 @@ namespace SHADE } } + /***************************************************************************/ + /*! + + \brief + Generates the dummy pipeline layout for subpass; specifically add the + input descriptor set layout if it exists. + + + \return + + */ + /***************************************************************************/ + void SHSubpass::GenerateDummyPipielineLayout(void) noexcept + { + auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING); + std::vector newLayouts = batchingSystemData.descSetLayouts; + if (inputDescriptorLayout) + { + newLayouts.push_back(inputDescriptorLayout); + } + + dummyPipelineLayout = graphStorage->logicalDevice->CreatePipelineLayoutDummy + ( + SHPipelineLayoutParamsDummy{ newLayouts } + ); + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 811cc70c..1300ee2b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -22,6 +22,7 @@ namespace SHADE class SHRenderer; class SHViewport; class SHVkPipeline; + class SHVkPipelineLayout; class SH_API SHSubpass : public ISelfHandle { @@ -87,6 +88,12 @@ namespace SHADE std::vector> inputSamplers; + //! Dummy pipeline layout for subpass to bind before draw. + //! // IMPORTANT NOTE: After implementing input descriptors, every subpass differs in number input descriptors. + //! Before binding the input descriptors, a pipeline layout containing the desc set layouts + //! for the input descriptors is required, making this umbrella initial dummy bind invalid. + Handle dummyPipelineLayout; + ////! subpass compute image barriers. We do this because every frame has a different ////! swapchain image. If the resource we want to transition is not a swapchain image, @@ -146,6 +153,7 @@ namespace SHADE //void InitComputeBarriers (void) noexcept; void CreateInputDescriptors (void) noexcept; void UpdateWriteDescriptors (void) noexcept; + void GenerateDummyPipielineLayout (void) noexcept; private: /*-----------------------------------------------------------------------*/