coral_shadowmap_renderer.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "coral_shadowmap_renderer.h"
  2. #define DEPTH_FORMAT VK_FORMAT_D16_UNORM
  3. #define SHADOWMAP_DIM 2048
  4. #define DEFAULT_SHADOWMAP_FILTER VK_FILTER_LINEAR
  5. #include "vk_initializers.h"
  6. namespace coral_3d
  7. {
  8. coral_shadowmap_renderer::coral_shadowmap_renderer(coral_device& device)
  9. : device_{device}
  10. {
  11. create_framebuffer();
  12. }
  13. coral_shadowmap_renderer::~coral_shadowmap_renderer()
  14. {
  15. vkDestroyRenderPass(device_.device(), render_pass_, nullptr);
  16. vmaDestroyImage(device_.allocator(), frame_buffer_attachment_.image.image, frame_buffer_attachment_.image
  17. .allocation);
  18. vkDestroyFramebuffer(device_.device(), frame_buffer_, nullptr);
  19. }
  20. void coral_shadowmap_renderer::create_render_pass()
  21. {
  22. // ATTACHMENT DESCRIPTION
  23. VkAttachmentDescription attachment_description{};
  24. attachment_description.format = DEPTH_FORMAT;
  25. attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
  26. attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  27. // We will read from the depth, so it's important to store it
  28. attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  29. attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  30. attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  31. attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  32. // Attachment will be transitioned to shader read at render pass end
  33. attachment_description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
  34. // DEPTH REFERENCE
  35. // VkAttachmentReference depth_ref{};
  36. // depth_ref.attachment = 0;
  37. // depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  38. // SUB PASSES
  39. // VkSubpassDescription sub_pass{};
  40. // sub_pass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  41. // sub_pass.colorAttachmentCount = 0;
  42. // sub_pass.pDepthStencilAttachment = &depth_ref;
  43. // Dependencies
  44. std::array<VkSubpassDependency, 2> dependencies;
  45. dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  46. dependencies[0].dstSubpass = 0;
  47. dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  48. dependencies[0].dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
  49. dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
  50. dependencies[0].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  51. dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
  52. dependencies[1].srcSubpass = 0;
  53. dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  54. dependencies[1].srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  55. dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  56. dependencies[1].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  57. dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
  58. dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
  59. VkRenderPassCreateInfo create_info{};
  60. create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  61. create_info.pNext = nullptr;
  62. create_info.attachmentCount = 1;
  63. create_info.pAttachments = &attachment_description;
  64. create_info.subpassCount = 1;
  65. create_info.dependencyCount = static_cast<uint32_t>(dependencies.size());
  66. create_info.pDependencies = dependencies.data();
  67. vkCreateRenderPass(device_.device(), &create_info, nullptr, &render_pass_);
  68. }
  69. void coral_shadowmap_renderer::create_framebuffer()
  70. {
  71. width_ = SHADOWMAP_DIM;
  72. height_ = SHADOWMAP_DIM;
  73. // For shadow mapping we only need a depth attachment
  74. VkImageCreateInfo image_ci = vkinit::image_ci(DEPTH_FORMAT,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
  75. VK_IMAGE_USAGE_SAMPLED_BIT, {width_, height_, 1});
  76. VmaAllocationCreateInfo alloc_info{};
  77. alloc_info.usage = VMA_MEMORY_USAGE_GPU_ONLY;
  78. vmaCreateImage(device_.allocator(), &image_ci, &alloc_info, &frame_buffer_attachment_.image.image,
  79. &frame_buffer_attachment_.image.allocation, nullptr);
  80. VkImageViewCreateInfo depth_stencil_view = vkinit::image_view_ci(DEPTH_FORMAT, frame_buffer_attachment_.image
  81. .image, VK_IMAGE_ASPECT_DEPTH_BIT);
  82. vkCreateImageView(device_.device(), &depth_stencil_view, nullptr, &frame_buffer_attachment_
  83. .image_view);
  84. // Create sampler to sample from to depth attachment
  85. // Used to sample in the fragment shader for shadowed rendering
  86. VkFilter shadowmap_filter = DEFAULT_SHADOWMAP_FILTER;
  87. VkSamplerCreateInfo sampler = vkinit::sampler_ci(shadowmap_filter, 1.0f, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
  88. sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
  89. vkCreateSampler(device_.device(), &sampler, nullptr, &depth_sampler_);
  90. create_render_pass();
  91. // Create frame buffer
  92. VkFramebufferCreateInfo frame_buffer_ci{};
  93. frame_buffer_ci.renderPass = render_pass_;
  94. frame_buffer_ci.attachmentCount = 1;
  95. frame_buffer_ci.pAttachments = &frame_buffer_attachment_.image_view;
  96. frame_buffer_ci.width = width_;
  97. frame_buffer_ci.height = height_;
  98. frame_buffer_ci.layers = 1;
  99. vkCreateFramebuffer(device_.device(), &frame_buffer_ci, nullptr, &frame_buffer_);
  100. }
  101. } // coral_3d