Skip to main content
VR streaming is experimental. Pixel Streaming for VR is still under active development by Epic Games and is not production-ready. Expect rough edges around input mapping, head-tracking jitter, and codec / framerate stability. Use it for prototypes, demos, and internal testing — not for shipping consumer experiences.
The outcome: a viewer puts on a Quest, opens your URL in the headset’s browser, taps “Enter VR,” and is inside your Unreal experience — no APK install, no app store, no native binary.

What works, what doesn’t

Streampixel streams pixels, and WebXR puts those pixels onto a stereo display. Combined, they let any WebXR-capable browser become a VR client.
Streampixel does not ship a native VR runtime. WebXR is the bridge — if a device’s browser exposes a WebXR session, the SDK can hand the stream to it.

Step 1 — Prepare the Unreal project

VR is an in-engine choice, not a different build target. You still package for Windows like any other Streampixel project — the VR-specific work is inside the editor:
  • Start from the VR template (or add VR Pawn + WebXR-friendly setup to an existing project).
  • Disable OpenXR (it conflicts with Pixel Streaming). See Prepare a VR experience.
  • Render in stereo (single-pass instanced recommended).
  • Target a stable framerate matching the headset (72, 90, or 120 Hz).
  • Use a forward renderer for best perf on standalone headsets.

Step 2 — Enable XR input in the SDK

The SDK has an xrInput config flag. Enable it on the page that will request the WebXR session:
xrInput: true tells the SDK to listen for WebXR controller, hand, and pose events and forward them to Unreal as input. Without it, the headset will display the stream but controllers will not function inside the UE world.

Step 3 — Trigger the WebXR session

Browsers require a user gesture (a tap or click) to enter immersive mode. Wire up a button:
Always feature-detect with navigator.xr.isSessionSupported('immersive-vr') before showing the button. Without that check, desktop visitors will see a button that throws on click.

Step 4 — Pick the right codec

Standalone headsets do most decoding in fixed-function silicon. The decoder’s codec support is what determines whether your stream plays smoothly or stutters. Set H264 as your default in the dashboard (Codec settings) for any project that targets headsets. Other codecs may negotiate but will burn battery and miss frame deadlines.

Step 5 — Tune for the device

Streampixel can deliver up to ~1080p per eye comfortably; pushing higher requires more bitrate and more decoder headroom. Start at 1920×1080 per eye, 25–30 Mbps, H264, and tune from there. See Performance tuning for bitrate guidance.

Latency

VR is unforgiving of lag. A delay between head movement and rendered frame that you would never notice on a 2D stream becomes nausea-inducing in stereo. Things that move latency in the right direction:
  • Closest region. A 30 ms RTT improvement is more valuable than any encoder tweak.
  • Wired or 6 GHz Wi-Fi. Standalone headsets on 2.4 GHz Wi-Fi are the most common cause of “this feels laggy” complaints. Quest 3 and Vision Pro on Wi-Fi 6E typically work well.
  • H264 over VP9. H264 hardware decode shaves several ms compared to software-decoded VP9.
  • Lower minQP in the dashboard’s adaptive settings, only if your bitrate budget allows it. Quality dips at the same bitrate, but frames arrive faster.

Gotchas

localhost over HTTP works during development on Quest browsers, but Safari on Vision Pro will not surface the WebXR API on insecure origins. Use a local HTTPS dev server (mkcert, Caddy, or vite --https) to test there.
navigator.xr.requestSession only resolves if it is called synchronously from a click or tap event. Wrapping it in a Promise chain that awaits something else first (like the SDK’s onVideoInitialized) breaks the gesture link. Always trigger from the button click handler directly.
Pass optionalFeatures: ['hand-tracking'] if your UE project expects hand input. If you require it, use requiredFeatures instead — the session will fail to start on devices without hand tracking, which is the right behavior for hand-only experiences.
Quest and Pico route audio to the headset speakers by default. Some users with paired Bluetooth headphones experience added audio latency that does not match the visual stream. Document this for your testers; there is no fix on the streaming side.
A standalone headset decoding a 30 Mbps H264 stream while running its display at 90 Hz drains the battery in roughly 90–120 minutes. For longer experiences, recommend tethered power or build in checkpoints.

Next steps

Prepare a VR experience

In-engine setup: VR Pawn, OpenXR, rendering paths.

Codec settings

Lock H264 as the default for headset audiences.

Performance tuning

Bitrate and resolution recipes that ship without dropped frames.

Regions

Pick the closest region — VR latency is dominated by RTT.