linux vr setup
#author_luna #vr #linux #living_article
initally written
current version
world in picture: Umbra by Blue Cat
assuming:
- quest headset (quest 2 or quest 3), NOT lighthouse
- machine with nvidia gpu (proprietary driver), though amd works too
- X11, NOT wayland (don't talk to me about wayland. i do not care. it probably works tho)
- native setup with envision + OpenComposite
- monado with wivrn, NOT steamVR
- as foss as i can, because SVR is abandonware / valvetime-ware
if flatpak:
- note that envision may give you better performance due to
CAP_SYS_NICE=eip
being set by its build process. idk if the flatpak does that lol
flatpak install flathub io.github.wivrn.wivrn
flatpak run io.github.wivrn.wivrn
if envision:
- envision with gcc13.2.0 (currently shipped with void linux) causes a compiler bug. waiting for gcc14 to land
- HOWEVER using clang works wonderfully!
CC=clang CXX=clang++ ./Envision-x86_64.AppImage
- profile is set to https://github.com/notpeelz/WiVRn.git,
solarxr-patches
branch, more in the full body tracking section
get wlxoverlay-s while at it
get xrgears while at it so you can test your setup. there's no specific appimage or whatever so you'll need to build it. link is for void-packages (i use void linux, you may be able to find it on AUR if arch)
then pair the headset (get wivrn app from meta quest store) to the server, and connect to it. you aren't dropped to vr until there's a vr client, so open another terminal and ./wlxoverlay-s-whatever-version-u-got.appimage
i recommend looking over wlxoverlay-s' readme to see controller mappings. i also recommend configuring it such that show/hide follows your HMD center (xsoverlay-style behavior, i know)
audio #
- i use pipewire + pipewire-pulse
- need to configure default devices to use wivrn, got a small script that does it
- i believe those become availble as soon as HMD connects
- i configured wivrn to run this script on HMD connection, spins up overlays as well
#!/bin/sh set -eux pactl set-default-sink wivrn.sink pactl set-default-source wivrn.source
full body tracking #
- i use slimevr
currently https://lvra.gitlab.io/docs/slimevr/ gives 3 options for full body tracking:
- linux steamvr (nope, this is not a steamvr setup lol)
- linux solarxr (it's what i'm using right now)
- vrchat osc (can use)
vrchat osc with slimevr sucks if your trackers are using cheap IMUs like mine (my bad experience with ozivr), since osc does not give HMD position, slimevr has to assume HMD is always upright, which requires you to always stay upright on any reset (yaw, full, mounting), which i have to do every 10 minutes or so. makes for good exercise i guess, but for me it's unusable.
relevant prs:
- slimevr (merged!) https://github.com/SlimeVR/SlimeVR-Server/pull/1247
- monado (soon, hopefully!) https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2253
no need to build slimevr! appimage exists for the currently WIP version that contains solarxr support: https://github.com/SlimeVR/SlimeVR-Server/releases/tag/v0.14.0-rc1. you may need tricks for nvidia though:
env WEBKIT_DISABLE_DMABUF_RENDERER=1 ./SlimeVR-amd64.appimage
video games #
IMPORTANT the LVRA DB is now a thing: https://respuit.github.io/VRDB/, prefer going to it to find out compatibility information for your preffered vr apps.
generally, copy the environment variables from wivrn into the steam game's launch options and it'll mostly likely work (test results as of
- vrchat (works, generally), save for:
- as long as you disable antialiasing on nvidia gpus (or else, bad performance on mirrors)
- some worlds' shaders don't work very well on linux (one example i got is a world where its lights were way brighter than windows version, it was still a good world but it can be jarring to ppl)
- bug at loading environment. something related to opencomposite not working with steamvr overlays, which vrchat's loading screen is
- it's possible xrizer works but it's really new
- lvra is a good resource in general: https://lvra.gitlab.io/docs/vrchat/
- beat saber (works, no issues. mods work too! i use bsmanager with flatpak. more info at the bsmg wiki)
- pistol whip (works, missing: downloading custom maps from within proton, recentering)
- synth riders (works, including custom songs here. missing: recentering)
- tetris effect (works), issues:
- black border around my HMD FIXED by wivrn v0.23
- likely due to "Forward visibility mask and framerate change (OpenXR features)"
- recentering FIXED by wivrn v0.23
- well, fixed enough. there's a 5deg offset but that's nothing compared to 180deg
- black border around my HMD FIXED by wivrn v0.23
random notes #
- never use h265, broken. h264 for the win
- somehow i can now take 8k vrc pictures without everything locking up (and in the worst cases, not coming back to life), at worst vrchat is a bit slow for 5 seconds, but not frozen for 10~20
- if you use barrier / input-leap it'll fuck up spetacularly with wlxoverlay, requires a reboot to get that functionality back
- i am able to get syncthing to synchronize linux vrchat's pictures to my main computer without much issue (save for faulty ram which triggered disk corruption but shhh we don't talk about that)
- vrcx has a stable native linux build! https://github.com/vrcx-team/VRCX/releases/tag/v2025.01.31, this should Just Work (as long as you have dotnet) but if it doesn't, please talk around in vrcx discord and we'll hook you up. native linux support is quite new
avahi on void linux #
need avahi on void
xbps-install avahi
sudo ln -s /etc/sv/avahi-daemon/ /var/service/
- set
enable-dbus=yes
on/etc/avahi/avahi-daemon.conf
need dbus fixed on void
- i have both a system bus and a session bus
- got
dbus-run-session /usr/bin/awesome
configured under/usr/share/xsessions/awesomewm.desktop
already - seems avahi cant connect to system bus tho
2025-01-25T01:04:55.77879 daemon.warn: Jan 24 22:04:55 avahi-daemon[21245]: WARNING: No NSS support for mDNS detected, consider installing nss-mdns!
2025-01-25T01:04:55.77935 daemon.err: Jan 24 22:04:55 avahi-daemon[21245]: dbus_bus_request_name(): Connection ":1.12091" is not allowed to own the service "org.freedesktop.Avahi" due to security policies in the configuration file
2025-01-25T01:04:55.77939 daemon.warn: Jan 24 22:04:55 avahi-daemon[21245]: WARNING: Failed to contact D-Bus daemon.
need to restart dbus methinks. avahi package installs avahi.conf into dbus settings so it has perms
NOTE: need to restart entire system after restarting dbus system bus. everything explodes otherwise
https://stackoverflow.com/questions/4560877/dbus-bus-request-name-connections-are-not-allowed-to-own-the-service
wivrn can't start due to unknown error (999) in nvenc encoder #
following https://github.com/obsproject/obs-studio/issues/11381, i did this:
nvidia-smi
sudo modprobe -r nvidia-uvm
sudo modprobe nvidia-uvm
- restart wivrn
also https://github.com/tensorflow/tensorflow/issues/53341#issuecomment-1166532019
desktop mode #
while vrchat mainly targets windows, and its status is steam deck verified, that doesn't mean that you're guaranteed to work in all scenarios. there's various things specific to the VR setup (explained throughout this article), but there are some tips for desktop mode as well (which also apply to VR!)
main one being to use a custom Proton version for vrc. due to shenanigans with windows media apis, the way to map these APIs is not straightforward back to linux (especially when most vrchat worlds depend on AVPro, which is a proprietary component). we heavily recommend the proton-ge-rtsp patches by SpookySkeletons, most specifically GE-Proton9-20-rtsp15:
wget 'https://github.com/SpookySkeletons/proton-ge-rtsp/releases/download/GE-Proton9-20-rtsp15-1/GE-Proton9-20-rtsp15.tar.gz' tar -xvf ./GE-Proton9-20-rtsp15.tar.gz -C ~/.steam/steam/compatibilitytools.d/# restart steam!!!! then use it as the compat tool on vrchat
this seems to be the version that works the MOST in terms of youtube playback. however, there is one caveat. due to even more shenanigans with how youtube has been doing anti-bot and anti-adblock efforts, i have this small flowchart in terms of recommendations:
- if you're in the USA: GE-Proton9-20-rtsp15
- if you're NOT in the USA: GE-Proton9-22-rtsp17-1, but you will eat the cost of being unable to seek on youtube videos (only youtube videos specifically)
- IMPORTANT: this doesn't mean seeking is broken on everything. rtsp17-1 is recommended for things like watching movies with friends
- i've been playing with Proton Experimental but you'll need to
- run
steam steam://unlockh264/
to enable... h265 support (yes) - might deal with some bugs like low framerate
- run
NOTE: if you want to experiment, i am in the process of validating this version: GE-Proton10-15-rtsp18 with VRCVideoCacher, if things remain stable i'll promote them as my recommendations
face tracking #
THIS SECTION IS VERY WIP. the face tracking system is not finished until i can use it consistently, that's not the case yet. this is already a living article after all.
I DO NOT GUARANTEE THIS GUIDE TO WORK. on any system, for any user. no warranty is provided by me. this is a reference for my linux vr setup
firstly thank you very much to dfgHiatus and frozenreflex for helping me guide into a functional setup, answering my questions and in general working on the software powering all of this!
i've preordered Project Babble's official tracker and have been working on getting things running ON VOID LINUX (this means other distros MAY JUST BE EASIER LMAO!!!), here's how my setup went, in the hopes that others that don't have as many builtin components can start "from the ground up":
- setup the tracker firmware connect to wifi
- you may need udev rules so that the tracker is detected via usb
- can only continue if plugging the tracker to the computer gives you
/dev/ttyACM0
anddmesg
output about the device - currently, baballonia does not support setting up the firmware via usb on linux by itself, so don't setup it yet
- you'll have to use a separate tool as a workaround that talks through the serial openiris protocol to make the tracker join wifi:
- https://github.com/SummerSigh/OpenIris-ESPIDF/tree/mutimodal,
cd tools
, get a python venv (i am not providing python support: my python packaging patterns) - run
openiris_setup.py
, it should detect the tracker and you can use its TUI to put wifi credentials and make it join the network. after it joins wifi you can ping it to validate it works - to get mdns working:
- assert avahi can resolve the mdns of the tracker:
avahi-resolve --name openiristracker.local
should return the LAN IP for it - get nss-mdns installed (depends on avahi, which should be setup already in this setup!
avahi on void linux
is a subsection of this very article!) - open
http://openiristracker.local/
on firefox, it takes some seconds but afterwards you'll get an mjpeg stream and you SHOULD be able to see yourself, etc
- assert avahi can resolve the mdns of the tracker:
- from-source build of baballonia
- why?
- baballonia does ship appimages on its CI, but currently the appimages are broken. due to issues with velopack flattening the internal dll structure it leads to startup failures
- you can absolutely do
--appimage-extract
and mess around the appimage root so you can add the missing paths and restore a functional structure, but that path is absurdly hacky and not super reproducible. source builds should generally work better
- dependencies:
- gstreamer
- dotnet8 sdk, i have to do it on bespoke paths because of custom sdk packages i made. i am NOT good at csharp, and am not going to get an ide just for an end-user build
- after cloning the repo, it's mainly a process of building things in order as talked about in the README of baballonia, example:
cd src/Baballonia.OpenCVCapture
env "PATH=/opt/dotnet8/target DOTNET_ROOT=/opt/dotnet8/target" /opt/dotnet8/target publish
- repeat for 7 other modules
- keep going all the way to Baballonia.Desktop, build that too
- get model files (currently it depends on those files existing in CWD)
cp ./src/Baballonia/faceModel.onnx ./src/Baballonia.Desktop
cp ./src/Baballonia/eyeModel.onnx ./src/Baballonia.Desktop
- start baballonia
cd ./src/Baballonia.Desktop && env .. path/to/dotnet run
- set face tracker address of
http://openiristracker.local
- IMPORTANT on linux, OpenCVCapture basically does not work, prefer IpCameraCapture for much better stability (hopefully ipcamera can be set as default on linux)
- starting the tracker should connect to the stream and show it inside Baballonia
- why?
- VRCFaceTracking.Avalonia
- VRCFaceTracking is a primarily Windows-only application. VRCFT is a bridge between various face tracking hardware/software and VRChat itself
- why not wine?
- breaks. you can make it start but it'll attempt to get VRC OSC files from inside the wineprefix and simply explode
- why not wine?
- thankfully, VRCFT.Avalonia is a cross-platform port of it by dfgHiatus
- this one is much more standard. version v1.1.1.0 contains a ready-to-use appimage. you should be able to start it, install the babble module, and enjoy
- VRCFaceTracking is a primarily Windows-only application. VRCFT is a bridge between various face tracking hardware/software and VRChat itself
- workflow to link everything together
- START IN A SPECIFIC ORDER
- VRChat
- OSC mode on VRChat must be enabled already, see its docs:
- https://docs.vrchat.com/docs/osc-overview
- VRCFT.Avalonia
- it should be able to detect VRC running and get a hold of the current avatar you're using already (even if it doesn't support face tracking), would prove the two are communicating
- Baballonia
- Baballonia contacts with VRCFT.Avalonia via ports 8888 (send) and 8889 (receive), not 9000/9001 (an unfortunate catch that I misconfigured due to trying to fix other problems, like the startup order, thank you dfgHiatus for catching that)
- VRChat
- swap to an avatar with face tracking support, the babble documentation goes on more detail: https://docs.babble.diy/docs/software/integrations/vrc
- START IN A SPECIFIC ORDER
changelog #
- initial setup instructions for my face tracking setup
- update desktop mode section
- add desktop mode section
- no flatpak wivrn here thanks to clang
- keep flatpak wivrn instructions because flatpak is still a faster setup experience
- linux solarxr works perfectly
- LVRA DB is now a thing
- barrier being broken remains