Blazingly fast1 Vulkan glTF viewer.

OPAQUE, MASK (using alpha testing and Alpha To Coverage) and BLEND (using Weighted Blended OIT) materials.LINE_LOOP support as Vulkan does not support it natively..glb).KHR_materials_emissive_strengthKHR_materials_iorKHR_materials_unlit for lighting independent material shadingKHR_materials_variantsKHR_mesh_quantizationKHR_texture_basisu for BC7 GPU compression texture decodingKHR_texture_transformEXT_mesh_gpu_instancing for instancing multiple meshes with the same geometryEXT_meshopt_compressionClick the below image will redirect the page to the YouTube video (due to the GitHub's policy, I cannot directly embed the video into markdown).
See Performance Comparison page for the performance comparison with other desktop glTF viewers.
I initially developed this application for leveraging Vulkan's performance and using some modern GPU features, like bindless/GPU driven rendering/etc. There are two main goals for this application: speed and memory consumption. Here are some key points:
VK_EXT_descriptor_indexing extension.VK_KHR_buffer_device_address. Only index buffers are bound to the command buffer.memcpyed into the GPU memory with dedicated transfer queue. No pre-processing is required!
VK_IMAGE_USAGE_STORAGE_BIT flags for the images, which can enable the Delta Color Compression (DCC) in the AMD GPUs (I've not tested this in an AMD GPUs).[!WARNING] Currently the latest Vulkan SDK (1.4.335) is broken when using Vulkan-Hpp named module. Please use Vulkan SDK 1.4.328 until the issue is solved.
The extensions and feature used in this application are quite common in the modern desktop GPU drivers, so I hope you don't have any problem with this.
[!TIP] My primary development environment is Apple M1 Pro, so if you're MoltenVK user, you'll be able to run this application.
VK_KHR_dynamic_renderingVK_KHR_synchronization2VK_EXT_extended_dynamic_state (dynamic state cull mode)VK_KHR_push_descriptorVK_KHR_swapchainVK_KHR_swapchain_mutable_format (proper ImGui gamma correction, UI color will lose the color if the extension not presented)VK_EXT_attachment_feedback_loop_layout (optimized bloom composition)VK_EXT_index_type_uint8 (if not presented, unsigned byte primitive indices will re-generated with uint16_ts)VK_EXT_shader_stencil_export (more plausible bloom effect)VK_AMD_shader_image_load_store_lod (can replace the descriptor indexing based cubemap mipmapping and prefilteredmap generation2)VK_EXT_extended_dynamic_state3 (if supported and VkPhysicalDeviceExtendedDynamicState3PropertiesEXT::dynamicPrimitiveTopologyUnrestricted is true, can reduce the pipeline switch for different primitive topologies)VkPhysicalDeviceFeatures
depthClampdrawIndirectFirstInstancemultiViewportsamplerAnistropyshaderInt16multiDrawIndirectshaderStorageImageWriteWithoutFormatindependentBlend (Weighted Blended OIT)fragmentStoresAndAtomicsVkPhysicalDeviceVulkan11Features
shaderDrawParameters (use gl_BaseInstance for primitive index)storageBuffer16BitAccessuniformAndStorageBuffer16BitAccessmultiview (reducing cubemap image precision with color correction)VkPhysicalDeviceVulkan12Features
bufferDeviceAddressdescriptorIndexingdescriptorBindingPartiallyBounddescriptorBindingSampledImageUpdateAfterBinddescriptorBindingVariableDescriptorCountruntimeDescriptorArrayshaderOutputViewportIndexseparateDepthStencilLayoutsstorageBuffer8BitAccessscalarBlockLayouttimelineSemaphoreshaderInt8drawIndirectCount (If not presented, GPU frustum culling will be unavailable and fallback to the CPU frustum culling.)shaderBufferInt64Atomics (better mouse picking precision)VkPhysicalDeviceDynamicRenderingFeaturesVkPhysicalDeviceSynchronization2FeaturesVkPhysicalDeviceExtendedDynamicStateFeaturesEXTVkPhysicalDeviceIndexTypeUint8FeaturesEXT (if not presented, unsigned byte primitive indices will re-generated with uint16_ts)VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXTmaxDescriptorSetUpdateAfterBindSamplers and maxDescriptorSetUpdateAfterBindSampledImages, respectively.maxDescriptorSetUpdateAfterBindSamplers.This project requires support for C++20 modules and the C++23 standard library. The supported compilers are:
The following build tools are required:
Additionally, you need vcpkg for dependency management. Make sure VCPKG_ROOT environment variable is defined as your vcpkg source directory path!
This project depends on:
module), which has the following dependencies:
Dependencies will be automatically fetched via vcpkg.
Also, there are some optional dependencies that are enabling the features. These are not included in vcpkg.json by default.
KHR_texture_basisu extension..exr skybox.You can provide the dependencies at the CMake configuration time to enable the corresponding features. Followings are some ways to provide.
# Provide all optional dependencies, with platform agnostic way (most recommended).
# Be aware that fetching cgal will be extremely slow since it fetches all of the boost dependencies and build gmp and mpfr.
vcpkg add port cgal ktx openexr
# Provide CGAL, if you're using Ubuntu and apt system package manager.
sudo apt install libcgal-dev
# Provide OpenEXR, if you're using macOS and Homebrew system package manager.
brew install openexr
[!TIP] This project uses GitHub Runner to ensure build compatibility on Windows (with MSVC and MinGW Clang), macOS and Linux (with Clang), with dependency management handled by vcpkg. You can check the workflow files in the .github/workflows folder.
First, you have to clone the repository.
git clone https://github.com/stripe2933/vk-gltf-viewer
cd vk-gltf-viewer
The CMake preset is given by default.
cmake --preset=default
cmake --build build -t vk-gltf-viewer
The executable will be located in build folder.
Install Clang, libc++ and extra build dependencies from MSYS2 pacman.
pacman -S mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-libc++ mingw-w64-clang-x86_64-libwinpthread-git
Add the following CMake user preset file in your project directory. I'll assume your Clang compiler executable is at C:/tools/msys64/clang64/bin/clang++.exe.
CMakeUserPresets.json
{
"version": 6,
"configurePresets": [
{
"name": "windows-mingw-clang",
"inherits": "default",
"cacheVariables": {
"CMAKE_C_COMPILER": "C:/tools/msys64/clang64/bin/clang.exe",
"CMAKE_CXX_COMPILER": "C:/tools/msys64/clang64/bin/clang++.exe",
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
"VCPKG_TARGET_TRIPLET": "x64-windows-mingw-clang"
}
}
]
}
VCPKG_TARGET_TRIPLET configuration parameter is mandatory for make vcpkg uses Clang compiler instead of the system default compiler. Add following vcpkg toolchain and triplet files.
mingw-clang-toolchain.cmake
include($ENV{VCPKG_ROOT}/scripts/toolchains/mingw.cmake)
set(CMAKE_C_COMPILER C:/tools/msys64/clang64/bin/clang.exe)
set(CMAKE_CXX_COMPILER C:/tools/msys64/clang64/bin/clang++.exe)
triplets/x64-windows-mingw-clang.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH "PATH;VCPKG_ROOT")
set(VCPKG_CMAKE_SYSTEM_NAME MinGW)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../mingw-clang-toolchain.cmake)
set(VCPKG_C_FLAGS "")
set(VCPKG_CXX_FLAGS "-stdlib=libc++")
Configure and build the project with windows-mingw-clang configuration preset.
cmake --preset=windows-mingw-clang
cmake --build build -t vk-gltf-viewer
The executable will be located in build folder.
Install libc++ and extra build dependencies from apt.
sudo apt install clang-19 clang-tools-19 libc++-19-dev libc++abi-19-dev xorg-dev libtool libltdl-dev
Add the following CMake user preset file in your project directory. I'll assume your Clang compiler executable is at /usr/bin/.
CMakeUserPresets.json
{
"version": 6,
"configurePresets": [
{
"name": "linux-clang",
"inherits": "default",
"cacheVariables": {
"CMAKE_C_COMPILER": "/usr/bin/clang-19",
"CMAKE_CXX_COMPILER": "/usr/bin/clang++-19",
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
"CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++ -lc++abi",
"VCPKG_TARGET_TRIPLET": "x64-linux-clang"
}
}
]
}
VCPKG_TARGET_TRIPLET configuration parameter is mandatory for make vcpkg uses Clang compiler instead of the system default compiler. Add following vcpkg toolchain and triplet files.
clang-toolchain.cmake
include($ENV{VCPKG_ROOT}/scripts/toolchains/linux.cmake)
set(CMAKE_C_COMPILER /usr/bin/clang-19)
set(CMAKE_CXX_COMPILER /usr/bin/clang++-19)
triplets/x64-linux-clang.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../clang-toolchain.cmake)
set(VCPKG_C_FLAGS "")
set(VCPKG_CXX_FLAGS "-stdlib=libc++")
set(VCPKG_LINKER_FLAGS "-stdlib=libc++ -lc++abi")
Configure and build the project with linux-clang configuration preset.
cmake --preset=linux-clang
cmake --build build -t vk-gltf-viewer
The executable will be located in build folder.
Install extra build dependencies from homebrew.
brew install autoconf automake libtool nasm
Add the following CMake user preset file in your project directory. I'll assume your Clang compiler executable is at /opt/homebrew/opt/llvm/bin/.
CMakeUserPresets.json
{
"version": 6,
"configurePresets": [
{
"name": "macos-clang",
"inherits": "default",
"cacheVariables": {
"CMAKE_C_COMPILER": "/opt/homebrew/opt/llvm/bin/clang",
"CMAKE_CXX_COMPILER": "/opt/homebrew/opt/llvm/bin/clang++",
"VCPKG_TARGET_TRIPLET": "arm64-macos-clang"
}
}
]
}
VCPKG_TARGET_TRIPLET configuration parameter is mandatory for make vcpkg uses Clang compiler instead of the system default compiler. Add following vcpkg toolchain and triplet files.
homebrew-clang-toolchain.cmake
include($ENV{VCPKG_ROOT}/scripts/toolchains/osx.cmake)
set(CMAKE_C_COMPILER /opt/homebrew/opt/llvm/bin/clang)
set(CMAKE_CXX_COMPILER /opt/homebrew/opt/llvm/bin/clang++)
triplets/arm64-macos-clang.cmake
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../homebrew-clang-toolchain.cmake)
Configure and build the project with macos-clang configuration preset.
cmake --preset=macos-clang
cmake --build build -t vk-gltf-viewer
The executable will be located in build folder.
All shaders are located in the shaders folder and will be automatically compiled to SPIR-V format during the CMake configuration time. The result SPIR-V binary files are located in the build/shader folder.
KHR_texture_basisu).This project is licensed under the GPL-v3 License. See the LICENSE file for details.
I like this term because it's hilarious for several reasons, but it's no joke! It has the significantly faster glTF model loading speed than the other the viewers I've tested. See Performance Comparison page for details. ↩
On Apple GPU platform prior to the MoltenVK 1.2.11 (which enables the Metal Argument Buffer by default), maxPerStageDescriptorUpdateAfterBindStorageImages is 8. It limited the cubemap resoluton and prefilteredmap roughnesslevels. Instead, it can use VK_AMD_shader_image_load_store_lod extension to replace the descriptor indexing based cubemap mipmapping and prefilteredmap generation. ↩