Real-time PBR model viewer for glasses-free 3D displays, built on the
DisplayXR runtime via OpenXR with Vulkan. Loads glTF 2.0 (.glb / .gltf),
STL, OBJ, FBX, and USD (.usdz / .usd / .usda / .usdc)
models and renders them with asymmetric per-eye Kooima projection for the full
multiview 3D experience.
Loads metallic-roughness PBR materials with textures and image-based lighting, a blurred procedural skybox, and a transparent see-through mode (Windows). The bundled sample is the Khronos DamagedHelmet, auto-loaded at startup.
Requires the DisplayXR runtime v1.9.1 or newer (Windows) / the latest macOS runtime
.pkg. Download the matching installer from thedisplayxr-runtimereleases page:DisplayXRSetup-*.exeon Windows orDisplayXR-Installer-*.pkgon macOS. v1.9.1 ships the Vulkan transparent-window bridge + in-place resize this demo relies on; older runtimes produce a broken/black window or flicker on resize. The shell (displayxr-shell-releases) is optional — only needed for the spatial workspace shell.
| Format | Extensions | Materials | Notes |
|---|---|---|---|
| glTF 2.0 | .glb .gltf |
Full metallic-roughness PBR + textures | Reference path |
| STL | .stl |
Neutral default material | Binary + ASCII; geometry only |
| OBJ | .obj (+ .mtl) |
Phong → metallic-roughness shim | Best-effort material fidelity |
| FBX | .fbx |
PBR maps, Phong fallback | Skinned + animated (auto-plays first clip); no blend shapes yet |
| USD | .usdz .usd .usda .usdc |
UsdPreviewSurface PBR | Base-color/emissive textures + PBR factors; normal & metallic-roughness maps not yet honoured |
Every format feeds the same renderer (metallic-roughness PBR + image-based
lighting). Not yet supported: Draco mesh compression and KTX2 / Basis
textures (textures are PNG/JPEG only). See PORTING.md for the
per-backend breakdown and roadmap.
| Input | Action |
|---|---|
| WASD / Q / E | Strafe the virtual display in 3D |
| Left-click drag | Rotate the virtual display |
| Scroll / trackpad | Zoom (virtual display height) |
- / = |
Decrease / increase depth + IPD together (10 %–100 %) |
M |
Auto-orbit: slow turntable rotation when idle |
V |
Cycle rendering modes advertised by the display runtime |
L or top-bar Open… |
Load a different model (glTF / STL / OBJ / FBX / USD) |
| Drag-and-drop (macOS) | Load a supported model dropped onto the window |
| Space | Reset pose, zoom, depth |
| Tab | Toggle HUD |
| Ctrl+T | Toggle transparent background (desktop see-through; Windows only) |
| Esc | Quit |
- CMake ≥ 3.21 + Ninja
- Vulkan SDK (includes
glslangValidator) - OpenXR loader (find_package-visible)
- A DisplayXR-compatible runtime (install via
DisplayXRSetup-*.exefrom displayxr-runtime releases)
model_common/ fetches tinygltf, glm, and tinyusdz (USD) via CMake
FetchContent on first configure (no submodules); tinyobjloader (OBJ) and
ufbx (FBX) are vendored under model_common/third_party/. STL has no
dependency. The first configure builds tinyusdz from source, so it is slower.
brew install cmake ninja vulkan-sdk openxr-loader
./scripts/build_macos.sh
# Run against an installed DisplayXR runtime (handles the Vulkan-loader setup):
./scripts/run_macos_dev.shLaunch the dev build with
scripts/run_macos_dev.sh, not the bare binary. The dev binary links Homebrew's Vulkan loader while the installed runtime loads its own; the script converges both on one loader (and points Vulkan at the runtime's bundled MoltenVK) so thexrGetVulkanGraphicsDeviceKHRhandshake succeeds. The distributed.app(build_macos.sh --installer) bundles a self-consistent Vulkan stack and needs none of this.
REM Sets vcvars64 + OpenXR_ROOT + Vulkan SDK, then configures + builds.
scripts\build-with-deps.bat
REM Run
build\windows\model_viewer_handle_vk_win.exeUse
build-with-deps.bat, not the barebuild_windows.bat— the latter assumes you are already inside a VS developer environment.
.
├── macos/ Platform entry + window handling (Cocoa / MoltenVK)
├── windows/ Platform entry + window handling (Win32 / Vulkan)
├── model_common/ Multi-format PBR renderer: loaders + renderer + shaders
├── common/ Shared helpers: Kooima math, input, HUD
├── openxr_includes/ Vendored OpenXR headers (incl. DisplayXR extensions)
├── installer/ Windows NSIS + macOS .pkg installers
├── scripts/ Build scripts for each platform
└── PORTING.md Roadmap (port done; animation/skinning next)
common/ and openxr_includes/ are shared with the other DisplayXR demos and
were seeded from the runtime source tree.
This is a separate demo, not a mode bolted onto the splat viewer: it shows a different DisplayXR capability (mesh + PBR rendering) and grows the demo gallery. The renderer draws on techniques from the MIT-licensed SaschaWillems/Vulkan-glTF-PBR.
BSL-1.0 — see LICENSE. Bundled demo models carry their own licenses.