DEEP MATRIX

[ GAME DEVELOPMENT ]

Quest Optimization: Draw Calls, Shaders and Overdraw

5 MIN READDEEP MATRIX

To optimise a standalone VR game for Quest, you reduce the number of draw calls, simplify expensive shaders, cut overdraw from transparent effects, and then measure every change on the device. Quest runs on a mobile chip with a tight power and thermal budget, so waste that a PC would hide shows up as dropped frames. The fixes are mostly about doing less work per frame, and the only reliable way to know you succeeded is to profile on the headset.

Why do draw calls cost so much on standalone VR?

Each draw call is a request from the CPU to the GPU to render some geometry with some material. Issuing one is not free. The CPU has to prepare state, bind resources and submit the work, and on a mobile platform that overhead adds up quickly.

A scene with thousands of separate small objects, each with its own material, can spend more time talking to the GPU than actually drawing. The screen may look simple, but the frame still runs long. This is why draw call count is usually the first number to check when a Quest scene is slow.

How do you reduce draw calls with batching?

Batching combines geometry so the engine can send fewer requests. The idea is simple, but the details decide whether it works.

  • Share materials. Meshes that use the same material and textures can be merged or batched. Every unique material is a potential extra draw call, so consolidating materials is often the biggest single win.
  • Use texture atlases. Packing several textures into one sheet lets many objects share one material.
  • Merge static geometry. Props that never move, like floors, walls and set dressing, can be combined into larger meshes offline. Keep the merged chunks small enough that culling still works.
  • Avoid per-object effects. Each object with its own shader parameters or per-object properties can break batching.

Your engine's frame debugger will show you where batches break. Start there, not with guesses.

When should you use instancing instead?

Instancing draws many copies of one mesh in a single call. It is a strong fit for repeated items such as railings, fence posts, crates, cables, debris, grass or crowds of identical enemies.

The tradeoff is flexibility. Instanced objects usually share the same material and cannot each have a unique texture without extra work. Use instancing where the repetition is obvious and keep unique hero props separate.

Here is a quick comparison:

Technique Best for Watch out for
Batching Static props that share a material Lost batches when materials differ
Instancing Many copies of one mesh Limited per-object variation
Atlasing Reducing the number of materials Texture size and mip quality
Merging Static environment chunks Culling granularity

How do you simplify shaders for Quest?

Shaders run for every pixel they cover, so a shader that looks fine on a PC can be far too heavy on a mobile GPU. The goal is to keep the visual result while reducing the instructions and the number of texture reads.

Practical steps:

  1. Remove features you do not use. Unused branches, extra texture channels and debug paths still cost you.
  2. Prefer simpler lighting models for most materials. Save the expensive ones for the few surfaces where the player will look closely.
  3. Replace real-time effects with baked or pre-computed results where you can.
  4. Keep shader variants under control. Every variant adds build size and can cause hitches when it loads.
  5. Check precision settings. Lower precision is often enough for colours and simple values, and it is cheaper on mobile hardware.

Measure after each change. A cleverer shader that is slower on device is not an improvement.

How do you control overdraw from transparent effects?

Overdraw happens when the GPU paints the same pixel more than once in a frame. Opaque objects are usually handled with depth testing, but transparent objects, particles, fog and glow effects often stack up and repaint the same screen area many times.

Common culprits include:

  • Large, stacked particle systems that overlap each other.
  • Full-screen fog or haze layers.
  • Big transparent sprites used for glows or smoke.
  • Decals drawn over many layers of geometry.

To control overdraw, use your engine's overdraw visualisation to find the hot spots. Then reduce the area each effect covers, cut the number of layers, use fewer and smaller particles, and move effects closer to the player only when they need to be seen. Sometimes the best fix is to remove a layer that adds almost nothing to the image.

How do you measure performance on the headset?

Measurements on a PC or in the editor do not tell you what the headset will do. Profile on device, with the same build you will ship, and record results before and after each change.

A simple routine works well:

  • Pick a fixed camera path or test scene so you compare the same work.
  • Record CPU time, GPU time and frame time with the platform's profiling tools.
  • Note the draw call count and the number of material changes.
  • Repeat each test several times, because thermal state changes results.
  • Keep a short log of what you changed, so you know which change helped.

Do not copy performance figures from articles or forum posts. Your scene, engine version and driver stack decide the numbers, and only your own device measurements matter.

What is a good order for optimising a Quest game?

Work on the biggest and cheapest wins first. A sensible order is to fix obvious problems in the profiler, reduce draw calls through material consolidation and batching, simplify the shaders on your most common surfaces, control overdraw from effects, and then tune the rest.

If you are bringing a PC game to standalone hardware, the specific changes are covered in what changes when you port a PC VR game to Quest. For a broader starting point on performance, see performance on standalone VR and where to start. Once the basics are in place, profiling a VR game with the right tools and habits shows how to turn raw numbers into clear decisions.

Optimisation is a loop: measure, change one thing, measure again. Keep that loop short and you will find the real bottlenecks faster than any checklist can tell you.

Frequently asked questions

What is a draw call and why does it matter on Quest?

A draw call is a request from the CPU to the GPU to render a batch of geometry. On a standalone headset the CPU and GPU share a tight power budget, so sending too many separate requests can cost frame time even when the scene looks simple.

What is the difference between batching and instancing?

Batching combines different meshes that share a material into fewer draw calls. Instancing draws many copies of one mesh in a single call, which works well for repeated props like railings, crates or debris.

How do I find overdraw in a Quest game?

Most engines have a debug view that shows how many times each pixel is drawn. Look for large areas that are painted many times, especially stacked transparent particles and fog, and reduce or remove them.

Should I trust a performance number from a guide?

No. Hardware, drivers, engine versions and scene content change the results, so measure on the headset you ship to and compare before and after each change.