A barebones example of how to integrate OpenXR with wgpu (Vulkan-only)

Overview

wgpu-openxr-example

a barebones example of how to integrate OpenXR with wgpu (Vulkan-only)

It has four modes:

  • cargo run --no-default-features: desktop-only, renders the scene without any XR integration
  • cargo run -- desktop: build with XR support, but render the scene without initialising XR
  • cargo run -- desktop-with-xr-resolution: build with XR support, initialise XR, but do not render to headset
  • cargo run -- xr: build with XR support, and render to the headset

These modes are intended to show you how to gracefully integrate XR into your project's code and how you can move from one stage of integration to the next.

Note that this code is not production-quality; there are a few shortcuts that have been taken in the interest of keeping it simple and relatively modular. Make sure to clean up your resources properly and use robust code where possible :)

Rendering flow

The code renders three instances of a triangle (two being the controllers) to a multi-view render target.

  • In desktop mode, this render target is then blitted to the swapchain, and the user can select which view to look at using the arrow keys.
  • In desktop with XR resolution mode, much the same occurs, except the window is resized to the XR headset's render resolution.
  • In XR mode, the program synchronises with the headset and blits the multi-view render target to the headset as well.

Rendering to a render target is necessary to accommodate these:

  • Showing what the user is seeing within the desktop window, without having to re-render the scene
  • Decoupling the colour formats of the various display surfaces; wgpu (on my machine) will offer BGRA8888, while my OpenXR runtime offers RGBA8888.

Future

It should theoretically be possible to do the following:

  • D3D11/12 backend with OpenXR
  • WebGL2 backend with WebXR
  • Metal backend with ARKit

Reference

Cobbled together from the following sources:

Comments
  • Question: Why only Vulkan

    Question: Why only Vulkan

    First of all thank you for this great example!

    It's early in my reading but I'm wondering why not let wgpu choose the underlying device and then write a TryFrom impl or similar for the openxr state. Bear in mind I'm still skimming this repo and have not yet grokked it. Essentially, why go from openxr to wgpu instead of the other way around?

    opened by schell 3
  • Crash on session idle followed by session ready

    Crash on session idle followed by session ready

    The existing logic does not handle the headset being made available after loss, resulting in the swapchain being used improperly and a resulting crash.

    bug 
    opened by philpax 0
  • When trying to run the xr flags, the app panics.

    When trying to run the xr flags, the app panics.

    Error logs

    Error [GENERAL | xrCreateInstance | OpenXR-Loader] : ApiLayerInterface::LoadApiLayers - failed to find layer XR_APILAYER_LUNARG_core_validation
    Error [GENERAL | xrCreateInstance | OpenXR-Loader] : Failed loading layer information
    Error [GENERAL | xrCreateInstance | OpenXR-Loader] : xrCreateInstance failed
    Error: a requested API layer is not present or could not be loaded
    error: process didn't exit successfully: `target\debug\wgpu-openxr-example.exe desktop-with-xr-resolution` (exit code: 1)
    

    Hardware and software

    • Valve index
    • SteamVR (stable and beta versions tested)
    • Windows 11
    • Radeon RX 6800 XT
    • Driver version 22.5.1
    opened by 1SMOL 1
  • Unable to load swapchain

    Unable to load swapchain

    I'm trying to run the example with cargo run -- xr and am getting this error:

    PS C:\Users\efsub\source\repos\wgpu-openxr-example> $env:RUST_BACKTRACE=1; cargo run -- xr
        Finished dev [unoptimized + debuginfo] target(s) in 1.32s
         Running `target\debug\wgpu-openxr-example.exe xr`
    loaded OpenXR runtime: SteamVR/OpenXR 0.1.0
    thread 'main' panicked at 'Unable to load create_swapchain_khr', C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\ash-0.37.0+1.3.209\src\vk\extensions.rs:268:21
    stack backtrace:
       0: std::panicking::begin_panic<str>
                 at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\std\src\panicking.rs:616
       1: ash::vk::extensions::impl$9::load::create_swapchain_khr
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\ash-0.37.0+1.3.209\src\vk\extensions.rs:268
       2: ash::extensions::khr::swapchain::Swapchain::create_swapchain
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\ash-0.37.0+1.3.209\src\extensions\khr\swapchain.rs:64
       3: wgpu_hal::vulkan::Device::create_swapchain
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-hal-0.13.2\src\vulkan\device.rs:559
       4: wgpu_hal::vulkan::instance::impl$5::configure
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-hal-0.13.2\src\vulkan\instance.rs:737
       5: wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>::surface_configure<wgpu_core::hub::IdentityManagerFactory,wgpu_hal::vulkan::Api>
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-core-0.13.2\src\device\mod.rs:5089
       6: wgpu::backend::direct::impl$3::surface_configure
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-0.13.1\src\backend\direct.rs:1003
       7: wgpu::Surface::configure
                 at C:\Users\efsub\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-0.13.1\src\lib.rs:3576
       8: wgpu_openxr_example::main
                 at .\src\main.rs:136
       9: core::ops::function::FnOnce::call_once<enum2$<core::result::Result<tuple$<>,anyhow::Error> > (*)(),tuple$<> >
                 at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\core\src\ops\function.rs:248
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    error: process didn't exit successfully: `target\debug\wgpu-openxr-example.exe xr` (exit code: 101)
    

    I have since installed the LunarG Vulkan SDK, installed the latest drivers for my GPU (Nvidia GeForce GTX 1060) and SteamVR is running before I run cargo run -- xr. Are there any other setup steps I'm forgetting?

    opened by schell 12
  • Android builds

    Android builds

    With the increasing prevalence of standalone Android headsets, it's important to have this compile and work on the major headsets (Quest 2, Pico 4, Lynx R-1, etc) to ensure that people can see how to build something for the standalone market.

    enhancement help wanted 
    opened by philpax 0
  • Figure out what's going on with the coordinate space

    Figure out what's going on with the coordinate space

    I've bodged the transform from OpenXR space to wgpu space:

    let xr_rotation = {
        let o = pose.orientation;
        Quat::from_rotation_x(180.0f32.to_radians()) * glam::quat(o.w, o.z, o.y, o.x)
    };
    let xr_translation = glam::vec3(-pose.position.x, pose.position.y, -pose.position.z);
    

    This is very much trial and error and not based in any kind of well-understood transformation. Getting to the bottom of this would be ideal.

    enhancement good first issue 
    opened by philpax 0
