This website uses cookies to improve our services and deliver relevant ads.
By interacting with this site, you agree to this use. For more information, see our Cookies Policy

Advanced Rendering Features

This guide describes advanced rendering features that can assist performance.

VR Compositor Layers

OVROverlay is a script in OVR/Scripts that allows you to render Game Objects as VR Compositor Layers instead of drawing them to the eye buffer.

OVROverlay

Game Objects rendered as VR compositor layers render at the frame rate of the compositor instead of rendering at the application frame rate. They are less prone to judder, and they are raytraced through the lenses, improving the clarity of textures displayed on them. This is useful for displaying easily-readable text.

Quadrilateral and cubemap compositor layers are currently supported by Rift and mobile. Cylinder and offset cubemap compositor layers are currently available in mobile only.

Overlay sample: A sample illustrating the use of quad and cylinder VR Compositor Layers for a UI is included with the rendering samples of our Unity Sample Framework. See Unity Sample Framework for more information.

All layer types support both stereoscopic and monoscopic rendering, though stereoscopic rendering only makes sense for cubemaps in most cases. Stereoscopically-rendered overlays require two textures, specified by setting Size to 2 in the Textures field of OVROverlay in the Inspector.

Gaze cursors and UIs are good candidates for rendering as quadrilateral compositor layers. Cylinders may be useful for smooth-curve UI interfaces. Cubemaps may be used for startup scenes or skyboxes.

We recommend using a cubemap compositor layer for your loading scene, so it will always display at a steady minimum frame rate, even if the application performs no updates whatsoever.

Applications may add three compositor layers to a scene. You may use no more than one cylinder and one cubemap compositor layer per scene.

Note that if a compositor layer fails to render (e.g., you attempt to render more than three compositor layers), only quads will currently fall back and be rendered as scene geometry. Cubemaps and cylinders will not display at all, but similar results can be achieved with scene geometry such as Unity’s Skybox component or Cylinder MeshFilter.

You may use OVRRTOverlayConnector to render textures to a compositor layer. See OVRRTOverlayConnector below for more information.

Ordering and Transparency

The depth ordering of compositor layers is controlled by two factors:

  1. Whether objects are rendered in front of or behind the scene geometry rendered to the eye buffer, and
  2. The sequence in which the compositor layers are enabled in the scene.

By default, VR compositor layers are displayed as overlays in front of the eye buffer. To place them behind the eye buffer, set Current Overlay Type to Underlay in the Inspector. Note that underlay compositor layers are more bandwidth-intensive, as the compositor must “punch a hole” in the eye buffer with an alpha mask so that underlays are visible. Texture bandwidth is often a VR bottleneck, so use them with caution and be sure to assess their impact on your application.

Underlays depend on the alpha channel of the render target. If a scene object that should occlude an underlay is opaque, set its alpha to 1. If the occluder is transparent, you must use the OVRUnderlayTransparentOccluder shader provided in the Utilities in Assets/OVR/Shaders. Overlays do not require any special handling for transparency.

Compositor layers are depth ordered by the sequence in which they are enabled in the scene, but the order is reversed for overlays and underlays. Underlays should be enabled in the scene in the sequence in which you want them to appear, enabling the underlays in front first and the layers in the back last. Overlays should be enabled in the opposite order.

Basic usage

  1. Attach OVROverlay.cs to a Game Object.
  2. Specify the Current Overlay Shape:
    • Quad (Rift and Mobile)
    • Cubemap (Rift and Mobile)
    • Cylinder (Mobile only)
  3. Specify the OVROverlay Texture. If you leave it as None (default), it will use the Renderer material’s main texture, if available. See OVRRTOverlayConnector below for more information on rendering textures to an OVROverlay Game Object.
  4. Disable all compositor layers (both overlays and underlays),
  5. Enable them sequentially to set the order in which you wish them to appear, enabling overlays in front last and underlays in front first.

Example

In this example, most of the scene geometry is rendered to the eye buffer. The application adds a gaze cursor as a quadrilateral monoscopic overlay and a skybox as a monoscopic cubemap underlay behind the scene.

Note the dotted sections of the eye buffer, indicating where OVROverlay has “punched a hole” to make the skybox visible behind scene geometry.

In this scene, the quad would be set to Current Overlay Type: Overlay and the cubemap would be set to Current Overlay Type: Underlay. Both would be disabled, then the quad overlay enabled, then the skybox enabled.

