-
Notifications
You must be signed in to change notification settings - Fork 50
Description
Description
Custom OpenVR overlays created via IVROverlay::createOverlay() render behind the scene application (game) on Linux, making them invisible during gameplay. The overlays work correctly in the SteamVR grid/void environment and appear grayed out in the dashboard when pressed, confirming they are loaded and active but rendered at the wrong depth/layer.
The same overlay code works correctly on Windows where overlays render in front of the game scene as expected.
Steps to Reproduce
- Create a simple OpenVR overlay application using openvr.init(openvr.VRApplication_Overlay)
- Create an overlay with IVROverlay().createOverlay()
- Set overlay properties (color, alpha, width, texture via setOverlayFromFile)
- Set overlay transform with setOverlayTransformAbsolute() using TrackingUniverseSeated
- Call showOverlay()
- Launch any VR game (tested with DCS World via Proton and MSFS via Proton)
- Observe that the overlay is invisible during gameplay
- Press the system/menu button to open the dashboard
- Observe that the overlay appears grayed out in the dashboard view, confirming it exists but is rendered behind the scene
Expected Behavior
Overlays created via IVROverlay::createOverlay() should render in front of the game scene during gameplay, as they do on Windows. Per OpenVR documentation: "The vr::IVROverlay
interface provides access to draw 2D images over the 3D scene no matter which application is running."
Actual Behavior
Overlays render behind the scene application and are invisible during gameplay. They only become visible when:
- In the SteamVR void/grid environment (no scene app running)
- When the dashboard is activated (overlay appears grayed out)
Minimal Reproduction Code
import openvr
import time
import os
# Initialize as overlay application
openvr.init(openvr.VRApplication_Overlay)
overlay = openvr.IVROverlay()
# Create overlay
handle = overlay.createOverlay('test_overlay', 'test_overlay')
# Configure overlay
overlay.setOverlayColor(handle, 1, 1, 1)
overlay.setOverlayAlpha(handle, 1)
overlay.setOverlayWidthInMeters(handle, 0.5)
overlay.setOverlayFromFile(handle, '/path/to/image.png')
# Position in front of user
transform = openvr.HmdMatrix34_t()
transform[0][0] = 1.0
transform[1][1] = 1.0
transform[2][2] = 1.0
transform[0][3] = 0.0 # x
transform[1][3] = 0.0 # y
transform[2][3] = -1.0 # z (1m in front)
overlay.setOverlayTransformAbsolute(handle, openvr.TrackingUniverseSeated, transform)
overlay.showOverlay(handle)
# Keep running
while True:
time.sleep(0.1)
Flags/Settings Tested (None Fixed the Issue)
- VRApplication_Overlay (vs VRApplication_Background) - no change
- setOverlaySortOrder(handle, 100) - no change
- setOverlayFlag(handle, VROverlayFlags_SortWithNonSceneOverlays, True) - no change
- setOverlayFlag(handle, VROverlayFlags_VisibleInDashboard, False) - no change
System Information
- Linux Distribution: Garuda Linux (Arch-based, rolling)
- Kernel: 6.17.9-zen1-1-zen
- GPU: AMD Radeon RX 9070 XT (RDNA4, gfx1201)
- GPU Driver: Mesa radeonsi, LLVM 21.1.5, DRM 3.64
- SteamVR Version: 2.14.3
- Steam Client: Latest stable
- HMD: Quest 3S
Games Tested
- DCS World (via Proton)
- Microsoft Flight Simulator (via Proton)
Both exhibit identical behavior - overlays invisible during gameplay.
Additional Context
- Working Windows application (steam-vr-wheel) uses identical overlay code with no special flags and overlays work correctly on Windows
- This appears to be a compositor layering issue specific to Linux SteamVR where overlay layers are composited behind the scene layer instead of in front