Immersive Visualization / IQ-Station Wiki
This site hosts information on virtual reality systems that are geared toward scientific visualization, and as such often toward VR on Linux-based systems. Thus, pages here cover various software (and sometimes hardware) technologies that enable virtual reality operation on Linux.
The original IQ-station effort was to create low-cost (for the time) VR systems making use of 3DTV displays to produce CAVE/Fishtank-style VR displays. That effort pre-dated the rise of the consumer HMD VR systems, however, the realm of midrange-cost large-fishtank systems is still important, and has transitioned from 3DTV-based systems to short-throw projectors.
WebXR Linux
WebXR on Linux
WebXR is an API that allows XR experiences to be conveyed to users via a web browser interface. This can be an extremely convenient way to deliver certain immersive experiences to many end-users, both to all-in-one headsets such as the Meta-Quest series, or to PC-connected headsets.
Unfortunately, the only reliably available browsers that are capable of delivering WebXR experiences are on Microsoft-Windows and Android-based systems (phones and all-in-one headsets). This page describes efforts to remedy that situation as far as Linux browsers are concerned.
Note that this is largely possible, now that Monado has become a fully-functioning OpenXR runtime — especially for those of us that use HMDs/headsets that make use of Lighthouse tracking.
Current Status
While there are individuals who are known to have WebXR working with Chromium on their Linux system, I have not yet been able to fully attain that success, but there are glimmers of hope, including evidence that head position tracking data is received. What's not happening (for me) is that the graphics are not being transferred to the HMD due to errors that occur on my OS/GPU interface, but not necessarily for others.
But these instructions can be followed to at least get to the same point I have on my machine, and if you're fortunate it might "just work"!
For me, I don't intend to actually use the self-compiled version of Chromium for my day-to-day browsing, but to restrict using it for when I'm doing WebXR work, so I'm freer to experiment with the code.
Executive Summary
The core of this effort is based on the Chromium patches made available by Github users mrxz and rcetyle, and the general open-source nature of Chromium itself. For testing on Linux, I am using the Monado OpenXR Runtime, which I have successfully built and configured to run on both Rocky Linux (with an older Vive HMD) and Mint Linux (with a Valve Index HMD).
Building Chromium with WebXR (on Linux)
The first step of building Chromium with WebXR (on Linux) is of course to just be able to build Chromium on Linux, which turned out to not be as daunting as it might first seem, though depending on the capabilities of the system, it has taken me as much as 8 hours to do the initial build.
Another issue is getting to the same branch of the Chromium source that matches the WebXR patches that are available. Doing that is one of the services of this document, along with a handful of additional patching that I have added to get the final build to succeed.
Package Dependencies
The Building Chromium instructions has a lengthy list of dependencies, which for Ubuntu-based systems is ensconced in a bash script designed to load all of them. This is a problem both for people who don't have root/administrative access to their computer, and thus can't just willy-nilly be running bash scripts that require "sudo", but also for people who want to know what they are installing on their computer. On the other hand, for other Linux varients, there is a list of packages given as a single command line installation (again requiring root privileges!). I am not 100% convinced that all the listed packages are absolutely necessary (especially some that specifically install for an i686 chipset rather than x86_64. Also, some of these may be only needed for add-ons that I'm not interested in.
So unlike most of my build instructions, here is a list of packages that I am not installing on my systems(!):
- bluez-libs-devel
- libgcc.i686 — not sure why it wants the i686!
- libxkbcommon-x11-devel
- pciutils-devel
- zlib.i686 — not sure why it wants the i686!
- mod_ssl
- php & php-cli
- python-psutil — vs. the "python3-0psutil" which is installed
- wdiff — a tool that does word-by-word difference comparisons
What I did install on my Rocky system (and your mileage may vary depending on what you already have installed on your system) was:
- gperf
- Google's "depot_tools" — which requires Python3.9 at a minimum
- Because "depot_tools" requires Python3.8, and version "3.6.8" is the default on my system, I had to make a softlink to use the correct Python:
% cd .../depot_tools
% ln -s /usr/bin/python3.9 python3
What I installed on my Linux Mint system was:
- gperf
- generate-ninja — perhaps in lieu of pre-installing Google's "depot_tools" (which do get included as "third_party" code)
- apache2-ssl-dev
- php8.1-cli
- wdiff
Note that I already had OpenXR installed on my system, and I was hoping that
that would be sufficient for the Chromium build, however, it was
getting overly complicated in altering the Chromium configuration files
(BUILD.gn
), so in the end it was just easier to have OpenXR
built as a "third_party" contribution.
Chromium Source Code
The next step is to get the Chromium source code itself, and then do the build process. These steps are an amalgamation of the official Building Chromium instructions along with the instructions on adding the WebXR patch instructions from the README.md, plus a handful of additional steps that I had to add.
Note that the WebXR patch was created from Chromium version 130.0.6692, so
after the Chromium source is downloaded, one must change to that tagged branch,
and then update the source code.
(And because of this, using the --no-history
flag to save time and space in downloading the source should NOT be used.)
% cd Chromium
% fetch --nohooks chromium
% cd src
% git fetch origin 130.0.6692.0 --depth=1
% git checkout refs/tags/130.0.6692.0
% ls -lR third_party/openxr/ | grep $USER | wc -l
12
So far so good. The 12
count means only 12 files dealing with OpenXR
to this point, and this is where applying the WebXR patch expands the code:
% pushd ..
% wget https://raw.githubusercontent.com/rcelyte/webxr-linux/refs/heads/chromium/chromium/webxr-linux-vulkan.patch
% popd
% git apply --verbose ../webxr-linux-vulkan.patch
% gclient runhooks
% ls -lR third_party/openxr/ | grep $USER | wc -l
12
% gclient sync
% ls -lR third_party/openxr/ | grep $USER | wc -l
408
And two things to note. First, the OpenXR code went from 12 files to 408, but I wouldn't be concerned if these numbers don't match exactly — only that it would be a concern if there were only a handful of files for OpenXR. Second, if you had to create the Python3.9 softlink, some of these steps will remove that link and you'll have to make the link again.
At this point, we need to do some manual tweaks to the now-patched code:
% cp -p device/vr/BUILD.gn{,_orig}
% vi device/vr/BUILD.gn
[After the line: "//third_party/openxr", add these 4 lines:
"//gpu/vulkan", # Vulkan support
"//gpu/command_buffer/service", # Command buffer
"//gpu/ipc/service", # GPU IPC
"//third_party/vulkan-headers:vulkan_headers", # Vulkan headers
]
% diff device/vr/BUILD.gn{,_orig}
295,298d293
< "//gpu/vulkan", # Vulkan support
< "//gpu/command_buffer/service", # Command buffer
< "//gpu/ipc/service", # GPU IPC
< "//third_party/vulkan-headers:vulkan_headers", # Vulkan headers
% cat > third_party/vulkan-headers/BUILD.gn
import("//build/config/linux/pkg_config.gni")
group("vulkan_headers") {
include_dirs = [
"include",
]
}
^D
%
And here, the official instructions use Default
as the name of the build
they are creating, but I use WebXR
instead. You just need to be consistent,
but if you see Default
in the original directions, this is why mine is different.
Continuing:
% gn gen out/WebXR
% gn args out/WebXR
NOTE: an editor will open, and here you can put arguments for the build. Put the output from the next step as your arguments.
% cat out/WebXR/args.gn
# Set build arguments here. See `gn help buildargs`.
symbol_level=0
blink_symbol_level=0
v8_symbol_level=0
enable_nacl=false
enable_vulkan=true
enable_openxr=true
% autoninja -C out/WebXR chrome
And the autoninja
command will probably take a few hours!
Running Chromium with WebXR on Linux
Because of how Chromium works, there is a need to "un-sandbox" it such that it
can access files needed for OpenXR, so the --no-sandbox
option is
required for use.
There are other options as well, though given that I do not yet have it fully
functioning, it is not clear what other command-line options are required.
Likewise, there are "flags" that will need to be set, some of which can be indicated on the command line, or configured in the settings URL.
Here is how I am currently running my build of Chromium (from the same directory
I was in when running autoninja
above:
% out/WebXR/chrome --enable-features=OpenXR --enable-webxr --use-vulkan --no-sandbox
Here is a list of options that are required and/or possibly useful (or, until I know better, possibly detrimental):
--no-sandbox
— absolutely necessary--enable-features=OpenXR
--enable-webxr
--use-vulkan
--use-gl=egl
--use-cmd-decoder=passthrough
--ozone-platform-hint=auto
--enable-features=Vulkan,WebXRIncubations