Featured Article

Vulkan Shadow Mapping Tutorial: Real-Time Shadows with Shadow Maps

Cynthia Jul 13, 2026

Vulkan, a modern graphics and computing API, has revolutionized real-time 3D rendering and its capabilities extend to advanced techniques like shadow mapping. Shadow mapping is a rendering method used to create realistic shadows in computer graphics, adding depth and realism to 3D scenes. In this article, we will delve into a practical example of implementing shadow mapping with Vulkan, providing a comprehensive guide for both beginners and experienced developers.

Volcanoes
Volcanoes

Before we proceed with the example, let's quickly recap the basics of shadow mapping. Shadow mapping is a form of shadow rendering technique where a depth buffer is used to store the depth information of each pixel in the scene from the perspective of the light source. This technique allows us to determine if a pixel is in shadow or not, thereby creating realistic shadows.

volcano diagram with labeled parts labelled in black and white, including the main ventils
volcano diagram with labeled parts labelled in black and white, including the main ventils

Setting Up the Shadow Mapping Pipeline

To implement shadow mapping in Vulkan, we first need to set up a pipeline that consists of two main stages:

13 Volcano Worksheets 2nd Grade
13 Volcano Worksheets 2nd Grade

1. The first stage is the depth pass, where we render the scene from the perspective of the light source and store the depth information in a depth buffer.

Depth Pass: Rendering from the Light's Perspective

an image of the inside of a volcano
an image of the inside of a volcano

In this stage, we disable any fragementshader that would normally output color or lighting information. Instead, we use a simple pass-through shader that outputs the depth value of each vertex to the depth buffer. This stage is typically accomplished using a separate framebuffer that only contains a depth attachment.

Here's an example of a simple depth pass shader:

```vulkan layout(location=0) in vec2 inVertex; layout(location=0) out float outDepth; void main() { outDepth = -gl_Position.z; } ```

The Shadow Mapping Technique

an image of a volcano with lava coming out of it
an image of a volcano with lava coming out of it

In the second stage, known as the shadow pass, we render the scene from the camera's perspective. For each fragment, we lookup the depth value from the depth buffer generated in the first stage. If the depth value from the first stage is greater than the depth value from the second stage, the fragment is considered to be in shadow; otherwise, it is in light.

During this stage, we use a fragment shader to compare the depth of each fragment with the stored depth in the texture. If the fragment's depth is greater than the depth stored in the texture, then the fragment is in shadow, and we discard it; otherwise, we only illuminate it.

Implementing Shadow Mapping in Vulkan

different types of volcanos are shown in this diagram, including the top and bottom layers
different types of volcanos are shown in this diagram, including the top and bottom layers

Now that we have a basic understanding of the shadow mapping pipeline, let's discuss how to implement it in Vulkan:

Creating Vulkan Buffers and Textures

the structure of a volcano is shown in this graphic above it's main features
the structure of a volcano is shown in this graphic above it's main features
Mauna Lava
Mauna Lava
an image of the volcano with labeled parts
an image of the volcano with labeled parts
two different views of the same area with rocks and lavas in it, as well as
two different views of the same area with rocks and lavas in it, as well as
GitHub - kevinblighe/EnhancedVolcano: Publication-ready volcano plots with enhanced colouring and labeling
GitHub - kevinblighe/EnhancedVolcano: Publication-ready volcano plots with enhanced colouring and labeling
the steps to drawing volcanos in adobe and photoshopped with text that reads, how
the steps to drawing volcanos in adobe and photoshopped with text that reads, how
Lava Falls • game location bioms • background asset
Lava Falls • game location bioms • background asset
an image of a volcano with lava in the background
an image of a volcano with lava in the background
an image of a volcano with lava and rocks around it on a white background illustration
an image of a volcano with lava and rocks around it on a white background illustration

As mentioned earlier, we need to create a depth buffer (Vulkan buffer) and depth texture (Vulkan image) for storing the depth information. We also need a framebuffer for rendering to the depth texture. In Vulkan, creating buffers and textures involves allocating memory, creating buffer/image objects, and binding them together.

Here is a basic example of creating a depth buffer and framebuffer:

```c VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, nullptr, 0, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 0, nullptr}; vkCreateBuffer(device, &bufferInfo, nullptr, &depthBuffer); VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, nullptr, 0, VK_IMAGE_TYPE_2D, format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SHARING_MODE_EXCLUSIVE, 0, nullptr, {width, height, 1}, 1, 1, VK_IMAGE_TILING_OPTIMAL, 0, nullptr, nullptr}; vkCreateImage(device, &imageInfo, nullptr, &depthImage); VkFramebufferCreateInfo framebufferInfo = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, width, height, 1, nullptr, nullptr, nullptr, nullptr}; vkCreateFramebuffer(device, &framebufferInfo, nullptr, &depthFramebuffer); ```

Depth Prepass and Shadow Pass

Once the buffers and textures are set up, we can begin implementing the depth pass and shadow pass shaders in GLSL and associating them with pipeline stages using Vulkan. We use the Vulkan command buffer to schedule and execute these passes.

Again, this is a high-level overview, and actual implementation would involve setting up the command buffer, recording commands, and executing them. Also, texture sampling and depth comparison are done in the fragment shader of the shadow pass, and you need to set up appropriate texture samplers and depth buffer parameters.

That wraps up our discussion about Vulkan shadow mapping. By following this guide, you should be well-equipped to implement shadow mapping in your Vulkan applications. Keep in mind that performance optimization and extremes like large or dynamic lighting situations might require more advanced techniques. Happy coding, and may your shadows be realistic and your frames be smooth!