diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index f8a8f0e..35b47df 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -127,185 +127,17 @@ void VulkanExampleBase::prepare() /* Command pool */ - VkCommandPoolCreateInfo cmdPoolInfo = {}; - cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex; - cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - VK_CHECK_RESULT(vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &cmdPool)); + /* Render pass */ - if (settings.multiSampling) { - std::array attachments = {}; - - // Multisampled attachment that we render to - attachments[0].format = swapChain.colorFormat; - attachments[0].samples = settings.sampleCount; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - // This is the frame buffer attachment to where the multisampled image - // will be resolved to and which will be presented to the swapchain - attachments[1].format = swapChain.colorFormat; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - // Multisampled depth attachment we render to - attachments[2].format = depthFormat; - attachments[2].samples = settings.sampleCount; - attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - // Depth resolve attachment - attachments[3].format = depthFormat; - attachments[3].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[3].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[3].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[3].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[3].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[3].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[3].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorReference = {}; - colorReference.attachment = 0; - colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depthReference = {}; - depthReference.attachment = 2; - depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - // Resolve attachment reference for the color attachment - VkAttachmentReference resolveReference = {}; - resolveReference.attachment = 1; - resolveReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorReference; - // Pass our resolve attachments to the sub pass - subpass.pResolveAttachments = &resolveReference; - subpass.pDepthStencilAttachment = &depthReference; - - std::array dependencies; - - dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; - dependencies[0].dstSubpass = 0; - dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - dependencies[1].srcSubpass = 0; - dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; - dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - VkRenderPassCreateInfo renderPassCI = {}; - renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassCI.attachmentCount = static_cast(attachments.size()); - renderPassCI.pAttachments = attachments.data(); - renderPassCI.subpassCount = 1; - renderPassCI.pSubpasses = &subpass; - renderPassCI.dependencyCount = 2; - renderPassCI.pDependencies = dependencies.data(); - VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass)); - } - else { - std::array attachments = {}; - // Color attachment - attachments[0].format = swapChain.colorFormat; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - // Depth attachment - attachments[1].format = depthFormat; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorReference = {}; - colorReference.attachment = 0; - colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depthReference = {}; - depthReference.attachment = 1; - depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpassDescription = {}; - subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDescription.colorAttachmentCount = 1; - subpassDescription.pColorAttachments = &colorReference; - subpassDescription.pDepthStencilAttachment = &depthReference; - subpassDescription.inputAttachmentCount = 0; - subpassDescription.pInputAttachments = nullptr; - subpassDescription.preserveAttachmentCount = 0; - subpassDescription.pPreserveAttachments = nullptr; - subpassDescription.pResolveAttachments = nullptr; - - // Subpass dependencies for layout transitions - std::array dependencies; - - dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; - dependencies[0].dstSubpass = 0; - dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - dependencies[1].srcSubpass = 0; - dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; - dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - VkRenderPassCreateInfo renderPassCI{}; - renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassCI.attachmentCount = static_cast(attachments.size()); - renderPassCI.pAttachments = attachments.data(); - renderPassCI.subpassCount = 1; - renderPassCI.pSubpasses = &subpassDescription; - renderPassCI.dependencyCount = static_cast(dependencies.size()); - renderPassCI.pDependencies = dependencies.data(); - VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass)); - } - /* Pipeline cache */ - VkPipelineCacheCreateInfo pipelineCacheCreateInfo{}; - pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - VK_CHECK_RESULT(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache)); + + /* Frame buffer @@ -1921,7 +1753,7 @@ void VulkanExampleBase::setupFrameBuffer() depthStencilView.image = depthStencil.image; VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view)); - // + // create framebuffer VkImageView attachments[4]; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fad9224..23ec7c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ function(buildHomework HOMEWORK_NAME) "render/glTFModel.h" "render/glTFModel.cpp" - "render/vulkanFoundation.h" "render/vulkanFoundation.cpp" "render/renderSetter.h" "render/renderSetter.cpp") + "render/vulkanFoundation.h" "render/vulkanFoundation.cpp" "render/renderSetter.h" "render/renderSetter.cpp" "render/PBR.h" "render/PBR.cpp") target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS}) else(WIN32) add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES}) diff --git a/src/render/PBR.cpp b/src/render/PBR.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/render/PBR.h b/src/render/PBR.h new file mode 100644 index 0000000..24f258c --- /dev/null +++ b/src/render/PBR.h @@ -0,0 +1,46 @@ +#pragma once +#include "glm/glm.hpp" + + + +namespace PBR +{ + class Material + { + public: + Material(); + ~Material(); + + struct PushConstBlockMaterial { + glm::vec4 baseColorFactor; + glm::vec4 emissiveFactor; + glm::vec4 diffuseFactor; + glm::vec4 specularFactor; + float workflow; + int colorTextureSet; + int PhysicalDescriptorTextureSet; + int normalTextureSet; + int occlusionTextureSet; + int emissiveTextureSet; + float metallicFactor; + float roughnessFactor; + float alphaMask; + float alphaMaskCutoff; + } pushConstBlockMaterial; + + private: + + + + + + }; + + Material::Material() + { + } + + Material::~Material() + { + } +} \ No newline at end of file diff --git a/src/render/render.cpp b/src/render/render.cpp index 9cdc2ea..11a5ca8 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -300,39 +300,7 @@ void PlumageRender::setupNodeDescriptorSet(glTFModel::Node* node) void PlumageRender::setupDescriptors() { - /* - Descriptor Pool - */ - uint32_t imageSamplerCount = 0; - uint32_t materialCount = 0; - uint32_t meshCount = 0; - - // Environment samplers (radiance, irradiance, brdflut) - imageSamplerCount += 3; - - std::vector modellist = { &models.skybox, &models.scene }; - for (auto& model : modellist) { - for (auto& material : model->materials) { - imageSamplerCount += 5; - materialCount++; - } - for (auto node : model->linearNodes) { - if (node->mesh) { - meshCount++; - } - } - } - - std::vector poolSizes = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount } - }; - VkDescriptorPoolCreateInfo descriptorPoolCI{}; - descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptorPoolCI.poolSizeCount = 2; - descriptorPoolCI.pPoolSizes = poolSizes.data(); - descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * swapChain.imageCount; - VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool)); + /* Descriptor sets @@ -492,154 +460,6 @@ void PlumageRender::setupDescriptors() } } -void PlumageRender::preparePipelines() - { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{}; - inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssemblyStateCI.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - - VkPipelineRasterizationStateCreateInfo rasterizationStateCI{}; - rasterizationStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL; - rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterizationStateCI.lineWidth = 1.0f; - - VkPipelineColorBlendAttachmentState blendAttachmentState{}; - blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - blendAttachmentState.blendEnable = VK_FALSE; - - VkPipelineColorBlendStateCreateInfo colorBlendStateCI{}; - colorBlendStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlendStateCI.attachmentCount = 1; - colorBlendStateCI.pAttachments = &blendAttachmentState; - - VkPipelineDepthStencilStateCreateInfo depthStencilStateCI{}; - depthStencilStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depthStencilStateCI.depthTestEnable = VK_FALSE; - depthStencilStateCI.depthWriteEnable = VK_FALSE; - depthStencilStateCI.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; - depthStencilStateCI.front = depthStencilStateCI.back; - depthStencilStateCI.back.compareOp = VK_COMPARE_OP_ALWAYS; - - VkPipelineViewportStateCreateInfo viewportStateCI{}; - viewportStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportStateCI.viewportCount = 1; - viewportStateCI.scissorCount = 1; - - VkPipelineMultisampleStateCreateInfo multisampleStateCI{}; - multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - - if (setter.settings.multiSampling) { - multisampleStateCI.rasterizationSamples = setter.settings.sampleCount; - } - - std::vector dynamicStateEnables = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - }; - VkPipelineDynamicStateCreateInfo dynamicStateCI{}; - dynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicStateCI.pDynamicStates = dynamicStateEnables.data(); - dynamicStateCI.dynamicStateCount = static_cast(dynamicStateEnables.size()); - - // Pipeline layout - const std::vector setLayouts = { - descriptorSetLayouts.scene, descriptorSetLayouts.material, descriptorSetLayouts.node - }; - VkPipelineLayoutCreateInfo pipelineLayoutCI{}; - pipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutCI.setLayoutCount = static_cast(setLayouts.size()); - pipelineLayoutCI.pSetLayouts = setLayouts.data(); - VkPushConstantRange pushConstantRange{}; - pushConstantRange.size = sizeof(PushConstBlockMaterial); - pushConstantRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - pipelineLayoutCI.pushConstantRangeCount = 1; - pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); - - // Vertex bindings an attributes - VkVertexInputBindingDescription vertexInputBinding = { 0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX }; - std::vector vertexInputAttributes = { - { 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 }, - { 1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3 }, - { 2, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6 }, - { 3, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 8 }, - { 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 10 }, - { 5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 14 }, - { 6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 18 } - }; - VkPipelineVertexInputStateCreateInfo vertexInputStateCI{}; - vertexInputStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputStateCI.vertexBindingDescriptionCount = 1; - vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding; - vertexInputStateCI.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()); - vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data(); - - // Pipelines - std::array shaderStages; - - VkGraphicsPipelineCreateInfo pipelineCI{}; - pipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineCI.layout = pipelineLayout; - pipelineCI.renderPass = renderPass; - pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; - pipelineCI.pVertexInputState = &vertexInputStateCI; - pipelineCI.pRasterizationState = &rasterizationStateCI; - pipelineCI.pColorBlendState = &colorBlendStateCI; - pipelineCI.pMultisampleState = &multisampleStateCI; - pipelineCI.pViewportState = &viewportStateCI; - pipelineCI.pDepthStencilState = &depthStencilStateCI; - pipelineCI.pDynamicState = &dynamicStateCI; - pipelineCI.stageCount = static_cast(shaderStages.size()); - pipelineCI.pStages = shaderStages.data(); - - if (setter.settings.multiSampling) { - multisampleStateCI.rasterizationSamples = setter.settings.sampleCount; - } - - // Skybox pipeline (background cube) - shaderStages = { - loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), - loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) - }; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox)); - for (auto shaderStage : shaderStages) { - vkDestroyShaderModule(device, shaderStage.module, nullptr); - } - - // PBR pipeline - shaderStages = { - loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), - loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) - }; - depthStencilStateCI.depthWriteEnable = VK_TRUE; - depthStencilStateCI.depthTestEnable = VK_TRUE; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbr)); - rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrDoubleSided)); - - rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; - blendAttachmentState.blendEnable = VK_TRUE; - blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; - blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrAlphaBlend)); - - for (auto shaderStage : shaderStages) { - vkDestroyShaderModule(device, shaderStage.module, nullptr); - } - //Create Tone Mapping render pipeline - //CreateToneMappingPipeline(); - - - - } - // generate two cube maps // irradiance cube map // prefileter environment cube map diff --git a/src/render/render.h b/src/render/render.h index 785be93..d7abc25 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -124,22 +124,6 @@ public: glm::vec3 camPos; } shaderDataScene, shaderDataSkybox; - struct PushConstBlockMaterial { - glm::vec4 baseColorFactor; - glm::vec4 emissiveFactor; - glm::vec4 diffuseFactor; - glm::vec4 specularFactor; - float workflow; - int colorTextureSet; - int PhysicalDescriptorTextureSet; - int normalTextureSet; - int occlusionTextureSet; - int emissiveTextureSet; - float metallicFactor; - float roughnessFactor; - float alphaMask; - float alphaMaskCutoff; - } pushConstBlockMaterial; @@ -164,27 +148,9 @@ public: VkDeviceMemory memory; } vertexStaging, indexStaging; - struct Pipelines { - VkPipeline skybox; - VkPipeline pbr; - VkPipeline pbrDoubleSided; - VkPipeline pbrAlphaBlend; - VkPipeline solid; - VkPipeline wireframe = VK_NULL_HANDLE; - VkPipeline toneMapping = VK_NULL_HANDLE; - } pipelines; - VkPipeline boundPipeline = VK_NULL_HANDLE; - struct PipelineLayouts - { - VkDescriptorSetLayout scene; - VkDescriptorSetLayout material; - VkDescriptorSetLayout node; - VkPipelineLayout tonemappingLayout; - } pipelineLayouts; - - VkPipelineLayout pipelineLayout; + struct DescriptorSets { VkDescriptorSet scene; @@ -192,9 +158,6 @@ public: VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE; }; - - - std::vector descriptorSets; diff --git a/src/render/vulkanFoundation.cpp b/src/render/vulkanFoundation.cpp index 1ed0bad..562ba52 100644 --- a/src/render/vulkanFoundation.cpp +++ b/src/render/vulkanFoundation.cpp @@ -26,6 +26,39 @@ void VulkanBackend::VulkanFondation::initVulkan() // 创建renderpass createRenderPass(); + + // 创建资源描述符层级 + createDescriptorSetLayout(); + + // 创建管线缓存 + createPipelineCache(); + + // 创建图形管线 + createGraphicPipeline(); + + // 创建主要帧缓冲区 + createFramebuffer(); + + // 创建命令缓冲池 + createCommandPool(); + + // 创建顶点缓存 + createVertexBuffer(); + + // 创建索引缓存区 + createIndexBuffer(); + + // 创建统一缓存区 + createUniformBuffer(); + + // 创建资源描述存储池 + createDescriptorPool(); + + // 创建资源描述符集 + createDescriptorSets(); + + // 创建命令缓存区 + createCommandBuffer(); } @@ -823,6 +856,8 @@ bool VulkanBackend::VulkanFondation::hasStencilComponent(VkFormat format) return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT; } + + void VulkanBackend::VulkanFondation::createDescriptorSetLayout() { // scene,场景的资源描述符 @@ -865,3 +900,248 @@ void VulkanBackend::VulkanFondation::createDescriptorSetLayout() } + +void VulkanBackend::VulkanFondation::createPipelineCache() +{ + VkPipelineCacheCreateInfo pipelineCacheCreateInfo{}; + pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + VK_CHECK_RESULT(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache)); +} + + + +void VulkanBackend::VulkanFondation::createGraphicPipeline() +{ + VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{}; + inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssemblyStateCI.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + VkPipelineRasterizationStateCreateInfo rasterizationStateCI{}; + rasterizationStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL; + rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterizationStateCI.lineWidth = 1.0f; + + VkPipelineColorBlendAttachmentState blendAttachmentState{}; + blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + blendAttachmentState.blendEnable = VK_FALSE; + + VkPipelineColorBlendStateCreateInfo colorBlendStateCI{}; + colorBlendStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlendStateCI.attachmentCount = 1; + colorBlendStateCI.pAttachments = &blendAttachmentState; + + VkPipelineDepthStencilStateCreateInfo depthStencilStateCI{}; + depthStencilStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depthStencilStateCI.depthTestEnable = VK_FALSE; + depthStencilStateCI.depthWriteEnable = VK_FALSE; + depthStencilStateCI.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + depthStencilStateCI.front = depthStencilStateCI.back; + depthStencilStateCI.back.compareOp = VK_COMPARE_OP_ALWAYS; + + VkPipelineViewportStateCreateInfo viewportStateCI{}; + viewportStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportStateCI.viewportCount = 1; + viewportStateCI.scissorCount = 1; + + VkPipelineMultisampleStateCreateInfo multisampleStateCI{}; + multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + + if (setter.settings.multiSampling) { + multisampleStateCI.rasterizationSamples = setter.settings.sampleCount; + } + + std::vector dynamicStateEnables = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR + }; + VkPipelineDynamicStateCreateInfo dynamicStateCI{}; + dynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicStateCI.pDynamicStates = dynamicStateEnables.data(); + dynamicStateCI.dynamicStateCount = static_cast(dynamicStateEnables.size()); + + // Pipeline layout + const std::vector setLayouts = { + descriptorSetLayouts.scene, descriptorSetLayouts.material, descriptorSetLayouts.node + }; + VkPipelineLayoutCreateInfo pipelineLayoutCI{}; + pipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCI.setLayoutCount = static_cast(setLayouts.size()); + pipelineLayoutCI.pSetLayouts = setLayouts.data(); + VkPushConstantRange pushConstantRange{}; + pushConstantRange.size = sizeof(pbrMaterial.pushConstBlockMaterial); + pushConstantRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + pipelineLayoutCI.pushConstantRangeCount = 1; + pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); + + // Vertex bindings an attributes + VkVertexInputBindingDescription vertexInputBinding = { 0, sizeof(glTFModel::Model::Vertex), VK_VERTEX_INPUT_RATE_VERTEX }; + std::vector vertexInputAttributes = { + { 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 }, + { 1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3 }, + { 2, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6 }, + { 3, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 8 }, + { 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 10 }, + { 5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 14 }, + { 6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(float) * 18 } + }; + VkPipelineVertexInputStateCreateInfo vertexInputStateCI{}; + vertexInputStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputStateCI.vertexBindingDescriptionCount = 1; + vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding; + vertexInputStateCI.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()); + vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data(); + + // Pipelines + std::array shaderStages; + + VkGraphicsPipelineCreateInfo pipelineCI{}; + pipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineCI.layout = pipelineLayout; + pipelineCI.renderPass = renderPass; + pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; + pipelineCI.pVertexInputState = &vertexInputStateCI; + pipelineCI.pRasterizationState = &rasterizationStateCI; + pipelineCI.pColorBlendState = &colorBlendStateCI; + pipelineCI.pMultisampleState = &multisampleStateCI; + pipelineCI.pViewportState = &viewportStateCI; + pipelineCI.pDepthStencilState = &depthStencilStateCI; + pipelineCI.pDynamicState = &dynamicStateCI; + pipelineCI.stageCount = static_cast(shaderStages.size()); + pipelineCI.pStages = shaderStages.data(); + + if (setter.settings.multiSampling) { + multisampleStateCI.rasterizationSamples = setter.settings.sampleCount; + } + + // Skybox pipeline (background cube) + shaderStages = { + loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), + loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) + }; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox)); + for (auto shaderStage : shaderStages) { + vkDestroyShaderModule(device, shaderStage.module, nullptr); + } + + // PBR pipeline + shaderStages = { + loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), + loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) + }; + depthStencilStateCI.depthWriteEnable = VK_TRUE; + depthStencilStateCI.depthTestEnable = VK_TRUE; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbr)); + rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrDoubleSided)); + + rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; + blendAttachmentState.blendEnable = VK_TRUE; + blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; + blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.pbrAlphaBlend)); + + for (auto shaderStage : shaderStages) { + vkDestroyShaderModule(device, shaderStage.module, nullptr); + } + //Create Tone Mapping render pipeline + //CreateToneMappingPipeline(); + +} + + + +void VulkanBackend::VulkanFondation::createFramebuffer() +{ + +} + + + +void VulkanBackend::VulkanFondation::createCommandPool() +{ + QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); + + VkCommandPoolCreateInfo poolInfo{}; + poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(); + + if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) + { + throw std::runtime_error("failed to create command pool in createCommandpool"); + } +} + +void VulkanBackend::VulkanFondation::createVertexBuffer() +{ + +} + +void VulkanBackend::VulkanFondation::createIndexBuffer() +{ + +} + +void VulkanBackend::VulkanFondation::createUniformBuffer() +{ + +} + +void VulkanBackend::VulkanFondation::createDescriptorPool() +{ + /* + Descriptor Pool + */ + uint32_t imageSamplerCount = 0; + uint32_t materialCount = 0; + uint32_t meshCount = 0; + + // Environment samplers (radiance, irradiance, brdflut) + imageSamplerCount += 3; + + std::vector modellist = { &models.skybox, &models.scene }; + for (auto& model : modellist) { + for (auto& material : model->materials) { + imageSamplerCount += 5; + materialCount++; + } + for (auto node : model->linearNodes) { + if (node->mesh) { + meshCount++; + } + } + } + + std::vector poolSizes = { + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount } + }; + VkDescriptorPoolCreateInfo descriptorPoolCI{}; + descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolCI.poolSizeCount = 2; + descriptorPoolCI.pPoolSizes = poolSizes.data(); + descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * swapChain.imageCount; + VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool)); +} + +void VulkanBackend::VulkanFondation::createDescriptorSets() +{ + +} + +void VulkanBackend::VulkanFondation::createCommandBuffer() +{ + +} + + + + diff --git a/src/render/vulkanFoundation.h b/src/render/vulkanFoundation.h index acd770b..c19d4d0 100644 --- a/src/render/vulkanFoundation.h +++ b/src/render/vulkanFoundation.h @@ -9,6 +9,9 @@ #include "renderSetter.h" #include +#include "glTFModel.h" +#include "VulkanUtils.hpp" +#include "PBR.h" namespace VulkanBackend { @@ -35,6 +38,7 @@ namespace VulkanBackend private: VulkanBackend::Setter setter; + PBR::Material pbrMaterial; VkInstance instance; @@ -91,12 +95,44 @@ namespace VulkanBackend VkRenderPass renderPass; + VkCommandPool commandPool; + + struct Models + { + glTFModel::Model scene; + glTFModel::Model skybox; + } models; + struct DescriptorSetLayouts { VkDescriptorSetLayout scene; VkDescriptorSetLayout material; VkDescriptorSetLayout node; } descriptorSetLayouts; + struct Pipelines { + VkPipeline skybox; + VkPipeline pbr; + VkPipeline pbrDoubleSided; + VkPipeline pbrAlphaBlend; + VkPipeline solid; + VkPipeline wireframe = VK_NULL_HANDLE; + VkPipeline toneMapping = VK_NULL_HANDLE; + } pipelines; + + VkPipeline boundPipeline = VK_NULL_HANDLE; + + struct PipelineLayouts + { + VkDescriptorSetLayout scene; + VkDescriptorSetLayout material; + VkDescriptorSetLayout node; + VkPipelineLayout tonemappingLayout; + } pipelineLayouts; + + VkPipelineLayout pipelineLayout; + + VkPipelineCache pipelineCache; + // 句柄创建,检查校验层支持和获取需要的扩展 void createInstance(); bool checkValidationLayerSupport(); @@ -143,6 +179,9 @@ namespace VulkanBackend // 创建资源描述符层级,用于访问绑定的资源 void createDescriptorSetLayout(); + // 创建管线缓存 + void createPipelineCache(); + // 创建图形管线 void createGraphicPipeline(); @@ -167,6 +206,8 @@ namespace VulkanBackend // 创建描述符集合 void createDescriptorSets(); + // 创建命令缓存区 + void createCommandBuffer(); };