Skip to content

Small Windows application to pass thru two camera views to the corresponding eyes of a VR headset

Notifications You must be signed in to change notification settings

Danealor/VRPassthrough

Repository files navigation

VR Passthrough Standalone

A lightweight, high-performance standalone XR application for real-time stereo camera passthrough to VR headsets. Designed for the Bigscreen Beyond 2e with dual ELP CC01 USB cameras.

Overview

This application provides minimal-latency video passthrough from USB cameras directly to a VR headset compositor, bypassing the overhead of game engines like Unity. Built with OpenXR and DirectX 11 for maximum performance and battery efficiency.

Key Features

  • Low Latency: Direct camera-to-compositor pipeline (1-2 frame latency)
  • Efficient: ~90% less CPU/GPU usage compared to Unity-based solution
  • Auto-Reconnect: Automatic camera reconnection on disconnect
  • Configurable Rotation: 90° increment rotation (0°, 90°, 180°, 270°)
  • Debug Overlay: Real-time performance metrics via ImGui
  • Dual Logging: Console and file-based logging

Hardware Requirements

  • VR Headset: Bigscreen Beyond 2e (or any OpenXR-compatible headset)
  • Cameras: 2x ELP CC01 USB cameras (1920x1080@50fps, YUY2/MJPEG)
  • PC: Windows 10/11, USB 3.0 ports on separate controllers
  • Graphics: DirectX 11 compatible GPU

Software Requirements

  • Windows 10/11
  • SteamVR with OpenXR runtime
  • Visual Studio 2022 (for building)
  • CMake 3.20+

Architecture

┌─────────────────┐
│  DirectShow     │ ──> Capture 2 camera streams (YUY2/MJPEG)
│  Camera Capture │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Frame Processor│ ──> YUY2→RGBA conversion (GPU compute shader)
│                 │     + Rotation (90° increments)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  OpenXR Runtime │ ──> Submit to VR compositor
│  (SteamVR)      │     Left camera → Left eye
└─────────────────┘     Right camera → Right eye

Components

  1. Camera Manager (camera_manager.cpp): DirectShow camera enumeration, capture graph setup, auto-reconnect
  2. XR Session (xr_session.cpp): OpenXR lifecycle, D3D11 swapchain management, frame timing
  3. Frame Processor (frame_processor.cpp): YUY2→RGBA conversion, rotation, texture rendering
  4. Main Loop (main.cpp): Event polling, frame synchronization, reconnection logic
  5. Debug Overlay (debug_ui.cpp): ImGui-based performance metrics

Project Structure

VRPassthrough/
├── src/
│   ├── main.cpp                 # Entry point and main loop
│   ├── camera_manager.h/cpp     # DirectShow camera handling
│   ├── xr_session.h/cpp         # OpenXR lifecycle
│   ├── frame_processor.h/cpp    # GPU texture processing
│   ├── debug_ui.h/cpp           # ImGui debug overlay
│   ├── logger.h/cpp             # Logging system
│   └── config.h                 # Configuration structure
│
├── shaders/
│   ├── yuv_to_rgba.hlsl        # YUY2 → RGBA conversion (compute)
│   └── rotate_texture.hlsl     # Rotation shader (vertex + pixel)
│
├── external/                    # Third-party dependencies (gitignored)
│   ├── openxr/                 # OpenXR SDK
│   └── imgui/                  # Dear ImGui
│
├── build/                       # CMake build output (gitignored)
├── CMakeLists.txt              # Build configuration
├── config.ini                  # Runtime configuration
├── DESIGN.md                   # Detailed design documentation
└── README.md                   # This file

Configuration

Edit config.ini to customize behavior:

[Camera]
NameFilter=3.0 USB Camera
Width=1920
Height=1080
FPS=50
Format=YUY2
Rotation=180

[Display]
# EyeWidth=2560    # Optional: override auto-detection
# EyeHeight=2560

[Advanced]
AutoReconnect=true
MaxReconnectAttempts=0      # 0 = infinite
ReconnectDelay=2.0
DebugLogging=false
DebugOverlay=true

Building

Prerequisites

  1. Install Visual Studio 2022 with C++ Desktop Development workload
  2. Install CMake 3.20+ (or use VS2022's built-in CMake)
  3. Install SteamVR

Build Steps

# Clone repository
cd VRPassthrough

# Download dependencies (see DESIGN.md for details)
git submodule update --init --recursive

# Create build directory
mkdir build
cd build

# Configure CMake
cmake .. -G "Visual Studio 17 2022" -A x64

# Build
cmake --build . --config Release

# Run
cd Release
./VRPassthrough.exe

Usage

  1. Connect both ELP cameras to separate USB 3.0 controllers
  2. Start SteamVR
  3. Run VRPassthrough.exe
  4. Put on headset - you should see stereo passthrough
  5. Press F1 to toggle debug overlay (shows FPS, latency, camera status)

Performance Comparison

Metric Unity Version Standalone C++
CPU Usage 30-40% 5-10%
GPU Usage 40-50% 15-25%
RAM Usage 1.5-2 GB 200-300 MB
Frame Latency 3-5 frames (40-66ms) 1-2 frames (13-26ms)
Battery Life ~1-2 hours ~3-4 hours (est)

Troubleshooting

Cameras Not Detected

  • Ensure cameras are on separate USB controllers (check Device Manager)
  • Try different USB ports (opposite sides of laptop)
  • Check NameFilter in config.ini matches camera name

"Could Not Start Graph" Error

  • USB bandwidth issue - disconnect other USB devices
  • Lower resolution/FPS in config.ini
  • Switch from YUY2 to MJPEG format

Low Performance on Battery

  • Check Windows power plan (High Performance mode)
  • Ensure laptop stays awake with lid closed (see CLAUDE.md)

Cameras Disconnect During Use

  • Auto-reconnect should handle this automatically
  • Check USB cable connections
  • Verify AutoReconnect=true in config.ini

Development

See DESIGN.md for detailed architecture documentation.

Key Technologies

  • OpenXR 1.0: Cross-runtime XR API
  • DirectX 11: Graphics API for texture management
  • DirectShow: Windows camera capture API
  • HLSL: Shader language for GPU processing
  • Dear ImGui: Debug UI framework

License

This project is part of a werewolf costume VR passthrough system. See CLAUDE.md for full project history.

Acknowledgments

  • OpenXR Working Group for the OpenXR specification
  • Omar Cornut for Dear ImGui
  • Bigscreen for the Beyond 2e VR headset

About

Small Windows application to pass thru two camera views to the corresponding eyes of a VR headset

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors