Vav Labs
Back to case studies

Case study / Frame budget recovery / In progress

Meta Quest VR Performance

Mobile VR performance work on Meta Quest hardware running Unity URP. Every millisecond has witnesses on a device where the thermal envelope, the fixed-foveated rendering budget, and the draw call ceiling are all real constraints before the first profiler session opens.

The constraint

Quest hardware runs at 72 Hz or 90 Hz depending on the application target. That is an 11.1 ms or 13.8 ms frame budget split across CPU, GPU, and the runtime compositor. URP on mobile adds additional constraints: no compute shaders in the main render path, limited MSAA performance, shadow cascades that cost more than they appear to, and transparent objects that reward aggression with overdraw.

The platform also enforces thermal throttling without warning the application. A frame that passes certification can fail in the field after five minutes of play if the thermal budget was ignored during development. This is the constraint that testing on a cold device politely declines to surface.

Profiling methodology

The work begins with a device capture, not an editor estimate. OVR Metrics Tool for thermal and timing data, Unity Profiler over USB for script and rendering breakdown, and RenderDoc for draw call and shader inspection when the GPU timing looks suspicious.

Each capture targets one specific question. What is the GPU bottleneck? Which render pass costs the most? Which materials create shader variants that are never used at runtime? Broad captures are useful for orientation; narrow captures answer the question on the table.

Common recovery moves

The first passes are usually structural: shadow distance, cascade count, realtime lights per tile, and overdraw from particles and UI. These are recoverable changes that do not require artist rework and confirm whether the problem is architectural before committing to deeper changes.

Fixed-foveated rendering configuration, MSAA tier, render scale, and depth texture ownership are the second layer. These interact with post-processing and with Quest's compositor in ways that are not always obvious from the URP documentation alone.

UI is often a quiet offender. Canvases stacked at native screen resolution, transparent blurs behind menus, and per-frame text layout work add cost the rendering profiler attributes to the wrong pass at first glance. Rendering UI at a lower resolution into a blitted overlay buys back milliseconds at almost no visual cost.

The draw call ceiling

Quest has a draw call budget that the editor will not warn you about. SRP Batcher compatibility, GPU instancing, and static batching are not optional luxuries — they are how a scene with reasonable geometry stays inside the render thread's budget at all. A single material variant per shader keyword is the difference between a frame that ships and a frame that needs explaining.

The trap is materials that look identical but break batching: different render queue, different keywords, different instance data, different shadow casting modes. The Frame Debugger names the offenders honestly. The fix is usually consolidation, not cleverness.

Thermal and the second profile

A Quest build has two performance profiles: cold and warm. Cold is the profile most developers measure, because it is what the device shows for the first capture. Warm is what players actually experience after five minutes of play, once the device has throttled CPU and GPU clocks to stay inside the thermal envelope.

A frame that lands at 10.8 ms cold can land at 14.2 ms warm. That difference is the entire 72 Hz budget. The discipline is to leave headroom rather than fill the budget on a cold device. Targeting roughly 8 ms cold on a 13.8 ms warm budget is the kind of conservatism the field punishes by being right.

What does not survive contact with Quest

Post-processing stacks copied from a desktop project rarely survive the journey. Bloom, depth of field, and screen-space ambient occlusion are expensive on mobile tiled architectures even when they sound cheap on paper. The honest move is to drop them, not to tune them aggressively enough that they appear to fit.

Realtime shadows from multiple lights, full-screen transparent particle storms, and any effect that samples the camera depth or color texture more than once per frame are similar offenders. They are tools that belong in a different budget.

Current status

Optimization notes and checklist from real device work are being written up from captured sessions. The goal is a short, reusable reference for URP + Quest projects rather than a comprehensive manual. More detail will appear here as the notes solidify into something useful rather than private.

The intended output is not a generic optimization tutorial. There are many of those, and most of them are correct in the same ways. What is missing publicly is honest capture-backed notes about which moves matter in what order on this specific platform — which is exactly what survives a few cycles of real device work.