Note that if the cubemap in our scene were transparent, we would need to use the OVRUnderlayTransparentOccluder, which is required for any underlay with alpha less than 1. If it were stereoscopic, we would need to specify two textures and set Size to 2.

Cylinder and Offset Cubemap Overlays (Mobile Only)

The center of a cylinder overlay Game Objects is used as the cylinder’s center. The dimensions of the cylinder are encoded in transform.scale as follows:

  • [scale.z] cylinder radius
  • [scale.y] cylinder height
  • [scale.x] length of the cylinder arc

To use a cylinder overlay, your camera must be placed inside the inscribed sphere of the cylinder. The overlay will fade out automatically when the camera approaches to the inscribed sphere's surface.

Only half of the cylinder may be displayed, so the arc angle must be smaller than 180 degrees.

Offset cubemap compositor layers are useful for increasing resolution for areas of interest/visible areas by offsetting the cubemap sampling coordinate.

They are similar to the same as standard cubemap compositor layers. Attach the OVROverlay script to an Empty Game Object, and specify the texture coordinate offset in the Position Transform. For more information, see OVROverlay in our Unity Scripting Reference.

OVRRTOverlayConnector

OVRRTOverlayConnector is a helper class in OVR/Scripts/Util used to link a Render Texture to an OVROverlay Game Object. Attach this script to your camera object, and specify your overlay owner object in Ovr Overlay Obj.

The overlay camera must use Render Texture, and must be rendered before the Main Camera (e.g., using camera depth), so the Render Texture will be available before being used.

OVRRTOverlayConnector triple-buffers the render results before sending them to the overlay, which is a requirement for time warping a render target. It also clears the render Texture's border to alpha = 0 to avoid artifacts on mobile.

For more information, see "OVRRTOverlayConnector" in our Unity Scripting Reference.

Single Pass Stereo Rendering (Preview, Mobile Only)

Single Pass stereo rendering is a preview rendering feature for Gear VR. If your application is CPU-bound or draw call bound, we strongly recommend using Single Pass rendering to improve performance.

Single Pass stereo rendering is a preview rendering feature for Gear VR. If your application is CPU-bound or draw call bound, we strongly recommend using Single Pass rendering to improve performance.

In typical OpenGL stereo rendering, each eye buffer must be rendered in sequence, doubling application and driver overhead. When Single Pass is enabled, objects are rendered once to the left eye buffer, then duplicated to the right buffer automatically with appropriate modifications for vertex position and view-dependent variables such as reflection.

While Single Pass rendering primarily reduces CPU usage, GPU usage may be affected. On Exynos devices, Single Pass rendering slightly reduces the GPU load as well as the CPU load. Unfortunately, on Qualcomm devices, Single Pass currently causes a slight increase in GPU load of a few percent. Qualcomm is looking into optimizing this to reduce the increase in GPU load.

For additional technical information, you may wish to review Multi-View in our Mobile SDK documentation, which discusses the underlying framework that makes Single Pass rendering possible in our Unity integration.

Requirements

Single Pass rendering is currently supported by Note5, S6, S7, S7 Edge, S8 and S8+ phones using ARM Exynos processors and running Android M or N. It is also supported on S7 and S7 Edge phones using Qualcomm processors and running Android N.

Single Pass rendering requires OpenGL ES 3.

Although it can substantially reduce CPU overhead, keep in mind that applications submitted to the Oculus Store must maintain minimum frame rate per our requirements, even on devices that do not support multi-view.

Enabling Single Pass Rendering

  1. Open Player Settings and go to Rift.
  2. Set Stereo Rendering Method to Single Pass (Preview).

Single Pass Known Issues

Graphics Driver Issues

Two known graphics driver issues affect mobile applications using Single Pass in certain Unity/phone combinations:

  • Affected phones: SM-G955F (S8+) / SM-G950F (S8)
  • Affected Unity versions: 5.6.0p2 / 5.6.0p3

A fix is being deployed, but it will take some time for users to get it from OTA.

Issues

1. When “Standard Shader Quality” is low in your graphics config, the standard shader may appear black.

2. If you create tree objects, using the default “Optimized Bark Material” may cause the tree to disappear.

Both issues requires shader overwriting to workaround. The process is similar.

Workaround for the Standard Shader Issue

