Blitz3D+ Guides

Automatic PC VR — experimental

Attach a headset to one existing perspective camera. The engine tracks the head, renders stereo geometry and submits through OpenXR using the usual RenderWorld / Flip loop. The camera entity remains the authored player base. No headset/runtime/GPU combination is yet qualified for production use.

Start with the sample

Open AutomaticVR.bb in Full Win64 Extended mode. Install and select your headset vendor's PC OpenXR runtime, connect the headset, then run the program. If preparation fails the sample displays the reason and continues on the desktop. Full Win32 and OpenXR-disabled builds run the same source with unsupported-backend results.

prepared = InitVR()
Graphics3D 960,640,32,2
camera = CreateCamera()
CameraRange camera,0.05,100
PositionEntity camera,0,1.6,0
If prepared Then EnableVR(camera,1.0)

One scene unit is one metre here. The authored camera is the seated head height. The first valid head sample sets the seated translation and yaw origin; physical pitch and roll remain intact. R in the sample recentres. H toggles the HUD, M the desktop mirror, and +/- adjusts eye resolution. Escape exits. Mouse, keyboard and gamepad retain their ordinary desktop behavior; headset focus is a separate query.

Frame and scene rules

Advance simulation once, then call RenderWorld once and Flip once. The engine prepares one scene snapshot and renders two eyes; it does not call UpdateWorld for either eye. The sample uses fixed 60 Hz ticks with UpdateWorld 1 and elapsed seconds only to accumulate ticks. Do not reinterpret UpdateWorld's elapsed-time argument as seconds.

RenderWorld twice before Flip, another world, or RenderWorldToCanvas while VR is enabled reports an error and abandons the pending stereo frame. Flip without RenderWorld can submit a HUD-only frame; it never replays stale geometry. A runtime request not to render produces no layers. Invalid tracking suppresses stereo until a usable sample returns. Continue servicing the loop while invisible or waiting. Queries never block or pump events.

The camera must be perspective with a finite rigid ancestry and an ordered positive clipping range. Do not scale or mirror its parents. EnableVR's positive world-units-per-metre argument scales translations and eye separation. Windowed Graphics3D modes 2 and 3 are supported; exclusive fullscreen, autosuspend and GUI targets are rejected. DisableVR before rebinding a camera or changing world scale. Picking still uses the authored camera; head/controller picking is not provided.

HUD, mirror and sound

Draw ordinary 2D text/images after RenderWorld. They appear on a premultiplied-alpha head-relative panel, 1.2 m wide at 1.5 m by default. Untouched pixels are transparent; Cls or an opaque image produces an opaque panel. HUD dimensions are physical metres, independently of world scale. Resizing the back buffer adjusts its aspect at a subsequent frame boundary.

The optional mirror copies the left eye and composites the desktop HUD. XR pacing bypasses desktop VSync and FrameLimit; a busy mirror can skip presentation. CaptureFrame captures the left eye plus HUD, including when the mirror is disabled. Explicit capture readback can stall and must not be used for latency measurements. VRListener opts the existing audio-world listener into head-centre position/orientation once per rendered sample; authored velocity is retained. Zero detaches it.

Rendering support and effect policy

If the session is waiting or not visible, check that the headset is awake and its PC VR environment is connected. A successful EnableVR accepts the session request; it does not guarantee the runtime is displaying the application. The engine continues the OpenXR frame loop while obeying the runtime's rendering flag. Run the sample with --diagnose to write vr-diagnostics.txt in its working directory, including runtime version, headset system, adapter LUID, eye dimensions and frame-state transitions.

The experimental renderer uses two sequential views with independent targets and temporal history. Asymmetric eye projection reaches culling, shadows, planar reflections, decals and depth reconstruction. GPU texture tests cover asymmetric raster positions, HDR/AA output, HUD alpha and mirror ownership. These checks do not establish headset optical correctness or comfort. Terrain detail selection uses the shared head centre; each eye still culls separately.

Eye output is display-encoded RGBA8 with an sRGB swapchain declaration, so the compositor interprets its colour correctly without a second application-side conversion. The HUD decodes its source colours before blending into a separate linear RGBA8 UNORM, premultiplied-alpha layer. The backend accepts the corresponding typeless Direct3D resources returned by OpenXR.

Camera post effects are skipped by default in VR, including depth of field, motion blur, distortion and unqualified custom effects. Their authored enabled flags and parameters are preserved for desktop use. A format-2/3 layout-4 post manifest may declare vr-compatible 1 after layout and mode. The compiler and loader validate this declaration. It is an author assertion: use full inverse projection for depth reconstruction, operate on the supplied eye inputs, and avoid shared cross-eye history or forced symmetric projection. Qualify the result on hardware before opting it in. Skips are recorded once in diagnostics.

Failure and recovery

Save VRLastError$() immediately after a failed command; the next fallible command clears it. Queries preserve it. InitVR must precede any graphics device. Adapter overrides that conflict with the headset keep the requested desktop adapter and abandon VR. Runtime/session loss returns to desktop when graphics remains healthy. DisableVR may remain STOPPING until the runtime responds. ShutdownVR resets all settings; EndGraphics and IDE Stop clean up owned resources. To restart after terminal loss, close graphics, prepare VR and recreate the scene.

Scope and qualification

This is Windows PC stereo viewing through OpenXR 1.0 and XR_KHR_D3D12_enable. There are no tracked-controller actions, haptics, locomotion conversion, room-scale collision, independent spectator camera, compositor depth, foveation, Android/standalone-headset builds, or editor VR preview. Camera shake, locomotion, aiming and first-person weapons require application-specific VR design.

Production qualification still requires real headset/runtime/GPU testing, OpenXR validation-layer traces, focus/loss/reconnect/debugger/resize tests and CPU/GPU/frame-delivery measurements at the headset refresh rates. See the source-tree implementation progress record for measured results and outstanding gates.

VR command reference