GLB Optimizer for Meta Quest & VR: Hit 90fps Every Time
Here's an uncomfortable truth about VR: bad performance doesn't just look bad—it makes people physically sick.
Drop below 90 frames per second and your users start feeling dizzy, disoriented, and nauseous. Keep it up and they'll take off the headset and never come back.
That's why optimization isn't optional in VR/AR. It's the difference between an experience people love and one that lands in the "never again" pile.
Why VR Has Zero Tolerance for Bad Performance
The Science of VR Sickness
Your brain is constantly comparing what your eyes see with what your inner ear feels. In VR, when there's a mismatch—like your view stuttering while your head moves smoothly—your brain freaks out.
The result: motion sickness, nausea, and a very unhappy user.
The frame rate targets:
- 72 fps: 13.8ms per frame (bare minimum, some discomfort)
- 90 fps: 11.1ms per frame (industry standard, most people comfortable)
- 120 fps: 8.3ms per frame (noticeably smoother, minimal discomfort)
That frame time budget includes everything—rendering, physics, audio, input handling. Go over by even a few milliseconds and you drop frames.
Standalone vs. PC VR
PC VR headsets connected to a gaming computer have more headroom. A beefy GPU can push through heavier content.
But standalone headsets like Meta Quest? They're running on mobile chips. Think "really powerful phone" not "gaming PC." That means serious constraints.
Meta Quest Performance Targets
Meta Quest dominates the VR market—over 74% market share. If you're building for VR, you're probably building for Quest.
The Hardware Reality
- Quest 2: ~2GB usable RAM for your app
- Quest 3: 8GB total, better GPU, but still mobile-class
- Thermal throttling kicks in if you push too hard for too long
The Magic Numbers
These are your targets for Quest development:
- Draw calls: Under 100 per frame (ideally under 50)
- Triangles: 50,000-100,000 for the entire scene (not per model!)
- Texture memory: Budget carefully, aim for under 72MB
- File size: Keep individual models under 10MB
Note that triangle budget is for your whole scene. If you have 10 objects visible, each averaging 10k triangles, you're using your entire budget just on those.
VRChat Performance Ranks
If you're making avatars or worlds for VRChat, their ranking system tells you exactly where you stand:
Quest "Good" rank (avatars):
- Under 10,000 triangles
- 1 skinned mesh
- 1-2 materials
- Textures under 10MB total
Quest "Very Poor" (hidden by default):
- Over 20,000 triangles
- Multiple skinned meshes
- Too many materials or bones
Many VRChat events require avatars to meet at least "Medium" ranking. Go over the limits and you show up as a gray robot—not a great look.
WebXR: The Browser Challenge
Building VR/AR experiences for the web brings its own challenges. WebGL has different bottlenecks than native apps.
The #1 Problem: Draw Calls
Every material, every mesh that can't be batched = another draw call. JavaScript can't feed the GPU fast enough when draw calls pile up.
Real optimization results from a WebXR project:
| Metric | Before | After | Improvement |
|---|---|---|---|
| Materials | 49 | 34 | 31% fewer |
| Meshes | 638 | 38 | 94% fewer |
| File size | 21.7MB | 8.2MB | 62% smaller |
| Frame time (Quest) | ~34ms | ~7ms | 79% faster |
That's the difference between "unusable" and "smooth."
Framework Support
Good news: all major WebXR frameworks support GLB natively.
- Three.js: Full glTF 2.0, Draco, KTX2 support
- Babylon.js: Excellent glTF implementation
- A-Frame: Built on Three.js, same great support
- PlayCanvas: GLB is the primary format
Apple Vision Pro
Vision Pro's M2 chip gives you more headroom—200,000 to 500,000 triangles is possible. But optimization still matters for battery life and thermal management.
Apple's recommendations:
- Trade triangle count for fewer transparent pixels (transparency is expensive)
- Use unlit materials with baked lighting where possible
- Keep web-loaded models under 5MB
- USDZ format for native AR (convert from optimized GLB)
Mobile AR (ARKit & ARCore)
For phone-based AR experiences:
Platform Differences
- ARCore (Android) uses roughly 3x more memory than ARKit (iOS)
- LiDAR on iPhone 12 Pro+ enables much faster room mapping
- Target 100-200ms for model loading to feel snappy
Mobile AR Budget Guidelines
- Total triangles: 50k-150k for the scene
- Textures: 1024×1024 max for most assets
- File size: Under 5MB for fast loading over cellular
- Materials: As few as possible
Optimized assets reduce tracking interruptions by up to 40%—that's the difference between AR that "just works" and AR that constantly loses tracking.
Optimization Techniques for XR
Geometry Optimization
Aggressive decimation: You can often remove 80-90% of polygons with minimal visual impact.
LOD (Level of Detail): Multiple versions of the same model—high detail up close, low detail far away. Essential for any scene with distance.
Remove what's invisible:
- Backfaces that never face the camera
- Interior geometry (inside of solid objects)
- Details too small to see at viewing distance
Merge meshes: Fewer objects = fewer draw calls. Combine static objects where possible.
Texture Optimization
KTX2 compression: Unlike JPEG/PNG, KTX2 textures stay compressed in GPU memory. Huge savings for texture-heavy content.
Texture atlasing: Combine multiple textures into one large texture. Reduces material count and draw calls.
Mipmap generation: Pre-computed smaller versions for distant rendering. Improves quality AND performance.
Compress aggressively: ETC1S for solid colors, UASTC for complex textures.
Material Optimization
Merge materials: Every unique material is a potential draw call.
Bake lighting: Pre-computed lighting in textures instead of real-time calculation.
Avoid transparency: Alpha blending is expensive. Use alpha cutout or opaque materials where possible.
Unlit materials: When you don't need lighting calculations, skip them entirely.
Testing Your Optimized Models
Tools to Use
- OVR Metrics Tool: Meta's profiler for Quest
- Chrome DevTools: Performance tab for WebXR
- Xcode Instruments: For ARKit development
- Unity/Unreal Profilers: For native development
What to Measure
Don't just look at FPS—dig deeper:
- Frame time: More precise than FPS, shows exactly how long each frame takes
- Draw call count: Often the real bottleneck
- GPU utilization: Are you GPU-bound or CPU-bound?
- Memory usage over time: Watch for leaks during extended sessions
The Bottom Line
VR/AR optimization isn't about cutting corners—it's about respecting your users' physical comfort and the hardware they're using.
The good news: a well-optimized experience looks just as good as an unoptimized one. Often better, because consistent frame rates feel smoother than pretty graphics that stutter.
Start with the fundamentals:
- Know your triangle budget
- Minimize draw calls (merge meshes, reduce materials)
- Compress everything (Draco for geometry, KTX2 for textures)
- Test on actual target hardware
Get these right and you'll build VR/AR experiences people actually want to spend time in.
Need to optimize 3D models for Quest or WebXR? Our optimizer handles Draco compression, texture optimization, and mesh simplification automatically.
