This guide is for anyone who is looking to get into developing for Virtual Reality projects in Unreal Engine 4. Covering Blueprint, C++, performance considerations and how to set up your VR kits for UE4.

I highly recommend using the latest release of Unreal Engine 4 as VR is still being improved greatly with each new release.

A few good places to reference are the official Oculus forums, the official VR documentation pages and the Unreal Engine VR Subforums.

Unreal Engine 4.13 has a new built-in VR Template made in Blueprint. For more information check out my VR Template Guide!

Setup your VR Device

For this guide I will assume you have successfully installed your head-mounted display of choice (Visit Oculus Rift Setup or HTC Vive Pre Setup in case you did not). In case you are having difficulties getting your Vive to work, I found this Troubleshooting guide to be helpful.

Unreal Engine 4 supports all the major devices and you don’t need to perform any hassle to setup your game project for VR. Just make sure that the correct plugins are loaded for your HMD under Edit > Plugins. There are some performance considerations to take into account, we’re covering these later in the guide.

Before you launch the editor make sure your VR software is running, in the case of the HTC Vive this is the SteamVR app.

Launching VR Preview

Testing out your VR set is very straightforward, simply select “VR Preview” from the Play drop-down button. By default the head tracking will work right away without any changes to your existing project or template. I will go into more detail on how to add additional features such as motion controller setup and origin resetting etc. later on in this guide.

VR Best Practices

VR is still a relatively unexplored area, and we are learning new things with every day of development. Both Oculus and Epic Games have set up a Best Practices Guide that I recommend you read through and keep in the back of your head while developing games for VR.

Using VR in Blueprint

Using VR in Blueprint is very straightforward and you don’t need a lot of set up to get yourself going.

You will need a Camera Component and optionally one or two Motion Controllers Components. By default your Camera is already set up for HMD support, if you wish to disable rotation changes from the HMD you can disable “Lock to HMD” in the Component’s properties. For more information on the Motion Controllers you can jump down in this guide or immediately jump to the official documentation page on how to Setup Motion Controllers.

Here is a (non-exhaustive list) of the available nodes in Blueprint:

To reset your HMD position and/or orientation (With optional Yaw offset):

To selectively enable features when using VR you can easily check whether your HMD is enabled:

SteamVR Chaperone

The Chaperone component is specific to SteamVR and has easy access to the soft bounds. The soft bounds are represented as an array of Vectors centered around the calibrated HMD’s Origin (0,0,0). The Z component of the Vectors is always zero. You can add this component like any other ActorComponent to your Blueprint as seen below.

USteamVRChaperoneComponent

To use the chaperone in C++ open up your ProjectName.Build.cs and add the “SteamVR” module to the PrivateDependencyModuleNames array. See below for a sample.

using UnrealBuildTool; public class VRFirstPerson : ModuleRules { public VRFirstPerson(TargetInfo Target) { PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); /* VR Required Modules */ PrivateDependencyModuleNames.AddRange(new string[] { "HeadMountedDisplay" , "SteamVR" }); } }

Setup Motion Controllers

The official documentation has a good introduction on Motion Controller setup and input handling, so if your VR Device supports motion controllers I recommend following along with the documentation. For a practical example check out my VR Templates on GitHub.

If you’re having trouble aligning your Motion Controllers with the Camera, simply use a SceneComponent as “VROrigin”, this is especially helpful when the root component has an undesirable pivot like the CapsuleComponent in a Character Blueprint.

Using VR in C++

As of 4.11 not all functionality is exposed to Blueprint, if you are looking to do more advanced custom setups you might need to dig into C++ to adjust a few settings. Check out the IHeadMountedDisplay.h for a look at the available functions. Certain plugins add additional features like SteamVRChaperoneComponent but are specific to a single device.

Required Modules & Includes

If you wish to access the HMD features through C++ you need to include the “HeadMountedDisplay” Module in your ProjectName.Build.cs file you can find in your Visual Studio solution explorer. Here is an example of the build file from the VRFirstPerson project.

