Featured Article

Vulkan Deferred Rendering Tutorial

Cynthia Jul 13, 2026

Vulkan, a low-overhead, cross-platform 3D graphics and computing library, introduces several advanced rendering techniques, one of which is deferred rendering. This approach decouples geometry and lighting processing, improving performance in complex scenes. Here, we'll explore a practical example of Vulkan deferred rendering.

lava volcano, poster, 3d render
lava volcano, poster, 3d render

Before delving into our example, let's briefly recap traditional forward rendering. In this method, the scene is rendered twice: first for geometry, then for lighting. This approach can become bottlenecked in complex scenes with numerous light sources, as each light source's computations are performed per-draw call. Deferred rendering, however, performs lighting calculations once per pixel, optimizing performance.

a painting of a volcano in the middle of a dark sky with red and orange clouds
a painting of a volcano in the middle of a dark sky with red and orange clouds

Setting Up the Scene: Geometry and Light Propositions

The first step in our deferred rendering example involves setting up the scene, including geometry and lighting elements. Here, we'll use simple 3D models and several strategic light sources to highlight the benefits of deferred rendering.

Reaching For The Stars, Volcano, Stars
Reaching For The Stars, Volcano, Stars

For geometry, we'll employ the ubiquitous Vulkan hello triangle as a starting point. To enrich the scene, let's introduce more complex models like a teapot or a bunny model. As for lighting, we'll consider a combination of directional, point, and spotlights, each with distinct intensities, colors, and attenuation parameters.

Vulkan's Render Pass and Framebuffer

lava flowing down the side of a mountain at sunset with clouds in the sky above
lava flowing down the side of a mountain at sunset with clouds in the sky above

For deferred rendering, we need a pristine render pass configuration. This includes setting up a framebuffer with multiple attachments—one for the G-buffer (geometry buffer), containing depth, normals, and albedo data, and another for the lighting pass.

We'll utilize the VkFramebufferCreateInfo structure, adding our VkImageView attachments for color and depth, along with their respective layouts. The Vulkan setup function will create and configure the framebuffer, ensuring it's ready for our rendering stages:

```cpp VkFramebufferCreateInfo framebufferCreateInfo = vkinit::framebufferCreateInfo sponsored::swapChainImageCount, swapChainImageFormat, { colorImageView, depthImageView }, swapChainExtent.width, swapChainExtent.height, 1); ```

The Geometry Pass: Recording the G-Buffer

The Volcano
The Volcano

The geometry pass is the first stage in our deferred rendering pipeline. We'll record a Vulkan command buffer, binding the appropriate pipeline and descriptor sets. The scene's geometry will then be drawn, with each object's albedo, normal, and position data stored in the G-buffer.

Here, we can use Vulkan's early depth test to cull unnecessary fragments, saving computational resources. We'll set up the pipeline configuration with a depth test and write the depth attachment:

```cpp VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkinit::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true, false); VkPipelineRasterizationStateCreateInfo rasterizer = vkinit::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE); VkPipelineColorBlendStateCreateInfo colorBlending = vkinit::pipelineColorBlendStateCreateInfo(1, VK_FALSE); VkPipelineDepthStencilStateCreateInfo depthStencilState = vkinit::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE); VkPipelineMultisampleStateCreateInfo multisampling = vkinit::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); VkPipelineDynamicStateCreateInfo dynamicStates = vkinit::pipelineDynamicStateCreateInfo({ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }); ```

Shading and Lighting: Illuminating the Scene

an image of a fantasy scene with lava and trees
an image of a fantasy scene with lava and trees

In the lighting pass, we bring our scene to life by sampling data from the G-buffer and incorporating light source computations. For each pixel, we'll gather data from the 3D space, calculate lighting contributions, and apply them to produce the final color output.

To create the lighting pass pipeline, we'll follow a similar setup process as the geometry pass. Differences lie in the shaders, where we'll utilize the data stored in the G-buffer for light interpolation. Using the Vulkan vkCmdBindPipeline function, we'll set the pipeline for the lighting pass:

an image of a fantasy scene with lava and volcanos in the background at night
an image of a fantasy scene with lava and volcanos in the background at night
an image of a volcano with lava pouring out of it
an image of a volcano with lava pouring out of it
an aerial view of a volcano erupting lava and glowing lava in the distance
an aerial view of a volcano erupting lava and glowing lava in the distance
an aerial view of the inside of a volcano
an aerial view of the inside of a volcano
Molten Lava Aesthetic, Volcanic Art, Fantasy Volcanic Art, Fantasy Landscape With Erupting Volcano, Volcanic Eruption, Fiery Volcanic Landscape, Volcanic Fantasy Scenery, Volcanic Fantasy World, Molten Mountain
Molten Lava Aesthetic, Volcanic Art, Fantasy Volcanic Art, Fantasy Landscape With Erupting Volcano, Volcanic Eruption, Fiery Volcanic Landscape, Volcanic Fantasy Scenery, Volcanic Fantasy World, Molten Mountain
SỔ PHÁN QUAN KAI KỆ MẪU LÀ PHÁP BẢO TRẤN LONG MẠCH: 🌏🌎🌍 ThiênAnQuânLao~ChiAnBãoTỐ🗺️Hàn Quốc 🫧⛩️
SỔ PHÁN QUAN KAI KỆ MẪU LÀ PHÁP BẢO TRẤN LONG MẠCH: 🌏🌎🌍 ThiênAnQuânLao~ChiAnBãoTỐ🗺️Hàn Quốc 🫧⛩️
an image of a volcano with lava and fire in the air as it erupts
an image of a volcano with lava and fire in the air as it erupts
an image of a volcano with lava and water flowing down the mountain side at sunset
an image of a volcano with lava and water flowing down the mountain side at sunset
Pele is at it again! The volcano is erupting with the Hawaiian goddess Tūtū Pele the goddess of...
Pele is at it again! The volcano is erupting with the Hawaiian goddess Tūtū Pele the goddess of...

```cpp vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); ```

Final Render Target: Combining Geometry and Lighting

The final stage of our deferred rendering example involves blending the results of the geometry and lighting passes to produce the final color output. We'll set the framebuffer to our color attachment and begin rendering, applying the geometry pipeline. Once complete, we switch to the lighting pipeline and begin rendering light-mapped geometry.

After rendering, we'll present the result to the screen using Vulkan's swapchain. We'll submit the command buffer to the Vulkan queue, ensuring our rendered output is displayed on the target window:

```cpp vkQueuePresentKHR(presentQueue, &presentInfo); ```

In closing, utilizing Vulkan's deferred rendering in complex 3D scenes offers significant performance advantages. By decoupling geometry and lighting passes, we reduce redundant operations and optimize rendering. Our presented example demonstrates the key steps in achieving this, providing a solid foundation for further exploration and optimization within Vulkan's ecosystem.