From 3eb70400de6f3d6c9ee13412e787cc1c36416027 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Thu, 24 Jun 2021 15:38:40 +0200 Subject: [PATCH] [#82] Added depth prepass, fps go BRRRRRRRRRRRRRRR now --- include/vkcv/PipelineConfig.hpp | 13 ++-- .../resources/shaders/depthPrepass.frag | 7 ++ .../resources/shaders/depthPrepass.vert | 14 ++++ projects/voxelization/src/main.cpp | 73 +++++++++++++++++-- src/vkcv/PipelineManager.cpp | 18 ++++- 5 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 projects/voxelization/resources/shaders/depthPrepass.frag create mode 100644 projects/voxelization/resources/shaders/depthPrepass.vert diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp index c17f04ee..0d29625a 100644 --- a/include/vkcv/PipelineConfig.hpp +++ b/include/vkcv/PipelineConfig.hpp @@ -16,6 +16,7 @@ namespace vkcv { enum class PrimitiveTopology{PointList, LineList, TriangleList }; enum class CullMode{ None, Front, Back }; + enum class DepthTest { None, Less, LessEqual, Greater, GreatherEqual, Equal }; struct PipelineConfig { ShaderProgram m_ShaderProgram; @@ -25,11 +26,13 @@ namespace vkcv { VertexLayout m_VertexLayout; std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts; bool m_UseDynamicViewport; - bool m_UseConservativeRasterization = false; - PrimitiveTopology m_PrimitiveTopology = PrimitiveTopology::TriangleList; - bool m_EnableDepthClamping = false; - Multisampling m_multisampling = Multisampling::None; - CullMode m_culling = CullMode::None; + bool m_UseConservativeRasterization = false; + PrimitiveTopology m_PrimitiveTopology = PrimitiveTopology::TriangleList; + bool m_EnableDepthClamping = false; + Multisampling m_multisampling = Multisampling::None; + CullMode m_culling = CullMode::None; + DepthTest m_depthTest = DepthTest::LessEqual; + bool m_depthWrite = true; }; } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/depthPrepass.frag b/projects/voxelization/resources/shaders/depthPrepass.frag new file mode 100644 index 00000000..65592d2c --- /dev/null +++ b/projects/voxelization/resources/shaders/depthPrepass.frag @@ -0,0 +1,7 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable + +void main() { + +} \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/depthPrepass.vert b/projects/voxelization/resources/shaders/depthPrepass.vert new file mode 100644 index 00000000..d800c547 --- /dev/null +++ b/projects/voxelization/resources/shaders/depthPrepass.vert @@ -0,0 +1,14 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +#extension GL_GOOGLE_include_directive : enable + +layout(location = 0) in vec3 inPosition; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +void main() { + gl_Position = mvp * vec4(inPosition, 1.0); +} \ No newline at end of file diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 59b2d9fb..fa2b921d 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -118,11 +118,12 @@ int main(int argc, const char** argv) { const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; const vkcv::AttachmentDescription depth_attachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, + vkcv::AttachmentOperation::DONT_CARE, + vkcv::AttachmentOperation::LOAD, depthBufferFormat ); - + + // forward shading config vkcv::PassConfig forwardPassDefinition({ color_attachment, depth_attachment }, msaa); vkcv::PassHandle forwardPass = core.createPass(forwardPassDefinition); @@ -149,6 +150,48 @@ int main(int argc, const char** argv) { vkcv::DescriptorSetHandle forwardShadingDescriptorSet = core.createDescriptorSet({ forwardProgram.getReflectedDescriptors()[0] }); + // depth prepass config + vkcv::ShaderProgram depthPrepassShader; + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/depthPrepass.vert"), + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + depthPrepassShader.addShader(shaderStage, path); + }); + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/depthPrepass.frag"), + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + depthPrepassShader.addShader(shaderStage, path); + }); + + const std::vector<vkcv::VertexAttachment> prepassVertexAttachments = depthPrepassShader.getVertexAttachments(); + + std::vector<vkcv::VertexBinding> prepassVertexBindings; + for (size_t i = 0; i < prepassVertexAttachments.size(); i++) { + prepassVertexBindings.push_back(vkcv::VertexBinding(i, { prepassVertexAttachments[i] })); + } + const vkcv::VertexLayout prepassVertexLayout(prepassVertexBindings); + + const vkcv::AttachmentDescription prepassAttachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + depthBufferFormat); + + vkcv::PassConfig prepassPassDefinition({ prepassAttachment }, msaa); + vkcv::PassHandle prepassPass = core.createPass(prepassPassDefinition); + + vkcv::PipelineConfig prepassPipelineConfig{ + depthPrepassShader, + windowWidth, + windowHeight, + prepassPass, + vertexLayout, + {}, + true}; + prepassPipelineConfig.m_culling = vkcv::CullMode::Back; + prepassPipelineConfig.m_multisampling = msaa; + prepassPipelineConfig.m_depthTest = vkcv::DepthTest::LessEqual; + + vkcv::PipelineHandle prepassPipeline = core.createGraphicsPipeline(prepassPipelineConfig); + + // create descriptor sets vkcv::SamplerHandle colorSampler = core.createSampler( vkcv::SamplerFilterType::LINEAR, vkcv::SamplerFilterType::LINEAR, @@ -156,7 +199,6 @@ int main(int argc, const char** argv) { vkcv::SamplerAddressMode::REPEAT ); - // create descriptor sets std::vector<vkcv::DescriptorSetHandle> materialDescriptorSets; std::vector<vkcv::Image> sceneImages; @@ -234,6 +276,8 @@ int main(int argc, const char** argv) { }; forwardPipelineConfig.m_culling = vkcv::CullMode::Back; forwardPipelineConfig.m_multisampling = msaa; + forwardPipelineConfig.m_depthTest = vkcv::DepthTest::Equal; + forwardPipelineConfig.m_depthWrite = false; vkcv::PipelineHandle forwardPipeline = core.createGraphicsPipeline(forwardPipelineConfig); @@ -312,11 +356,13 @@ int main(int argc, const char** argv) { } std::vector<vkcv::DrawcallInfo> drawcalls; + std::vector<vkcv::DrawcallInfo> prepassDrawcalls; for (int i = 0; i < meshes.size(); i++) { drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(forwardShadingDescriptorSet).vulkanHandle), vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) })); + prepassDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {})); } vkcv::SamplerHandle voxelSampler = core.createSampler( @@ -440,9 +486,26 @@ int main(int argc, const char** argv) { modelMatrices, perMeshDescriptorSets); - // main pass + // depth prepass const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); + std::vector<glm::mat4> prepassMatrices; + for (const auto& m : modelMatrices) { + prepassMatrices.push_back(viewProjectionCamera * m); + } + + const vkcv::PushConstantData prepassPushConstantData((void*)prepassMatrices.data(), sizeof(glm::mat4)); + const std::vector<vkcv::ImageHandle> prepassRenderTargets = { depthBuffer }; + + core.recordDrawcallsToCmdStream( + cmdStream, + prepassPass, + prepassPipeline, + prepassPushConstantData, + prepassDrawcalls, + prepassRenderTargets); + + // main pass std::vector<std::array<glm::mat4, 2>> mainPassMatrices; for (const auto& m : modelMatrices) { mainPassMatrices.push_back({ viewProjectionCamera * m, m }); diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index 621abb0a..1b05269a 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -51,6 +51,18 @@ namespace vkcv } } + vk::CompareOp depthTestToVkCompareOp(DepthTest depthTest) { + switch (depthTest) { + case(DepthTest::None): return vk::CompareOp::eAlways; + case(DepthTest::Less): return vk::CompareOp::eLess; + case(DepthTest::LessEqual): return vk::CompareOp::eLessOrEqual; + case(DepthTest::Greater): return vk::CompareOp::eGreater; + case(DepthTest::GreatherEqual): return vk::CompareOp::eGreaterOrEqual; + case(DepthTest::Equal): return vk::CompareOp::eEqual; + default: vkcv_log(vkcv::LogLevel::ERROR, "Unknown depth test enum"); return vk::CompareOp::eAlways; + } + } + PipelineHandle PipelineManager::createPipeline(const PipelineConfig &config, PassManager& passManager) { const vk::RenderPass &pass = passManager.getVkPass(config.m_PassHandle); @@ -228,9 +240,9 @@ namespace vkcv const vk::PipelineDepthStencilStateCreateInfo depthStencilCreateInfo( vk::PipelineDepthStencilStateCreateFlags(), - true, - true, - vk::CompareOp::eLessOrEqual, + config.m_depthTest != DepthTest::None, + config.m_depthWrite, + depthTestToVkCompareOp(config.m_depthTest), false, false, {}, -- GitLab