using UnrealBuildTool; public class VRFirstPerson : ModuleRules { public VRFirstPerson(TargetInfo Target) { PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); /* VR Module */ PrivateDependencyModuleNames.AddRange(new string[] { "HeadMountedDisplay" }); // ... } }

To use HMD features or the motion controller component, make sure you include the following header files.

/* VR Includes */ #include "HeadMountedDisplay.h" #include "MotionControllerComponent.h"

Performance Considerations

For the whole VR experience to look smooth, your game needs to run on 75 hz (Oculus DK2) or even 90 hz. (HTC Vive and Oculus CV1) depending on your device. To see your current framerate type in “stat fps” or “stat unit” (for more detailed breakdown) in your console when running the game.

CPU Profiling

Your game might be CPU or GPU bound, to find out you need to measure (a quick way is to use “stat unit”). With the complexity of current gen games and engines it’s near impossible to make good guesses on what’s bottlenecking your performance so use the tools at your disposal! Bob Tellez wrote a blog post on CPU Profiling with Unreal Engine 4 and it’s a good place to get started.

GPU Profiling

To capture a single frame with GPU timings press Ctrl+Shift+, or type in “profilegpu” in the console. This command dumps accurate timings of the GPU, you will find that certain processes are a heavy burden on the framerate (Ambient Occlusion is one common example) when using VR.

The GPU Profiling & Performance and Profiling docs are a good place to learn about profiling your game.

While profiling you might stumble on other costly features depending on your scene and project. One example is the Translucent Lighting Volume you may not need but even when unused it adds a static cost to your scene, check out this AnswerHub post by Daniel Wright for more info on how to disable this feature. All that is left for you to do is measure and test, there is no single configuration that is perfect for all projects.

The developers from FATED came up with a great list of tips in their quest for optimized VR. A few examples they mention are to disable HZB Occlusion Culling (r.HZBOcclusion 0), Motion Blur (r.DefaultFeature.MotionBlur=False) and Lens Flares (r.DefaultFeature.LensFlare=False). The commands do not persist through multiple sessions, so you should add (or search and replace) them in your /Config/DefaultEngine.ini config file although most of these settings are available through Edit > Project Settings… > Rendering.

Another great optimization to consider is the Instanced Stereo Rendering, we’ll talk about that next.

Instanced Stereo Rendering

The latest 4.11 release introduces Instanced Stereo Rendering, check the video below for a comparison video of how that works.

“Basically, we’re utilizing hardware instancing to draw both eyes simultaneously with a single draw call and pass through the render loop. This cuts down render thread CPU time significantly and also improves GPU performance. Bullet Train was seeing ~15 – 20% CPU improvement on the render thread and ~7 – 10% improvement on the GPU.” – Ryan Vance.

To enable this feature in 4.11 and above, go to your Project Settings and look for “Instanced Stereo” under the Rendering category.

Disable Heavy Post-Processors

Certain post-processing effects are very costly in VR like Ambient Occlusion. Others may even become an annoyance in VR like Lens Flares as they may break your immersion of being present in the scene and instead looking through a camera. These are easy examples to get started and see how it affects your game and performance.

To disable post processing features on a project level, go to Edit > Project Settings > Rendering. You can do the same thing in post-processing volumes. Keep in mind that post-processing volumes can override the project-wide settings specified below.

Reduce Scene Complexity

With current gen hardware it’s really difficult to stay on your 90 fps target. You may need to revisit your previous traditional constraints and look at your scene complexity like dynamic shadows, atmospheric smoke effects and polycount of meshes.

It’s important to minimize overdraw to keep performance at a maximum. Lots of translucent surfaces and/or particle effects can easily cause your framerate to tank. To visualize the current shader complexity / overdraw press Alt+8 in your viewport (Alt+4 to return to default view). Look at the bottom picture from the Elemental Demo to get an idea of how much the atmospheric effects can impact your framerate (green = good, red = bad, white hot = extremely bad at about 2000 shader instructions per pixel)

Dynamic shadows and lights have a huge impact on performance too. Bake as much lighting as you can to keep the per-frame cost as low as possible.

List of Rendering Commands

The excellent talk by Nick Whiting and Nick Donaldson contains a list of render commands to use for GPU optimization in VR. You can find the list below. I recommend watching their talk regardless as it contains great info on the basics of Virtual Reality in general.

To test out these commands hit ~ (Tilde) to open the command console. Once you settled on a command to be included for your project, you can add them to your configuration in /Config/DefaultEngine.ini under [/Script/Engine.RendererSettings]. Tip: Check if the command exists in the list before adding it yourself.

r.SeparateTranslucency=0

r.HZBOcclusion=0

r.FinishCurrentFrame=1

r.MotionBlurQuality=0

r.PostProcessAAQuality=3

r.BloomQuality=1

r.EyeAdaptionQuality=0

r.AmbientOcclusionLevels=0

r.DepthOfFieldQuality=0

r.SceneColorFormat=2

r.TranslucentLightingVolume 0

r.TranslucencyVolumeBlur=0

r.TranslucencyLightingVolumeDim=4

r.MaxAnisotropy=8

r.LensFlareQuality=0

r.SceneColorFringeQuality=0

r.FastBlurThreshold=0

r.SSR.MaxRoughness=0

r.SSR.Quality=0

r.rhicmdbypass=0

r.TiledReflectionEnvironmentMinimumCount=10

Troubleshooting

Vive Specific (Non-PRE editions): Once you launched the editor, SteamVR may state “Not Ready” this means something may be overlapping and preventing the Compositor screen to run at more than 60 FPS causing jittering and motion sickness. More information and workaround for this issue can be found on this AnswerHub Thread! The next iteration of Vive devices (Vive PRE) no longer have this issue as they moved to direct mode for the displays, for this make sure you updated your graphics drivers to support direct mode.

References

Hopefully this guide has helped you get started with Virtual Reality project!

If you have a question or feel that I missed something important, let me know by leaving a reply below! To stay in touch, follow me on Twitter!