Vulkan-glTF-PBR: physically based rendering with glTF models in Vulkan
Physical based rendering with Vulkan using glTF 2.0 models
At a glance
- What is it?
- Vulkan-glTF-PBR is a single, complete C++20 example that loads a glTF 2.0 model and shades it with a physically based, image based lighting pipeline in Vulkan, and it generates its own BRDF lookup table and environment maps on the GPU at startup rather than relying on offline tools. It is a sample to read and extend, not an engine, and the README is explicit about what it does not implement.
- Who is it for?
- Adopt this repository as a reference implementation if you are learning Vulkan, if you need to understand how image based lighting is assembled from a BRDF table and pre-filtered environment maps, or if you want a working Vulkan pipeline you can read in an afternoon.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 109 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A sample, not an engine
The project is described as a physically based rendering example implementation with image based lighting in Vulkan using glTF 2.0 models, and the lighting equation is based on the reference glTF PBR implementation from Khronos, the glTF-WebGL-PBR project.
That last detail is the most useful sentence in the README for a reader deciding whether to read the code. The shading model is not this project's invention, it is the Khronos reference brought into Vulkan, so the code is a translation of a specification you can compare against a WebGL implementation of the same equations. What the project adds is the Vulkan plumbing, and what it teaches is how the pieces fit together in a modern graphics API.
The scope is a single application with a few models. The repository carries the damaged helmet, Polly and the buster drone as screenshots, the official collection of glTF 2.0 sample models is linked for more, and there is a YouTube playlist walking through the Vulkan glTF 2.0 work.
The licence is MIT, the default branch is master, the last push was on 2026-07-07, and there are no GitHub releases, so the repository itself is the artefact rather than a published package.
The audience is somebody who knows what a framebuffer and a descriptor are, and who wants to see a complete, working, physically based renderer rather than a tutorial that stops at a triangle.
Model loading through tinyglTF, with an honest feature list
The loading side is handled by the vkglTF::Model class, and it uses the tiny glTF library to import the glTF 2.0 files, which means all the file formats supported by tinyglTF are supported. The class converts the glTF structures into Vulkan compatible structures used for setup and rendering.
The feature list is a checklist, and reading it tells you what you can expect. Loading arbitrary glTF 2.0 models is supported, with the full node hierarchy and full PBR material support, which covers the metallic-roughness workflow and the specular-glossiness workflow as an extension. Animations are supported, both articulated with translate, rotate and scale, and skinned. Support for Draco mesh compression is supported, with a link to the instructions. And morph targets are not supported, and that box is empty.
The note under the list is the important one. The model loader does not fully implement all aspects of the glTF 2.0 standard, and as such there is no guarantee that all glTF 2.0 models work properly.
The supported extensions are listed separately: KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_emissive_strength and KHR_texture_basisu.
Loading a different scene is a command line argument, so the sample ships one scene and lets you point it at anything:
Vulkan-glTF-pbr "PATH-TO-glTF-Sample-Models\2.0\BrainStem\glTF\brainstem.gltf"On Windows the application supports drag and drop, so you can drop a .gltf or a .glb file onto the main window. That is a small feature, and it is a good one to have in a sample, because it removes the need to retype a path while you are experimenting with models.
Three maps generated on the GPU at startup
The most interesting engineering decision in the project is that it generates its own texture maps rather than relying on offline tools, and it does this on the GPU during startup.
The physical based render model uses multiple source images for the lighting equation, and instead of relying on offline tools to generate those, this example generates all required texture maps during startup using the GPU.
The first is the BRDF lookup table. This pass generates a 2D BRDF lookup table based on the formulas used in the pbr implementation, and the lookup table contains BRDF values for roughness and view angle, stored as a 16-bit per component floating point texture to provide proper precision. The function is VulkanApplication::generateBRDFLUT().
The second is the irradiance cube map, a small 64 by 64 pixel cube map that stores the light radiated from the surrounding environment, and it is sampled for the indirect diffuse part of the lighting equation. The function is VulkanApplication::generateCubemaps() with the target IRRADIANCE.
The third is the pre-filtered, mip-mapped radiance environment cube map, which is sampled for the indirect specular part and stores specular contribution based on roughness. The mip chain stores increasing roughness values with increasing level count and is sampled accordingly when rendering the object, and the README shows the complete chain from roughness = 0.0 on the left to roughness = 1.0 on the right, across ten levels. The function is generateCubemaps() with the target PREFILTEREDENV.
Generating these at startup is a design choice with a cost, and the cost is startup time on every run. The benefit is that the sample has no asset pipeline, which for a repository someone wants to clone and build is worth a lot.
Building on Windows, Linux and Android with C++20
The build section says the repository contains everything required to compile and build the examples on Windows, Linux and Android using a C++ compiler that supports C++20, and that all required dependencies are included.
The Windows and Linux path goes through the provided CMakeLists.txt, which generates a build configuration for your favourite IDE or compiler. On Windows the example given is:
cmake -G "Visual Studio 14 2015 Win64"and on Linux it is:
cmake .
makeThe Android path is different, because it goes through Android Studio rather than a command line. The prerequisites are Android Studio Jellyfish, 2023.3.1, or higher, and the Android NDK. In Android Studio you select Import project, then select the android sub folder of the repository, and once the import has finished the project can be built, run and debugged from Android Studio. The note is that the Android SDK API version is set to 33, which is Android 13.
The repository layout supports this. There is an android/ directory with the Android Studio project, base/ holding the shared code including the Vulkan-glTF-PBR model class, src/ for the application, external/ for the bundled dependencies, libs/ and data/ for the assets, cmake/ for the build scripts, and a screenshots/ directory for the images in the README.
Submodules and the Draco decoder you have to build yourself
Two build details are worth reading before you clone, because both cost time the first time and neither is obvious.
The first is the submodules. The repository contains submodules for some of the external dependencies, so when doing a fresh clone you need to clone recursively:
git clone --recursive https://github.com/SaschaWillems/Vulkan-glTF-PBR.gitIf you have already cloned without the flag, the README gives the manual route, which is git submodule init followed by git submodule update.
The second is Draco mesh compression, which is a three step manual procedure because the decoder library is not vendored. You clone and build the Draco repository from Google according to their build instructions, copy the Draco decoder library dracodec.lib into libs\draco, and copy the contents of the src folder into external\draco, making sure that draco_features.h is also present. If everything is in place, running CMake will output Draco mesh compression enabled and loading Draco compressed meshes will work out of the box.
So Draco support is genuinely optional and genuinely manual. A project that shipped the decoder as a submodule would save an afternoon, and the reason it does not is that the decoder is a build artefact rather than source.
The net effect on an adopter is that the project builds out of the box on Windows, Linux and Android with no external dependencies to install, but two features, namely the submodules and Draco, are one step further from a clean build than the rest of the repository.
Editorial conclusion
Adopt this repository as a reference implementation if you are learning Vulkan, if you need to understand how image based lighting is assembled from a BRDF table and pre-filtered environment maps, or if you want a working Vulkan pipeline you can read in an afternoon. Do not adopt it as a production engine or as a general glTF loader, because the model loader does not fully implement the glTF 2.0 standard and the project says there is no guarantee that all models work properly. Verify first that your toolchain supports C++20, that you clone with the submodules, and that the features you need are on the checked list, since morph targets are explicitly not supported.
Frequently asked questions
What does Vulkan-glTF-PBR do?
It is a physically based rendering example implementation with image based lighting in Vulkan using glTF 2.0 models. The lighting equation is based on the reference glTF PBR implementation from Khronos, and the project generates the required texture maps on the GPU during startup instead of relying on offline tools.
Which glTF 2.0 features does the model loader support?
Arbitrary models, the full node hierarchy, full PBR material support in both the metallic-roughness and the specular-glossiness workflows, articulated and skinned animations, and Draco mesh compression. Morph targets are not supported, and the README warns that the loader does not fully implement the standard and that there is no guarantee all models work properly.
How do I build the examples?
Use the provided CMakeLists.txt with a C++20 compiler. On Windows the example given is cmake -G "Visual Studio 14 2015 Win64", and on Linux it is cmake . followed by make. For Android, import the android sub folder of the repository into Android Studio Jellyfish 2023.3.1 or higher with the NDK, and the SDK API level is set to 33.
How do I enable Draco mesh compression?
Clone and build the Draco repository from Google, copy the decoder library dracodec.lib into libs\draco, and copy the contents of the src folder into external\draco including draco_features.h. Running CMake then reports that Draco mesh compression is enabled and compressed meshes load out of the box.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/saschawillems-vulkan-gltf-pbr)Was this useful?