Note: Before proceeding, we recommend backing up your project.
  1. Download the build-in shader package from Unity website for 5.6.0p2, available here.
  2. Copy the following files from the shader package to your project folder:
    1. All files under Assets\Shaders\CGIncludes. Not every file is necessary, but we recommend simply copying all of them, as the dependencies can be complicated.
    2. \DefaultResourcesExtra\Standard.shader
  3. In your project, modify the file UnityStandardCoreForwardSimple.cginc in Assets\Shaders\CGIncludes\ by adding the following code to the end of FragmentSetupSimple() before return s;
    #if defined(UNITY_STEREO_MULTIVIEW_ENABLED)  
      s.smoothness = saturate(s.smoothness);
    #endif
  4. Navigate to Assets\Shaders\CGIncludes\ and rename Standard.shader to StandardS8.shader.
  5. Open StandardS8.shader and change the first line from
    Shader "Standard"
    to
    Shader "StandardS8"
    .
  6. After you finished modifying the shaders, you need apply them. Change the shader for any affected material from Standard to StandardS8.

If you have a lot of affected materials, it may be easier to use an editor script to apply these changes, such as this:

[MenuItem("Tools/Oculus/ApplyS8Workaround")]
static void ApplyS8Workaround()
{
    Renderer[] _renderers = Component.FindObjectsOfType<Renderer>();
    foreach (Renderer _renderer in _renderers)
    {
        Material[] _materials = _renderer.sharedMaterials;
        foreach (Material _material in _materials)
        {
            if (_material.shader.name.Equals("Standard"))
            {
                _material.shader = Shader.Find("StandardS8");
            }
        }
    }
    
}

Workaround for the Optimized Bark Material Issue

Note: Before proceeding, we recommend backing up your project.
  1. Download the build-in shader package from Unity website for 5.6.0p2, available here.
  2. Copy the following files from the shader package to your project folder
    1. \DefaultResourcesExtra\Standard.shader
    2. \DefaultResourcesExtra\Nature\TreeCreator\TreeCreatorBarkOptimized.shader
  3. In your project, modify the file TerrainEngine.cginc in Assets\Shaders\CGIncludes\ by adding the following code right after the line float2 vWavesIn = _Time.yy + float2(fVtxPhase, fBranchPhase ):
    #if defined(UNITY_STEREO_MULTIVIEW_ENABLED)
      vWavesIn.x += saturate(fVtxPhase) * 0.00000001f;
    #endif
  4. Navigate to Assets\Shaders\CGIncludes\ and rename TreeCreatorBarkOptimized.shader to TreeCreatorBarkOptimizedS8.shader.
  5. Open TreeCreatorBarkOptimizedS8.shader and change the first line from
    Shader "Hidden/Nature/Tree Creator Bark Optimized"
    to
    Shader "Hidden/Nature/Tree Creator Bark Optimized S8"
  6. After you finished modifying the shaders, you will need apply them. Change the shader for any affected material from Tree Creator Bark Optimized to Tree Creator Bark Optimized S8.

If you have a lot of affected materials, you may wish to write an Editor script to do this conversion similar to the example given in the standard shader issue workaround above.

Compiling Issues

When Single Pass is enabled in Unity 5.6.0p2, building mobile projects will fail if either of the two cases are true:

  1. You are using Standard Shader and have enabled both specular highlights and normal mapping; or
  2. You are using the old mobile bumped diffuse detail shader.

You will see a shader error referring to bumped detail that says “Duplicated input semantics can't change type, size, or layout ('TEXCOORD7').”

Workaround

The actual details will differ depending on which shader you have problems with - these instructions use Mobile-Bumped.shader as an example.

Note: Before proceeding, we recommend backing up your project.
  1. Download the build-in shader package from Unity website for 5.6.0p2, available here.
  2. Copy any shaders reported by the compiler error the following files from the shader package to your project folder, such as Mobile-Bumped.shader (for example).
  3. In the file \Assets\Shaders\CGIncludes\UnityInstancing.cginc, replace
    #define UNITY_VERTEX_OUTPUT_STEREO float stereoTargetEyeIndex : TEXCOORD7;
    with:
    #define UNITY_VERTEX_OUTPUT_STEREO float stereoTargetEyeIndex : TEXCOORD10;
  4. Navigate to Assets\Shaders\CGIncludes\ and rename Mobile-Bumped.shader to Mobile-BumpedS8.shader.
  5. Open Mobile-BumpedS8.shader and change the first line from
    Shader "Mobile-Bumped" 
    to
    Shader "Mobile-BumpedS8"
  6. After you finished modifying the shaders, you need apply them. Change the shader for any affected material from Mobile-Bumped to Mobile-BumpedS8.

If you have a lot of affected materials, you may wish to write an Editor script to do this conversion similar to the example given in the standard shader issue workaround above.