update setupDescriptor for pbr and tonemapping
parent
d6542ac2f1
commit
441aca4df4
|
@ -979,11 +979,16 @@ void VulkanExample::getEnabledFeatures()
|
|||
*/
|
||||
|
||||
std::vector<VkDescriptorPoolSize> poolSizes = {
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1),
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 4),
|
||||
// One combined image sampler per material image/texture
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, static_cast<uint32_t>(glTFModel.images.size())),
|
||||
// One ssbo per skin
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<uint32_t>(glTFModel.skins.size())),
|
||||
// sampler descriptor
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,4),
|
||||
//animation storage buffer
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,1)
|
||||
|
||||
};
|
||||
// Number of descriptor sets = One for the scene ubo + one per image + one per skin
|
||||
const uint32_t maxSetCount = static_cast<uint32_t>(glTFModel.images.size()) + static_cast<uint32_t>(glTFModel.skins.size()) + 1;
|
||||
|
@ -991,18 +996,29 @@ void VulkanExample::getEnabledFeatures()
|
|||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||
|
||||
// Descriptor set layouts
|
||||
VkDescriptorSetLayoutBinding setLayoutBinding{};
|
||||
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(&setLayoutBinding, 1);
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings =
|
||||
{
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0),
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1),
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 2),
|
||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 3),
|
||||
};
|
||||
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
||||
// Descriptor set layout for passing matrices
|
||||
setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.matrices));
|
||||
|
||||
// Descriptor set layout for material uniform buffer
|
||||
VkDescriptorSetLayoutBinding materialBufferLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, 0);
|
||||
descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(&materialBufferLayoutBinding, 1);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.materialUniform));
|
||||
// Descriptor set layout for passing material textures
|
||||
setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0);
|
||||
VkDescriptorSetLayoutBinding setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0);
|
||||
descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(&setLayoutBinding, 1);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.textures));
|
||||
|
||||
// Descriptor set layout for ssbo
|
||||
setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.ssbo));
|
||||
// Descriptor set layout for passing skin joint matrices
|
||||
|
||||
setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.jointMatrices));
|
||||
|
||||
|
@ -1010,31 +1026,66 @@ void VulkanExample::getEnabledFeatures()
|
|||
// Set 0 = Scene matrices (VS)
|
||||
// Set 1 = Joint matrices (VS)
|
||||
// Set 2 = Material texture (FS)
|
||||
std::array<VkDescriptorSetLayout, 3> setLayouts = {
|
||||
std::array<VkDescriptorSetLayout, 8> setLayouts = {
|
||||
descriptorSetLayouts.matrices,
|
||||
descriptorSetLayouts.jointMatrices,
|
||||
descriptorSetLayouts.textures };
|
||||
descriptorSetLayouts.textures,
|
||||
descriptorSetLayouts.textures,
|
||||
descriptorSetLayouts.textures,
|
||||
descriptorSetLayouts.textures,
|
||||
descriptorSetLayouts.materialUniform,
|
||||
descriptorSetLayouts.ssbo,
|
||||
};
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
|
||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
|
||||
/*
|
||||
|
||||
// We will use push constants to push the local matrices of a primitive to the vertex shader
|
||||
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::mat4), 0);
|
||||
// Push constant ranges are part of the pipeline layout
|
||||
pipelineLayoutCI.pushConstantRangeCount = 1;
|
||||
pipelineLayoutCI.pPushConstantRanges = &pushConstantRange;
|
||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout));
|
||||
|
||||
*/
|
||||
// Descriptor set for scene matrices
|
||||
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.matrices, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &shaderData.buffer.descriptor);
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets =
|
||||
{
|
||||
vks::initializers::writeDescriptorSet(descriptorSet,VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,0,&shaderData.buffer.descriptor),
|
||||
vks::initializers::writeDescriptorSet(descriptorSet,VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,1,&ibltextures.irradianceCube.descriptor),
|
||||
vks::initializers::writeDescriptorSet(descriptorSet,VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,2,&ibltextures.lutBrdf.descriptor),
|
||||
vks::initializers::writeDescriptorSet(descriptorSet,VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,3,&ibltextures.prefilteredCube.descriptor),
|
||||
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(device, 4, writeDescriptorSets.data(), 0, nullptr);
|
||||
|
||||
// Descriptor set for glTF model skin joint matrices
|
||||
for (auto& skin : glTFModel.skins)
|
||||
if (glTFModel.skins.size() > 0)
|
||||
{
|
||||
const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.jointMatrices, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &skin.descriptorSet));
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(skin.descriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &skin.ssbo.descriptor);
|
||||
for (auto& skin : glTFModel.skins)
|
||||
{
|
||||
const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.jointMatrices, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &skin.descriptorSet));
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(skin.descriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &skin.ssbo.descriptor);
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.ssbo, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &skinDescriptorSet));
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(skinDescriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &shaderData.skinSSBO.descriptor);
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
for (auto& material : glTFModel.materials)
|
||||
{
|
||||
const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.materialUniform, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &material.materialData.descriptorSet));
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(material.materialData.descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &material.materialData.buffer.descriptor);
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1098,19 @@ void VulkanExample::getEnabledFeatures()
|
|||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
//tonemapping pipline layout
|
||||
{
|
||||
VkPipelineLayoutCreateInfo piplineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.textures, 1);
|
||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &piplineLayoutCI, nullptr, &pipelineLayouts.tonemappingLayout));
|
||||
|
||||
const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.textures, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &tonemappingDescriptorSet));
|
||||
|
||||
VkDescriptorImageInfo imageInfo = vks::initializers::descriptorImageInfo(colorSampler, pbrFrameBuffer.color.imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(tonemappingDescriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &imageInfo);
|
||||
vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VulkanExample::preparePipelines()
|
||||
|
@ -1069,9 +1133,10 @@ void VulkanExample::getEnabledFeatures()
|
|||
{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, normal)},
|
||||
{2, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, uv)},
|
||||
{3, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, color)},
|
||||
{4, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(VulkanglTFModel::Vertex, tangent)},
|
||||
// POI: Per-Vertex Joint indices and weights are passed to the vertex shader
|
||||
{4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointIndices)},
|
||||
{5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointWeights)},
|
||||
{5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointIndices)},
|
||||
{6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(VulkanglTFModel::Vertex, jointWeights)},
|
||||
};
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo();
|
||||
vertexInputStateCI.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size());
|
||||
|
@ -1106,6 +1171,44 @@ void VulkanExample::getEnabledFeatures()
|
|||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.wireframe));
|
||||
}
|
||||
}
|
||||
void VulkanExample::prepareToneMappingPipeline()
|
||||
{
|
||||
if (pipelines.toneMapping != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyPipeline(device, pipelines.toneMapping, nullptr);
|
||||
pipelines.toneMapping = VK_NULL_HANDLE;
|
||||
}
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentStateCI = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentStateCI);
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
|
||||
VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
|
||||
const std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), static_cast<uint32_t>(dynamicStateEnables.size()), 0);
|
||||
VkPipelineVertexInputStateCreateInfo emptyInputState = vks::initializers::pipelineVertexInputStateCreateInfo();
|
||||
|
||||
const std::string fragPath = ToneMapping ? "homework1/tonemapping_enable.frag.spv" : "homework1/tonemapping_disable.frag.spv";
|
||||
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {
|
||||
loadShader(getHomeworkShadersPath() + "homework1/genbrdflut.vert.spv", VK_SHADER_STAGE_VERTEX_BIT),
|
||||
loadShader(getHomeworkShadersPath() + fragPath, VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
};
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayouts.tonemappingLayout, renderPass, 0);
|
||||
pipelineCI.pVertexInputState = &emptyInputState;
|
||||
pipelineCI.pInputAssemblyState = &inputAssemblyStateCI;
|
||||
pipelineCI.pRasterizationState = &rasterizationStateCI;
|
||||
pipelineCI.pColorBlendState = &colorBlendStateCI;
|
||||
pipelineCI.pMultisampleState = &multisampleStateCI;
|
||||
pipelineCI.pViewportState = &viewportStateCI;
|
||||
pipelineCI.pDepthStencilState = &depthStencilStateCI;
|
||||
pipelineCI.pDynamicState = &dynamicStateCI;
|
||||
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
|
||||
pipelineCI.pStages = shaderStages.data();
|
||||
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.toneMapping));
|
||||
}
|
||||
|
||||
// Prepare and initialize uniform buffer containing shader uniforms
|
||||
void VulkanExample::prepareUniformBuffers()
|
||||
|
@ -1117,8 +1220,27 @@ void VulkanExample::getEnabledFeatures()
|
|||
&shaderData.buffer,
|
||||
sizeof(shaderData.values)));
|
||||
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&shaderData.skinSSBO,
|
||||
sizeof(glm::mat4) * glTFModel.nodeCount));
|
||||
|
||||
for (auto& material : glTFModel.materials)
|
||||
{
|
||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&material.materialData.buffer,
|
||||
sizeof(VulkanglTFModel::MaterialData::Values),
|
||||
&material.materialData.values
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Map persistent
|
||||
VK_CHECK_RESULT(shaderData.buffer.map());
|
||||
VK_CHECK_RESULT(shaderData.skinSSBO.map());
|
||||
|
||||
updateUniformBuffers();
|
||||
}
|
||||
|
@ -1127,6 +1249,9 @@ void VulkanExample::getEnabledFeatures()
|
|||
{
|
||||
shaderData.values.projection = camera.matrices.perspective;
|
||||
shaderData.values.model = camera.matrices.view;
|
||||
shaderData.values.viewPos = camera.viewPos;
|
||||
shaderData.values.bFlagSet.x = normalMapping;
|
||||
shaderData.values.bFlagSet.y = pbrEnabled;
|
||||
|
||||
memcpy(shaderData.buffer.mapped, &shaderData.values, sizeof(shaderData.values));
|
||||
}
|
||||
|
@ -1192,11 +1317,11 @@ void VulkanExample::getEnabledFeatures()
|
|||
|
||||
#pragma endregion
|
||||
|
||||
// ----------------------- pbr precompute end ---------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------- pbr precompute end ---------------------------------------
|
||||
void VulkanExample::prepare()
|
||||
{
|
||||
VulkanExampleBase::prepare();
|
||||
|
|
|
@ -364,6 +364,7 @@ public:
|
|||
void loadAssets();
|
||||
void setupDescriptors();
|
||||
void preparePipelines();
|
||||
void prepareToneMappingPipeline();
|
||||
void prepareUniformBuffers();
|
||||
void updateUniformBuffers();
|
||||
void prepare();
|
||||
|
|
Loading…
Reference in New Issue