# 5. Quest 2 Performance and Rendering
Part of [[Meta Quest 2]]. Requires Unity 6.3 LTS (6000.3.27f2) and newer. Previous: [[4.Quest 2 Testing and Deployment]]. Next: [[6.Quest 2 Input Hands and Passthrough]].
> [!important] Version requirement
> Unity 6.3 LTS (6000.3.27f2) and newer.
Quest 2 is a mobile (Snapdragon XR2 Gen 1) headset. You are tile-based and fill-rate bound. A VR app that misses its refresh rate causes discomfort and fails Store review (VRC.Quest.Performance.1).
## 5.1 Budgets
| Budget | Value | Source |
|---|---|---|
| Refresh rate (Store minimum) | **72 Hz** = 13.9 ms per frame | [VRC list](https://developers.meta.com/horizon/resources/publish-quest-req/) |
| Optional higher rates | 90 / 120 Hz; query/set with `OVRPlugin.systemDisplayFrequency` (Meta SDK) or the Unity display subsystem | [Meta: display refresh rate](https://developers.meta.com/horizon/documentation/unity/unity-set-disp-freq/) |
| Draw calls | Meta's Unity guidance for Quest 2: ~80-200 for a busy scene, 200-300 medium, 400-600 light | [Meta perf guidance](https://developers.meta.com/horizon/documentation/unity/unity-perf/) |
| Draw calls (conservative) | Meta's device comparison recommends fewer than 100 draw calls | [Meta device optimization comparison](https://developers.meta.com/horizon/documentation/unity/device-optimization-comparison/) |
| Triangles | 750K - 1M visible per frame (same pages recommend under 750K) | same |
| Eye buffer | Panel is 1832x1920 per eye; render scale 1.0 = 1440x1584; ~1.24 matches the panel | Meta [render scale](https://developers.meta.com/horizon/documentation/unity/os-render-scale/) |
| Render scale floor | 0.85 recommended (VRC.Quest.Performance.4) | VRC list |
> [!tip] Design to the lower bound
> Pick the conservative numbers (under 100 draw calls, under 750K triangles) for a Quest 2 scene with real-time lights, and relax them only after you measure on the device.
## 5.2 Rendering settings that matter
- **URP, Vulkan, Render Graph**, Instancing stereo path (the build profile default).
- **MSAA 4x** (tile memory makes it cheap), no post-processing, no HDR.
- **SRP Batcher** friendly shaders only: use URP Lit/Unlit or Shader Graph. Do not call `Shader.Find` at runtime (shaders get stripped; see [[9.Quest 2 Pitfalls]]).
- **Baked lighting** wherever possible; one real-time light at most.
- **ASTC** textures ([[3.Quest 2 Project and Build Setup]]).
- Avoid `Camera` stacking, grab pass, and full-screen effects.
## 5.3 Application SpaceWarp (ASW)
ASW lets you render at half the rate (for example 36 fps) while the runtime synthesizes in-between frames from motion vectors and depth.
Requirements for Unity's implementation ([URP Spacewarp](https://docs.unity3d.com/6000.2/Documentation/Manual/xr-graphics-spacewarp.html), [OpenXR Spacewarp feature](https://docs.unity3d.com/Packages/
[email protected]/manual/features/spacewarp.html)):
| Requirement | Value |
|---|---|
| Unity | 6.1+ |
| OpenXR Plugin | 1.11+ |
| URP | 17.0.3+ |
| Graphics API | Vulkan |
| URP render path | Render Graph (not compatibility mode) |
Enable it: **Project Settings > XR Plug-in Management > OpenXR > Android > Application SpaceWarp**. At runtime it is controlled through `SpaceWarpFeature` (calls: `SetSpaceWarp(true)`, and `SetAppSpacePosition` / `SetAppSpaceRotation` for the tracking-space offset when you move the rig).
> [!warning] ASW can hurt more than help
> ASW needs correct motion vectors on every moving object, including your hands and UI. Artifacts appear around fast-moving transparent objects. Try it only when you are GPU-bound at 72 Hz.
## 5.4 Foveated rendering
Foveation renders the periphery at lower resolution. On Quest 2 only **fixed** foveated rendering (FFR, centered) is available; eye-tracked foveation needs eye-tracking hardware, which Quest 2 does not have (general knowledge, not taken from a fetched page).
- Enable **Foveated Rendering** under the OpenXR Meta Quest feature options, and set the level at runtime through `XRDisplaySubsystem.foveatedRenderingLevel` (0..1) per the [SRP foveated rendering docs](https://docs.unity3d.com/6000.3/Documentation/Manual/xr-foveated-rendering.html).
- Higher levels gain more fill rate but show visible edge shimmer on text. UI panels at the periphery will blur ([[8.UI Toolkit for VR]]).
## 5.5 A runtime quality profile (inline script)
This script applies Quest 2-safe defaults at startup. It assumes Quest 2 unless it can positively identify a newer device, so a failed detection is safe. `SystemInfo.deviceModel` values for Quest headsets are **(unverified)**: check the log line on your device and adjust the string match.
```csharp
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR;
/// <summary>
/// Applies conservative Quest 2 defaults at startup.
/// Not compiled in an editor: verify API names against your installed package versions.
/// </summary>
public class QuestPerformanceProfile : MonoBehaviour
{
public enum Tier { Quest2, Newer }
[Header("Quest 2 tier")]
[SerializeField] float renderScale = 1.0f; // keep >= 0.85 (VRC.Quest.Performance.4)
[SerializeField, Range(0f, 1f)] float foveationLevel = 0.5f;
[SerializeField] float requestedRefreshRate = 72f; // Store minimum
[Header("Newer headsets")]
[SerializeField] float newerRefreshRate = 90f;
public static Tier DetectedTier { get; private set; } = Tier.Quest2;
public static float CurrentRefreshRate { get; private set; }
void Awake()
{
string model = SystemInfo.deviceModel ?? string.Empty;
Debug.Log(