Currently the first mode to try is OpenXR. If you are using compatible Oculus HMD you might also check the oculus native mode. The OpenVR is not fully compatible with 1.50+ and will likely have worse performance. The only feature it provides which the other modes do not currently have is the ability to draw the models of the controllers which is of very limited use.
Starting with 1.55 it is possible to enable VR support also in the normal builds however there are a few extra caveats to that:
- Only OpenXR is supported in those builds.
- When the build is not part of a experimental* or oculus* branch on Steam, you will need to specify additional command line parameter -experimental_vr to enable VR support.
- The VR features in the normal build are likely to lag behind the VR build. VR improvements happening after release of the normal build will be frequently only included in the VR build until the next major update.
- It is possible that some VR changes will be initially too big hacks/too experimental to include in the normal build so they will be only available in the VR build until they can be integrated properly.
- The eye tracking experiment (see the OpenXR section below).
- Oculus SDK 1.4.0
- OpenVR SDK 1.10.30
- OpenXR SDK 1.0.34
- A really fast GPU and CPU is recommended.
- Only DX11 mode is supported.
- The game assumes parallel projection for both eyes and will use the same orientation for both eyes.
- The game is currently not marked as VR capable on Steam so the Steam client will show warning when launching the game.
- Only some parts of the menu have 3d background
- The head orientation and position is not supported by some cameras (e.g. top down, debug)
- There might be distortions when using some menu screens in 3d mode or when switching the 3d mode of the menu in some situations.
- The game does not reset the orientation/position when entering truck so you will have to do that manually by pressing F12 if necessary.
- The default reset key F12 coincides with the default Steam screenshot key.
Oculus
To enable the support, run the game with -oculus command line parameter. You also need to enable launching applications from Unknown Sources in the Oculus application.
OpenVR
To enable the support, run the game with -openvr command line parameter. When using the game with SteamVR, you also should uncheck the "Use Desktop Game Theatre while SteamVR is active" in game properties in Steam client.
OpenXR
To enable the support, run the game with -openxr command line parameter.
Common
You might want to configure the graphics settings to use Scale of 100% and disable Depth of Field which introduces extra blur.
Supersampling
If you have sufficiently powerful GPU, you might want to use supersampling to improve the quality of the image. Generally there are three places where you can affect the rendering size: HMD vendor tool, r_manual_stereo_buffer_scale cvar in game and scaling settings set in game UI (corresponds to r_scale_x/r_scale_y cvars). Generally both HMD vendor setting and r_manual_stereo_buffer_scale will behave in a similar wait and you can use one or the other with similar result. The in-game scaling setting does not apply to the UI and might result in more blurry image because it uses just bilinear filter so you might want to keep it set to 100% and change the size using the HMD vendor tool or r_manual_stereo_buffer_scale instead.
Technically it works in the following way: The vendor setting changes size of the recommended rendering resolution which is reported to the game by the VR API. The game then multiplies this reported value by r_manual_stereo_buffer_scale and uses the resulting size to allocate eye buffer. When rendering the driving 3d scene, the game multiplies the eye buffer size by scaling setting and renders the scene using the resulting size. When the rendering is done, it is resized using a bilinear filter back to the size of the eye buffer. The UI is then drawn into the eye buffer. Finally entire buffer is provided to the VR API which applies whatever distortions and postprocessing (e.g. ASW) are required.
Since 1.50 the scale of texture used to render the UI is controlled using separate r_manual_stereo_ui_buffer_scale cvar (previously it was two times the render buffer scale). Additionally the texture is using mipmaps to reduce aliasing artifacts. Depending on the resolution of your HMD and the buffer size this might lead to excessive blurriness. This can be worked around by either disabling mipmaps entirely using r_manual_stereo_ui_mipmaps to match the 1.49 behavior or by adjusting the mipmap selection using r_manual_stereo_ui_lod_bias where values lower than zero increase sharpness.
Additional configuration
The game will by default show a undistorted image of both views on the screen. If you want to remove any related overhead, you can disable it by setting r_manual_stereo_mirror_mode to 0. Alternatively you can zoom to the center of the eye area by setting this cvar to 2 or show just content of the left eye preserving the eye texture aspect ratio by setting it to 3 (since 1.51)
It is possible to reset the HMD position using the F12 key. This conflicts with default Steam screenshot key so you might want change the setting in game keyboard setup UI or use the in-game screenshot key which since 1.6 also creates corresponding Steam screenshot.
The game can show the menu in 2D or 3D positioned mode. This is toggled by the r_manual_stereo_in_menu cvar or by F11 key. Note that since 1.54 this cvar is not saved in the config file and the game will always start with 3D mode enabled as too many people did toggle this by accident.
It is possible to configure the 3D parameters of the plane on which the UI is shown using the r_manual_stereo_ui_fov* and r_manual_stereo_ui_dist* cvars. There are two sets of the parameters. One is used in menu to provide view of all corners of the menu ui while the other is used when driving in game to provide better view of the advisor. Additionally it is possible to modify position and rotation of the UI plane using r_manual_stereo_ui_x*, r_manual_stereo_ui_y*, r_manual_stereo_ui_yaw* and r_manual_stereo_ui_pitch*. This allows you to put the menu or advisor to another place in the 3D scene. In case of the in-game configuration the game will automatically negate the x and yaw values when sitting in truck with a steering wheel on the right side. Please note that the position and rotation currently affects entire UI plane which means that it will affect the position of some dialog shown here (e.g. delivery difficulty selection) and the UI mirrors if you have them enabled for some reason. The static loading screen where the movement ability is limited is always rendered using a smaller resolution defined by r_manual_stereo_ui_static_fov without any positioning support to avoid clipping.
It is possible to change the UI quad from purely planar quad to one mapped on a cylinder using r_manual_stereo_ui_radius* cvars. If the value is set to zero the plannar quad is used. Otherwise the value represent a radius of cylinder to which is the quad mapped so smaller value means more curved "quad".
As the ui mirrors are not visible in the field of view in the default ui fov settings, it is good idea to disable them to improve performance.
The interior camera is using a limited variant of angle-dependent movement of the head from the normal game. It only keeps the window lookout and moves its start to about 85 degrees. The movement can be disabled entirely by setting g_hmd_no_artifical_movement profile cvar to 1 before starting the game.
The game reduces shaking of the cabin when HDM mode is active. This reduction can be disabled by setting g_hmd_reduced_cabin_movement profile cvar to 0.
The game before 1.50 uses a HMD-specific appearance of the desktop menu. Currently this is only used to change layout of the full-featured (with all widgets unlocked) desktop menu. Future builds are likely to tweak the menu more and improve layout of additional parts of the menu. This feature can be disabled by setting g_hmd_no_special_menu profile cvar to 1 before starting the game.
The background truck under the menu is drawn in 3D. This might be disabled by setting g_hmd_no_3d_background profile cvar to 1 before starting the game.
The game by default uses IPD value retrieved from your HMD. You can scale the value by setting r_ipd_scale to value other than 1.
Starting from 1.45, the game will select the size of the texture used to draw water reflections in VR mode based on FOV of the HMD by multiplying the (HMD FOV + g_additional_water_fov) by r_hmd_water_pixels_per_deg.
Starting from 1.46 it is possible to let the game show position of the VR controllers in the driving mode. Please note that this is just a visualization, you can not use the controllers to interact with the game in any way. You can use them for example to mark position where your physical steering wheel is. This is enabled by r_hmd_draw_controllers. Setting it to 1 will show controller model if supported by the VR API (OpenVR only) and small cross at the reported position otherwise. Setting it to 2 will always show the small cross. When model is shown, it does not cast shadows by default. That can be changed using r_hmd_controller_shadows.
By default the game will use frame timing information from the HMD to advance its internal time. If necessary, this can be disabled using t_ignore_hmd_timing. You might try to change this setting if experiencing stutter.
Debug configuration UI
Since 1.54 the in-game debug menu can enable two screens in the Rendering\VR menu. To access this menu you need to have the debug console enabled (g_console). First screen is OpenXR specific and shows more detailed frame timing information allowing to change some timing related options. The other is common to all VR APIs and allows changing some VR related options such as buffer scale and can more quickly (depends on your OpenXR runtime) apply changes which require reinit of graphics resources. Note that it includes only subset of settings described above. It does not include settings which can not be changed without restarting the game and also currently does not support changing API specific settings (e.g. the FOV override). Please note that each unique value of UI Load Bias you try during a single run of the game consumes limited resources so too many changes might cause crash of the game.
Oculus API only
Since 1.54 the game will always complete the rendering and frame buffer submit on a second thread. In previous versions this could be disabled using o_oculus_threaded_submit at the cost of decreased performance. Changing this cvar requires restart of the game.
OpenVR only
It is possible to force use of interleaved reprojection using o_openvr_interleaved_reproject. Changing this cvar requires restart of the game.
Before 1.54 it was possible to control if the game calls the PostPresentHandoff API using o_openvr_post_present_handoff. Since 1.54 that function is currently never called.
OpenXR only
The game now uses asymmetrical FOVs by default. If the VR system is supporting FOV change, it is still possible to force use of symmetrical one using o_openxr_force_symmetrical_fov however that is only meant for backward compatibility. The asymmetrical FOV is more efficient. Since 1.54 this cvar can be changed on the fly, older versions require restart of the game. Since 1.54 the game provides additional cvars which allow you to override the FOV assuming that the OpenxR runtime used is supporting FOV change (Virtual Desktop does, Oculus native runtime does not). There are two groups of cvars to control that. First group is o_openxr_max_hor_fov_override and o_openxr_max_vert_fov_override cvars. If set to value bigger than zero, they will reduce the maximal value of FOV in the specified direction to minimum from that value and the value reported by the HMD. Unlike the remaining overrides those cvars can reduce amount of geometry the game will attempt to send to the GPU however you will be likely unable to reduce the angle by more than a few degrees without it becoming noticeable. Changing those cvars requires restart of the game. The second group are o_openxr_left_left_override, o_openxr_left_right_override, o_openxr_left_top_override, o_openxr_left_bottom_override and similar cvars for the right eye. If cvar value is bigger than zero, it overrides specified component of the FOV up to the symmetrical maximum (based on what is reported by HMD and cvars from the previous group). This can be used to ignore parts of the FOV which you can not physically because of shape of your head thus improving the utilization of the render target allowing to either use a smaller buffer size to reduce GPU load or provide a better image for the same size. This second group can be changed on the fly. The general approach is to first fine tune the FOV using the second group of the cvars, ideally using the developer console for quick iteration, and then set the cvars from the first group to correspond to the maximal angle from the result.
Since 1.54 the game will always complete the rendering and frame buffer submit on a second thread. In previous versions this could be disabled using o_openxr_threaded_submit at the cost of decreased performance. Changing this cvar requires restart of the game.
By default the game acquires swapbuffer images after call to xrBeginFrame like shown in the OpenXR documentation for maximal compatibility. It is possible to increase amount of time by which rendering can overlap into the next frame by allowing the game to acquire images earlier by setting o_openxr_acquire_after_begin to 0. This setting is incompatible with OpenXR toolkit and might be incompatible by some other runtime or layers. Can be changed on the fly.
The game uses statically linked openxr loader by default. If for some reason you want to use externally provided one, you can use o_openxr_external_loader to enable that. In that case you need to provide a compatible openxr_loader.dll dll somewhere in the default loading chain. Changing this cvar requires restart of the game.
By default the game calls xrWaitFrame on the main thread at the start of the frame. As a experiment it is possible to use o_openxr_async_wait to start the next wait on separate thread right after the game calls xrBeginFrame. Might have no effect or might mess things up. Can be changed on the fly.
By default the game uses the predicted time for its timing calculation. For testing purposes it is possible to use o_openxr_one_period_ahead to use time extrapolated by one refresh period ahead. In my tests it did not have any noticeable effect.
As an experiment with a eye tracking, the 1.55 VR build has a poor man's (very poor) foveated rendering. As we currently do not support VRS nor SPS and normal rendering of multiple views would be counterproductive this feature just additionally reduces the FOV to specific rectangular area around the gaze direction so you will see black borders following your eyes instead of some less noticeable transition like with proper foveated rendering. The area is defined using o_openxr_eye_cull_hor_fov and o_openxr_eye_cull_vert_fov whose values represents angle in degrees between center of the gaze and the respective new border (i.e. half of the maximal effective FOV in respective axis). Value less than 0.5 will disable the effect for that axis. For this entire feature to work, the all the following must be true:
- It must be the VR build from oculus beta.
- Game must be started with an additional -xr_eye launch option.
- The runtime must provide the XR_EXT_eye_gaze_interaction extension and must report that eye gaze interaction is available
- The runtime must support FOV changes.