Here’s the renderpass creating code and the depth format is VK_FORMAT_D32_SFLOAT
VkAttachmentDescription attachmentDesciptions[3] = {};
attachmentDesciptions[0].format = mSwapchain.GetFormat();
attachmentDesciptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachmentDesciptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
attachmentDesciptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDesciptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentDesciptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDesciptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDesciptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDesciptions[1].format = mDepthFormat;
attachmentDesciptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachmentDesciptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachmentDesciptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDesciptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentDesciptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDesciptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDesciptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDesciptions[2].format = mDepthFormat;
attachmentDesciptions[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachmentDesciptions[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachmentDesciptions[2].samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDesciptions[2].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachmentDesciptions[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDesciptions[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachmentDesciptions[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
VkAttachmentReference colorAttachment = {};
colorAttachment.attachment = 0;
colorAttachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthPrePassAttachment = {};
depthPrePassAttachment.attachment = 1;
depthPrePassAttachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthAttachment = {};
depthAttachment.attachment = 2;
depthAttachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpassDescription[2] = {};
subpassDescription[0].pDepthStencilAttachment = &depthPrePassAttachment;
subpassDescription[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpassDescription[1].colorAttachmentCount = 1;
subpassDescription[1].pColorAttachments = &colorAttachment;
subpassDescription[1].pDepthStencilAttachment = &depthAttachment;
subpassDescription[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
VkSubpassDependency subpassDependencies[2] = {};
subpassDependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
subpassDependencies[0].srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
subpassDependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassDependencies[0].dstSubpass = 0;
subpassDependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassDependencies[1].srcSubpass = 0;
subpassDependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassDependencies[1].dstSubpass = 1;
subpassDependencies[1].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependencies[1].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo renderPassCreateInfo = {};
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.attachmentCount = 3;
renderPassCreateInfo.pAttachments = attachmentDesciptions;
renderPassCreateInfo.subpassCount = 2;
renderPassCreateInfo.pSubpasses = subpassDescription;
renderPassCreateInfo.dependencyCount = 2;
renderPassCreateInfo.pDependencies = subpassDependencies;
CHECK(vkCreateRenderPass(mVulkanContext.GetDevice(), &renderPassCreateInfo, nullptr, &mRenderPass) == VK_SUCCESS);
here’s the framebuffer creating
for (uint32_t i = 0; i < mSwapchain.GetImageCount(); ++i)
{
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.extent = { mSwapchain.GetExtent2D().width,mSwapchain.GetExtent2D().height,1 };
imageCreateInfo.format = mDepthFormat;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
VkImageViewCreateInfo imageViewCreateInfo = {};
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.components = { VK_COMPONENT_SWIZZLE_IDENTITY,VK_COMPONENT_SWIZZLE_IDENTITY,VK_COMPONENT_SWIZZLE_IDENTITY,VK_COMPONENT_SWIZZLE_IDENTITY };
imageViewCreateInfo.format = mDepthFormat;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
VulkanImage image;
image.Initialize(mVulkanContext, imageCreateInfo, imageViewCreateInfo);
VkImageView imageViews[3];
imageViews[0] = mSwapchain.GetImageView(i);
imageViews[1] = image.GetImageView();
imageViews[2] = image.GetImageView();
VkFramebufferCreateInfo framebufferCreateInfo = {};
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferCreateInfo.attachmentCount = 3;
framebufferCreateInfo.pAttachments = imageViews;
framebufferCreateInfo.width = mSwapchain.GetExtent2D().width;
framebufferCreateInfo.height = mSwapchain.GetExtent2D().height;
framebufferCreateInfo.layers = 1;
framebufferCreateInfo.renderPass = mRenderPass;
VkFramebuffer framebuffer;
CHECK(vkCreateFramebuffer(mVulkanContext.GetDevice(), &framebufferCreateInfo, nullptr, &framebuffer) == VK_SUCCESS);
mDepthBufferList.emplace_back(image);
mFramebufferList.emplace_back(framebuffer);
}
here’s the fragment shader
#version 460
layout(location = 0) in vec3 inFragPos;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 0) out vec4 fragColor;
layout(set = 2, binding = 0) uniform sampler2D diffuseTexture;
layout(set = 2, binding = 1) uniform sampler2D specularTexture;
struct Light
{
vec4 Position;
vec4 Color;
};
layout(set = 0, binding = 0) uniform GlobalUniforBufferBlock
{
mat4 projectionView;
vec4 cameraPosition;
Light light[50];
}globalUniforBufferBlock;
layout(set = 2, binding = 2) uniform Material
{
vec4 diffuse;
vec4 ambient;
vec4 specular;
float shininess;
}material;
layout(early_fragment_tests) in;
void main()
{
vec4 diffuseTextureValue = texture(diffuseTexture, inUV);
vec4 specularTextureValue = texture(specularTexture, inUV);
fragColor = vec4(0.0 ,0.0 ,0.0 , 1.0);
vec3 normal = normalize(inNormal);
for(uint i = 0; i < 50; ++i)
{
float lightDistance = length(globalUniforBufferBlock.light[i].Position.xyz - inFragPos);
float lightLinear = 0.0014;
float lightConstant = 1.0;
float lightQuadratic = 0.000007;
float lightAttenuation = 1.0 / (lightConstant + (lightLinear * lightDistance) + (lightQuadratic * pow(lightDistance, 2.0)));
vec4 ambientValue = material.ambient * diffuseTextureValue * globalUniforBufferBlock.light[i].Color;
vec3 lightDirection = normalize(vec3(globalUniforBufferBlock.light[i].Position) - inFragPos);
float diffuse = max(dot(lightDirection, normal), 0.0);
vec4 diffuseValue = diffuse * diffuseTextureValue * material.diffuse * globalUniforBufferBlock.light[i].Color * lightAttenuation;
vec3 viewDirection = normalize(vec3(globalUniforBufferBlock.cameraPosition) - inFragPos);
vec3 lightReflection = normalize(reflect(-lightDirection, normal));
float specular = pow(max(dot(viewDirection, lightReflection), 0.0), material.shininess);
vec4 specularValue = specular * specularTextureValue * material.specular * globalUniforBufferBlock.light[i].Color * lightAttenuation;
fragColor += diffuseValue + ambientValue + specularValue;
}
}