UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

graphics

[VulkanVR] Quest Backbuffer Read Fails: RenderGraph Fix

Solution

shader graphbuild optimizationvirtual realityvulkanmeta-questopenxr

Unity 2022.3.x - Unity 6.3.x

Published Mon, Mar 9

Issue

 Reading the color backbuffer on a VR HMD with Vulkan using RenderGraph.ImportTexture or RenderGraph.ImportBackbuffer can result in NullReferenceException during Blitter.BlitTexture or an invalid texture handle. This occurs when directly accessing the camera color texture on Meta Quest hardware, particularly when requiresIntermediateTexture is not enabled.

Quick-Fix

The foveated rendering OpenXR feature can interfere with framebuffer fetching on Meta Quest 3 with Vulkan. Disabling this feature or using a copy pass approach resolves rendering issues.

Expand Analysis

Disable the foveated rendering OpenXR 1.16 feature in project settings to address backbuffer read issues on Meta Quest 3 using Vulkan. This is especially critical in Unity 6 where it causes HMD black screens and rendering disruption during framebuffer fetch operations.

  1. Open Project Settings > XR Plug-in Management > OpenXR.
  2. Deselect the foveated rendering feature in the features list.
  3. Alternatively, integrate a dedicated copy pass into the RenderGraph for optimized backbuffer access.

Additional Tips

  • Use RenderGraph.AddCopyPass to copy the source render target to a temporary destination.
  • Use a RasterRenderPass to blit the content to your pass data to ensure compatibility.
  • Verify that requiresIntermediateTexture is not explicitly disabled if your script requires it.

Copy


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;

public class BackbufferPassManager
{
    private class PassData
    {
        public TextureHandle _Source;
        public TextureHandle _Destination;
    }

    public void AddPass(RenderGraph renderGraph, TextureHandle source, TextureHandle destA, TextureHandle destB, Vector4 scaleBias)
    {
        renderGraph.AddCopyPass(source, destA, "CopyFrameBufferPass");

        using (var builder = renderGraph.AddRasterRenderPass<PassData>("CopyFrameBufferPass2", out var passData))
        {
            passData._Source = destA;
            passData._Destination = destB;

            builder.UseTexture(passData._Source, AccessFlags.Read);
            builder.SetRenderAttachment(passData._Destination, 0, AccessFlags.WriteAll);
            builder.AllowPassCulling(false);

            builder.SetRenderFunc((PassData currentPassData, RasterGraphContext context) =>
            {
                Blitter.BlitTexture(context.cmd, currentPassData._Source, scaleBias, 0, true);
            });
        }
    }
}

Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.