Owner
Philpax
gamedev / systems programming / he/him
Philpax
Proof-of-concept of getting OpenXR rendering support for Bevy game engine using gfx-rs abstractions

Introduction Proof-of-concept of getting OpenXR rendering support for Bevy game engine using gfx-rs abstractions. (hand interaction with boxes missing

Mika 52 Nov 14, 2022
Tic-Tac-Toe on the GPU, as an example application for wgpu

Tic-Tac-GPU A simple (cough cough) example on a tic-tac-toe game with wgpu. Why? Because I didn't find that many small applications which use wgpu as

multisn8 2 Oct 7, 2022
egui-tetra is a library that helps integrate egui

egui-tetra is a library that helps integrate egui, an immediate mode GUI library, with Tetra, a 2D game framework.

null 19 Jan 5, 2023
An easy way to integrate @rhaiscript with @bevyengine.

Bevy Rhai What is Bevy Rhai? Bevy Rhai is an easy way to integrate and use Rhai with Bevy. It provides everything you need to get started, all you nee

Leon Davis 10 Jun 12, 2022
Vulkan rendering sandbox for raytracing

sol-rs ☀ sol-rs is a small rendering toolkit for Vulkan, with a focus on real-time raytracing (which is not currently available via other APIs such as

Éric Renaud-Houde 65 Dec 7, 2022
GFA visualizer, GPU-accelerated using Vulkan

gfaestus - Vulkan-accelerated GFA visualization Demo: https://youtu.be/TOJZeeCqatk gfaestus is a tool for visualizing and interacting with genome grap

Christian Fischer 46 Nov 29, 2022
Vulkan and Rust rendering~game engine which creation is covered with YouTube videos

Vulkan and Rust rendering~game engine which creation is covered with YouTube videos

小鳥 11 Dec 4, 2022
A vulkan library.

Docs.rs vkvk A vulkan library. Running The Example The shaders aren't compiled as part of the build script. Instead, run shader_build.bat (or copy the

Lokathor 7 Mar 13, 2023
A modern 3D/2D game engine that uses wgpu.

Harmony A modern 3D/2D game engine that uses wgpu and is designed to work out of the box with minimal effort. It uses legion for handling game/renderi

John 152 Dec 24, 2022
A curated list of wgpu code and resources.

Awesome wgpu A curated list of wgpu code and resources. PRs welcome. About wgpu https://github.com/gfx-rs/wgpu-rs matrix chat https://matrix.to/#/#wgp

Roman Frołow 283 Jan 3, 2023
Simple profiler scopes for wgpu using timer queries

wgpu-profiler Simple profiler scopes for wgpu using timer queries Features Easy to use profiler scopes Allows nesting! Can be disabled by runtime flag

null 41 Dec 5, 2022
Scion is a tiny 2D game library built on top of wgpu, winit and legion.

Scion is a 2D game library made in rust. Please note that this project is in its first milestones and is subject to change according to convience need

Jérémy Thulliez 143 Dec 25, 2022
Rustcraft is a simple Minecraft engine written in rust using wgpu.

Rustcraft is a simple Minecraft engine written in rust using wgpu.

Raphael Van Hoffelen 110 Dec 22, 2022
Self Study on developing a game engine using wgpu as the rendering API. Learning as I go.

Fabled Engine Any issues, enhancement, features, or bugs report are always welcome in Issues. The obj branch is where frequent development and up to d

Khalid 20 Jan 5, 2023
Guide for using gfx-rs's wgpu library.

Introduction What is wgpu? Wgpu is a Rust implementation of the WebGPU API spec. WebGPU is a specification published by the GPU for the Web Community

sotrh 1k Dec 29, 2022
game engine built in rust, using wgpu and probably other stuff too

horizon game engine engine for devpty games, made in 99.9% rust and 0.1% shell. this is our main project currently. the engine will be used for most i

DEVPTY 2 Apr 12, 2022
🍖A WGPU graphics pipeline, along with simple types used to marshal data to the GPU

renderling ?? This library is a collection of WGPU render pipelines. Shaders are written in GLSL. shaderc is used to compile shaders to SPIR-V. Defini

Schell Carl Scivally 5 Dec 20, 2022
🦅🦁 Fast, simple 2D text renderer for wgpu

?? glyphon ?? Fast, simple 2D text rendering for wgpu What is this? This crate provides a simple way to render 2D text with wgpu by: rasterizing glyph

Josh Groves 60 Nov 5, 2022
3d Cellular Automata using WGPU in Rust (for the web and using compute shaders)

3D-Cellular-Automata-WGPU 3d Cellular Automata using WGPU in Rust (for the web and using compute shaders) The branches are very messy... I recommend y

null 18 Dec 18, 2022