parent
6a8a44a75d
commit
b89716506b
1 changed files with 68 additions and 167 deletions
|
|
@ -23,7 +23,6 @@
|
|||
#include "VulkanTexture.hpp"
|
||||
#include "VulkanModel.hpp"
|
||||
|
||||
#define VERTEX_BUFFER_BIND_ID 0
|
||||
#define ENABLE_VALIDATION false
|
||||
|
||||
#define SSAO_KERNEL_SIZE 32
|
||||
|
|
@ -54,12 +53,6 @@ public:
|
|||
vks::Model scene;
|
||||
} models;
|
||||
|
||||
struct {
|
||||
VkPipelineVertexInputStateCreateInfo inputState;
|
||||
std::vector<VkVertexInputBindingDescription> bindingDescriptions;
|
||||
std::vector<VkVertexInputAttributeDescription> attributeDescriptions;
|
||||
} vertices;
|
||||
|
||||
struct UBOSceneMatrices {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 model;
|
||||
|
|
@ -279,8 +272,6 @@ public:
|
|||
void prepareOffscreenFramebuffers()
|
||||
{
|
||||
// Attachments
|
||||
VkCommandBuffer layoutCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
const uint32_t ssaoWidth = width / 2;
|
||||
const uint32_t ssaoHeight = height / 2;
|
||||
|
|
@ -310,8 +301,6 @@ public:
|
|||
// SSAO blur
|
||||
createAttachment(VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &frameBuffers.ssaoBlur.color, width, height); // Color
|
||||
|
||||
VulkanExampleBase::flushCommandBuffer(layoutCmd, queue, true);
|
||||
|
||||
// Render passes
|
||||
|
||||
// G-Buffer creation
|
||||
|
|
@ -455,7 +444,7 @@ public:
|
|||
// SSAO Blur
|
||||
{
|
||||
VkAttachmentDescription attachmentDescription{};
|
||||
attachmentDescription.format = frameBuffers.ssao.color.format;
|
||||
attachmentDescription.format = frameBuffers.ssaoBlur.color.format;
|
||||
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
|
@ -558,8 +547,9 @@ public:
|
|||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(offScreenCmdBuffer, &cmdBufInfo));
|
||||
|
||||
// First pass: Fill G-Buffer components (positions+depth, normals, albedo) using MRT
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
First pass: Fill G-Buffer components (positions+depth, normals, albedo) using MRT
|
||||
*/
|
||||
|
||||
vkCmdBeginRenderPass(offScreenCmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
|
|
@ -572,14 +562,15 @@ public:
|
|||
vkCmdBindPipeline(offScreenCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.offscreen);
|
||||
|
||||
vkCmdBindDescriptorSets(offScreenCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.gBuffer, 0, 1, &descriptorSets.floor, 0, NULL);
|
||||
vkCmdBindVertexBuffers(offScreenCmdBuffer, VERTEX_BUFFER_BIND_ID, 1, &models.scene.vertices.buffer, offsets);
|
||||
vkCmdBindVertexBuffers(offScreenCmdBuffer, 0, 1, &models.scene.vertices.buffer, offsets);
|
||||
vkCmdBindIndexBuffer(offScreenCmdBuffer, models.scene.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(offScreenCmdBuffer, models.scene.indexCount, 1, 0, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(offScreenCmdBuffer);
|
||||
|
||||
// Second pass: SSAO generation
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
Second pass: SSAO generation
|
||||
*/
|
||||
|
||||
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
|
||||
clearValues[1].depthStencil = { 1.0f, 0 };
|
||||
|
|
@ -604,8 +595,9 @@ public:
|
|||
|
||||
vkCmdEndRenderPass(offScreenCmdBuffer);
|
||||
|
||||
// Third pass: SSAO blur
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
Third pass: SSAO blur
|
||||
*/
|
||||
|
||||
renderPassBeginInfo.framebuffer = frameBuffers.ssaoBlur.frameBuffer;
|
||||
renderPassBeginInfo.renderPass = frameBuffers.ssaoBlur.renderPass;
|
||||
|
|
@ -682,68 +674,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void setupVertexDescriptions()
|
||||
{
|
||||
// Binding description
|
||||
vertices.bindingDescriptions.resize(1);
|
||||
vertices.bindingDescriptions[0] =
|
||||
vks::initializers::vertexInputBindingDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
vertexLayout.stride(),
|
||||
VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
|
||||
// Attribute descriptions
|
||||
vertices.attributeDescriptions.resize(4);
|
||||
// Location 0: Position
|
||||
vertices.attributeDescriptions[0] =
|
||||
vks::initializers::vertexInputAttributeDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
0,
|
||||
VK_FORMAT_R32G32B32_SFLOAT,
|
||||
0);
|
||||
// Location 1: Texture coordinates
|
||||
vertices.attributeDescriptions[1] =
|
||||
vks::initializers::vertexInputAttributeDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
1,
|
||||
VK_FORMAT_R32G32_SFLOAT,
|
||||
sizeof(float) * 3);
|
||||
// Location 2: Color
|
||||
vertices.attributeDescriptions[2] =
|
||||
vks::initializers::vertexInputAttributeDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
2,
|
||||
VK_FORMAT_R32G32B32_SFLOAT,
|
||||
sizeof(float) * 5);
|
||||
// Location 3: Normal
|
||||
vertices.attributeDescriptions[3] =
|
||||
vks::initializers::vertexInputAttributeDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
3,
|
||||
VK_FORMAT_R32G32B32_SFLOAT,
|
||||
sizeof(float) * 8);
|
||||
|
||||
vertices.inputState = vks::initializers::pipelineVertexInputStateCreateInfo();
|
||||
vertices.inputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertices.bindingDescriptions.size());
|
||||
vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data();
|
||||
vertices.inputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertices.attributeDescriptions.size());
|
||||
vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data();
|
||||
}
|
||||
|
||||
void setupDescriptorPool()
|
||||
{
|
||||
std::vector<VkDescriptorPoolSize> poolSizes =
|
||||
{
|
||||
std::vector<VkDescriptorPoolSize> poolSizes = {
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 10),
|
||||
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 12)
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo =
|
||||
vks::initializers::descriptorPoolCreateInfo(
|
||||
static_cast<uint32_t>(poolSizes.size()),
|
||||
poolSizes.data(),
|
||||
descriptorSets.count);
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, descriptorSets.count);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||
}
|
||||
|
||||
|
|
@ -852,66 +789,38 @@ public:
|
|||
|
||||
void preparePipelines()
|
||||
{
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
|
||||
vks::initializers::pipelineInputAssemblyStateCreateInfo(
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||
0,
|
||||
VK_FALSE);
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
||||
vks::initializers::pipelineRasterizationStateCreateInfo(
|
||||
VK_POLYGON_MODE_FILL,
|
||||
VK_CULL_MODE_BACK_BIT,
|
||||
VK_FRONT_FACE_CLOCKWISE,
|
||||
0);
|
||||
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState =
|
||||
vks::initializers::pipelineColorBlendAttachmentState(
|
||||
0xf,
|
||||
VK_FALSE);
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendState =
|
||||
vks::initializers::pipelineColorBlendStateCreateInfo(
|
||||
1,
|
||||
&blendAttachmentState);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
||||
vks::initializers::pipelineDepthStencilStateCreateInfo(
|
||||
VK_TRUE,
|
||||
VK_TRUE,
|
||||
VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportState =
|
||||
vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState =
|
||||
vks::initializers::pipelineMultisampleStateCreateInfo(
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
0);
|
||||
|
||||
std::vector<VkDynamicState> dynamicStateEnables = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
||||
vks::initializers::pipelineDynamicStateCreateInfo(
|
||||
dynamicStateEnables.data(),
|
||||
static_cast<uint32_t>(dynamicStateEnables.size()),
|
||||
0);
|
||||
|
||||
// Final composition pass pipeline
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0);
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState);
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0);
|
||||
std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
|
||||
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
|
||||
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/composition.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
// Vertex input state for scene rendering
|
||||
const std::vector<VkVertexInputBindingDescription> vertexInputBindings = {
|
||||
vks::initializers::vertexInputBindingDescription(0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX),
|
||||
};
|
||||
const std::vector<VkVertexInputAttributeDescription> vertexInputAttributes = {
|
||||
vks::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position
|
||||
vks::initializers::vertexInputAttributeDescription(0, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 3), // Location 1: UV
|
||||
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 5), // Location 2: Color
|
||||
vks::initializers::vertexInputAttributeDescription(0, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Location 3: Normal
|
||||
};
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo();
|
||||
vertexInputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexInputBindings.size());
|
||||
vertexInputState.pVertexBindingDescriptions = vertexInputBindings.data();
|
||||
vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributes.size());
|
||||
vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data();
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
|
||||
vks::initializers::pipelineCreateInfo(
|
||||
pipelineLayouts.composition,
|
||||
renderPass,
|
||||
0);
|
||||
// Empty vertex input state for fullscreen passes
|
||||
VkPipelineVertexInputStateCreateInfo emptyVertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo();
|
||||
|
||||
pipelineCreateInfo.pVertexInputState = &vertices.inputState;
|
||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo( pipelineLayouts.composition, renderPass, 0);
|
||||
pipelineCreateInfo.pVertexInputState = &emptyVertexInputState;
|
||||
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
|
||||
pipelineCreateInfo.pRasterizationState = &rasterizationState;
|
||||
pipelineCreateInfo.pColorBlendState = &colorBlendState;
|
||||
|
|
@ -922,22 +831,13 @@ public:
|
|||
pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
|
||||
pipelineCreateInfo.pStages = shaderStages.data();
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo emptyInputState{};
|
||||
emptyInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
emptyInputState.vertexAttributeDescriptionCount = 0;
|
||||
emptyInputState.pVertexAttributeDescriptions = nullptr;
|
||||
emptyInputState.vertexBindingDescriptionCount = 0;
|
||||
emptyInputState.pVertexBindingDescriptions = nullptr;
|
||||
pipelineCreateInfo.pVertexInputState = &emptyInputState;
|
||||
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/composition.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.composition));
|
||||
|
||||
pipelineCreateInfo.pVertexInputState = &emptyInputState;
|
||||
|
||||
// SSAO Pass
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/ssao.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
{
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/ssao.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
// Set constant parameters via specialization constants
|
||||
std::array<VkSpecializationMapEntry, 2> specializationMapEntries;
|
||||
specializationMapEntries[0] = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); // SSAO Kernel size
|
||||
|
|
@ -953,31 +853,33 @@ public:
|
|||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssao));
|
||||
}
|
||||
|
||||
|
||||
// SSAO blur pass
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/blur.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
pipelineCreateInfo.renderPass = frameBuffers.ssaoBlur.renderPass;
|
||||
pipelineCreateInfo.layout = pipelineLayouts.ssaoBlur;
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssaoBlur));
|
||||
{
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/blur.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
pipelineCreateInfo.renderPass = frameBuffers.ssaoBlur.renderPass;
|
||||
pipelineCreateInfo.layout = pipelineLayouts.ssaoBlur;
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssaoBlur));
|
||||
}
|
||||
|
||||
// Fill G-Buffer
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/gbuffer.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/gbuffer.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
pipelineCreateInfo.pVertexInputState = &vertices.inputState;
|
||||
pipelineCreateInfo.renderPass = frameBuffers.offscreen.renderPass;
|
||||
pipelineCreateInfo.layout = pipelineLayouts.gBuffer;
|
||||
// Blend attachment states required for all color attachments
|
||||
// This is important, as color write mask will otherwise be 0x0 and you
|
||||
// won't see anything rendered to the attachment
|
||||
std::array<VkPipelineColorBlendAttachmentState, 3> blendAttachmentStates = {
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE)
|
||||
};
|
||||
colorBlendState.attachmentCount = static_cast<uint32_t>(blendAttachmentStates.size());
|
||||
colorBlendState.pAttachments = blendAttachmentStates.data();
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.offscreen));
|
||||
{
|
||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/gbuffer.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/gbuffer.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
pipelineCreateInfo.pVertexInputState = &vertexInputState;
|
||||
pipelineCreateInfo.renderPass = frameBuffers.offscreen.renderPass;
|
||||
pipelineCreateInfo.layout = pipelineLayouts.gBuffer;
|
||||
// Blend attachment states required for all color attachments
|
||||
// This is important, as color write mask will otherwise be 0x0 and you
|
||||
// won't see anything rendered to the attachment
|
||||
std::array<VkPipelineColorBlendAttachmentState, 3> blendAttachmentStates = {
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE),
|
||||
vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE)
|
||||
};
|
||||
colorBlendState.attachmentCount = static_cast<uint32_t>(blendAttachmentStates.size());
|
||||
colorBlendState.pAttachments = blendAttachmentStates.data();
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.offscreen));
|
||||
}
|
||||
}
|
||||
|
||||
float lerp(float a, float b, float f)
|
||||
|
|
@ -1084,7 +986,6 @@ public:
|
|||
{
|
||||
VulkanExampleBase::prepare();
|
||||
loadAssets();
|
||||
setupVertexDescriptions();
|
||||
prepareOffscreenFramebuffers();
|
||||
prepareUniformBuffers();
|
||||
setupDescriptorPool();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue