Vulkan
C++ examples for the Vulkan graphics API
Install / Use
/learn @SaschaWillems/VulkanREADME
Vulkan C++ examples and demos
A comprehensive collection of open source C++ examples for Vulkan®, the low-level graphics and compute API from Khronos.
Table of Contents
- Official Khronos Vulkan Samples
- Cloning
- Assets
- Building
- Running
- Shaders
- A note on synchronization
- Examples
- Credits and Attributions
How to Vulkan in 2026
For an introduction on how to use Vulkan for graphics in 2026, see this repository. It's esp. helpful if you haven't done much with Vulkan (yet) and want to understand how Vulkan (and in turn these samples) work.
Official Khronos Vulkan Samples
Khronos has made an official Vulkan Samples repository available to the public (press release).
You can find this repository at https://github.com/KhronosGroup/Vulkan-Samples
As I've been involved with getting the official repository up and running, I'll be mostly contributing to that repository from now, but may still add samples that don't fit there in here and I'll of course continue to maintain these samples.
Cloning
This repository contains submodules for external dependencies and assets, so when doing a fresh clone you need to clone recursively:
git clone --recursive https://github.com/SaschaWillems/Vulkan.git
Existing repositories can be updated manually:
git submodule init
git submodule update
Building
The repository contains everything required to compile and build the examples on Windows, Android, iOS and macOS (using MoltenVK) using a C++ compiler that supports C++20.
See BUILD.md for details on how to build for the different platforms.
Running
Once built, examples can be run from the bin directory. The list of available command line options can be brought up with --help:
--help: Show help
-h, --height: Set window height
-v, --validation: Enable validation layers
-vs, --vsync: Enable V-Sync
-f, --fullscreen: Start in fullscreen mode
-w, --width: Set window width
-s, --shaders: Select shader type to use (glsl, slang, hlsl)
-g, --gpu: Select GPU to run on
-gl, --listgpus: Display a list of available Vulkan devices
-b, --benchmark: Run example in benchmark mode
-bw, --benchwarmup: Set warmup time for benchmark mode in seconds
-br, --benchruntime: Set duration time for benchmark mode in seconds
-bf, --benchfilename: Set file name for benchmark results
-bt, --benchframetimes: Save frame times to benchmark results file
-bfs, --benchmarkframes: Only render the given number of frames
-rp, --resourcepath: Set path for dir where assets and shaders folder is present
Note that some examples require specific device features, and if you are on a multi-gpu system you might need to use the -gl and -g to select a gpu that supports them.
Shaders
Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is GLSL, most samples also come with slang and HLSL shader sources, making it easy to compare the differences between those shading languages. The Rust GPU project maintains Rust shader sources in a separate repo.
Examples
Basics
-
Basic triangle using Vulkan 1.0
Basic and verbose example for getting a colored triangle rendered to the screen using Vulkan. This is meant as a starting point for learning Vulkan from the ground up. A huge part of the code is boilerplate that is abstracted away in later examples.
-
Basic triangle using Vulkan 1.3
Vulkan 1.3 version of the basic and verbose example for getting a colored triangle rendered to the screen. This makes use of features like dynamic rendering simplifying api usage.
-
Using pipeline state objects (pso) that bake state information (rasterization states, culling modes, etc.) along with the shaders into a single object, making it easy for an implementation to optimize usage (compared to OpenGL's dynamic state machine). Also demonstrates the use of pipeline derivatives.
-
Descriptors are used to pass data to shader binding points. Sets up descriptor sets, layouts, pools, creates a single pipeline based on the set layout and renders multiple objects with different descriptor sets.
-
Dynamic uniform buffers are used for rendering multiple objects with multiple matrices stored in a single uniform buffer object. Individual matrices are dynamically addressed upon descriptor binding time, minimizing the number of required descriptor sets.
-
Uses push constants, small blocks of uniform data stored within a command buffer, to pass data to a shader without the need for uniform buffers.
-
Uses SPIR-V specialization constants to create multiple pipelines with different lighting paths from a single "uber" shader.
-
Loads a 2D texture from disk (including all mip levels), uses staging to upload it into video memory and samples from it using combined image samplers.
-
Loads a 2D texture array containing multiple 2D texture slices (each with its own mip chain) and renders multiple meshes each sampling from a different layer of the texture. 2D texture arrays don't do any interpolation between the slices.
-
Loads a cube map texture from disk containing six different faces. All faces and mip levels are uploaded into video memory, and the cubemap is displayed on a skybox as a backdrop and on a 3D model as a reflection.
-
Loads an array of cube map textures from a single file. All cube maps are uploaded into video memory with their faces and mip levels, and the selected cubemap is displayed on a skybox as a backdrop and on a 3D model as a reflection.
-
Generates a 3D texture on the cpu (using perlin noise), uploads it to the device and samples it to render an animation. 3D textures store volumetric data and interpolate in all three dimensions.
-
Uses input attachments to read framebuffer contents from a previous sub pass at the same pixel position within a single render pass. This can be used for basic post processing or image composition (blog entry).
-
Advanced example that uses sub passes and input attachments to write and read back data from framebuffer attachments (same location only) in single render pass. This is used to implement deferred render composition with added forward transparency in a single pass.
-
Basic offscreen rendering in two passes. First pass renders the mirrored scene to a separate framebuffer with color and depth attachments, second pass samples from that color attachment for rendering a mirror surface.
-
Implements a simple CPU based particle system. Particle data is stored in host memory, updated on the CPU per-frame and synchronized with the device before it's rendered using pre-multiplied alpha.
-
Uses the stencil buffer and its compare functionality for rendering a 3D model with dynamic outlines.
-
Demonstrates two different ways of passing vertices to the vertex shader using either interleaved or separate vertex attributes.
glTF
These samples show how implement different features of the glTF 2.0 3D format 3D transmission file format in detail.
-
glTF model loading and rendering
Shows how to load a complete scene from a glTF 2.0 file. The structure of the glTF 2.0 scene is converted into the data structures required to render the scene with Vulkan.
-
Demonstrates how to do GPU vertex skinning from animation data stored in a glTF 2.0 model. Along with reading all the data structures required for doing vertex skinning, the sample also shows how to upload animation data to the GPU and how to render it using shaders.
-
[glTF scene rendering](
