Jump to content

Starting with Shadowmaps on Vulkan


Now that we have lights working in our clustered forward Vulkan renderer (same great technique the latest DOOM games are using) I am starting to implement shadow maps. The first issue that came up was managing render-to-texture when the texture might still be in use rendering the previous frame. At first I thought multiple shadowmaps would be needed per light, like a double-buffering system, but that would double the number of shadow textures and video memory. Instead, I created a simple object pool which stores spare shadowmaps that can be swapped around and used as they are needed.

It turns out I already have pretty much all the code I need because Vulkan's swapchain creation works exactly the same way, by rendering to a series of images. I worked through the code slowly and came up with this by the end of the day, which runs successfully without throwing any validation errors:

	bool RenderBuffer::Initialize(shared_ptr<RenderContext> context, const int width, const int height, const int depth, const int colorcomponents, const bool depthcomponent, const int samples)
	{
		this->device = GameEngine::Get()->renderingthreadmanager->instance;

		int totalcomponents = colorcomponents;
		if (depthcomponent) totalcomponents++;

		std::fill(colortexture.begin(), colortexture.end(), nullptr);
		depthtexture = nullptr;

		//Create color images
		for (int i = 0; i < colorcomponents; ++i)
		{
			colortexture[i] = make_shared<RenderTexture>();
			colortexture[i]->Initialize(VK_IMAGE_TYPE_2D, device->chaininfo.imageFormat, width, height, 1, 0, false, -1,-1,-1,-1,1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
			colorimages[i] = colortexture[i]->vkimage;
		}

		//Create depth image
		if (depthcomponent)
		{
			depthtexture = make_shared<RenderTexture>();
			depthtexture->Initialize(VK_IMAGE_TYPE_2D, device->depthformat, width, height, 1, samples, false, -1, -1, -1, -1, 1, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
		}

		//Create image views
		imageviews.resize(totalcomponents);
		VkImageViewCreateInfo createInfo = {};
		createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
		createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
		createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
		createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
		createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
		createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
		createInfo.subresourceRange.baseMipLevel = 0;
		createInfo.subresourceRange.levelCount = 1;
		createInfo.subresourceRange.baseArrayLayer = 0;
		createInfo.subresourceRange.layerCount = 1;

		// Create color image views
		for (size_t i = 0; i < colorcomponents; i++)
		{
			createInfo.image = colorimages[i];			
			createInfo.format = device->chaininfo.imageFormat;
			createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
			VkAssert(vkCreateImageView(device->device, &createInfo, nullptr, &imageviews[i]));
		}

		//Create depth image view
		if (depthcomponent)
		{
			createInfo.image = depthtexture->vkimage;
			createInfo.format = depthtexture->format;
			createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
			VkAssert(vkCreateImageView(device->device, &createInfo, nullptr, &imageviews[colorcomponents]));
		}

		//Create framebuffer
		VkFramebufferCreateInfo framebufferInfo = {};
		framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
		framebufferInfo.renderPass = device->renderpass->pass;
		framebufferInfo.attachmentCount = 2;
		framebufferInfo.pAttachments = imageviews.data();
		framebufferInfo.width = width;
		framebufferInfo.height = height;
		framebufferInfo.layers = 1;
		VkAssert(vkCreateFramebuffer(device->device, &framebufferInfo, nullptr, &framebuffer));

		return true;
	}

The blog cover image isn't the Vulkan renderer, I just found a random image of Leadwerks shadows.

  • Like 3

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...