LogoLogo
DocumentationWebsiteCommunityPortal
  • Get Started
    • Quickstart
    • Tutorials
    • Wizards
  • Features
    • Release Notes
      • 2024
        • 04-05 Apr Update
        • 03-27 Mar Update
        • 02-07 Feb Update
        • 01-23 Jan Update
        • 01-05 Jan Update
      • 2023
        • 12-18 Dec Update
        • 11-30 Nov Update
        • 10-30 Oct Update
        • 10-04 Oct Update
        • 09-18 Sep Update
        • 09-11 Sep Update
        • 08-28 Aug Update
        • 08-14 Aug Update
        • 07-23 July Update
        • 07-14 July Update
        • 06-16 June Update
        • 06-6 June Update
        • 05-16 May Update
        • 03-31 Mar Update
        • 03-16 Mar Update
        • 03-10 Mar Update
        • 02-07 Feb Update
        • 01-24 Jan Update
        • 01-10 Jan Update
      • 2022
        • 12-08 Dec Update
        • 11-13 Nov Update
        • 11-07 Nov Update
        • 10-26 Oct Update
        • 10-14 Oct Update
        • 10-01 Oct Update
        • 08-26 Aug Update
        • 08-02 Aug Update
        • 07-01 July Update
        • 06-08 June Update
        • 05-20 May Update
        • 05-05 May Update
        • 04-25 Apr Update
        • 02-11 Feb Update
        • 01-28 Jan Update
        • 01-10 Jan Update
      • 2021
        • 12-10 Dec Update
        • 12-01 Dec Update
        • 11-26 Nov Update
        • 11-17 Nov Update
        • 11-12 Nov Update
        • 11-09 Nov Update
        • 11-02 Nov Update
        • 10-26 Oct Update
        • 10-21 Oct Update
        • 10-14 Oct Update
        • 09-27 Sep Update
        • 08-31 Aug Update
        • 07-20 July Update
        • 07-02 July Update
        • 06-31 June Update
  • Metaverse
    • Building
      • Portal
        • Team Members
        • Defining Global Variables
      • Editor
        • File Manager
          • Selecting a file
          • Sketchfab Integration
        • Placement in 3D Space
        • Project Settings
          • Preferences
          • Branding
          • Collaborators
          • Menu
          • Variables in Settings
          • Lead Generation
          • Tour Mode
          • Advanced
          • E-Commerce in Settings
        • Preview
          • Headset Testing - WebXR Emulator
        • Viewport Properties
        • Editor Keyboard Shortcuts
      • Scenes
        • 3D Scene
          • Avatar System
          • Colliders
          • Zones
          • Lights
        • 360 Scene
        • Orbit Scene
      • Elements
        • Image
        • Video
        • Audio
        • GIF
        • Text to Speech
        • Character
        • Character AI
        • Actionbar
        • Timer
        • Polygon
        • Linked Popups
        • Variants
      • Rules
        • Shared Rules
        • How Rules Work
        • Number Variable Rules
        • String Variable Rules
        • Boolean Variable Rules
      • Variables
        • Autogenerated Variables
        • String Substitution
        • Capturing User Input
      • Build FAQs
    • Publishing
      • URL or QR Code
      • Embed on your Website
      • Full-Page HTML
      • Embedding within Apps
        • Android Embed
        • React Native Embed
      • Export as SCORM package
      • Authentication
        • SSO
        • Password With Expiry
        • Email with OTP
        • Custom List
        • Token
        • Load from another Experience
      • Publishing FAQs
      • Private Cloud Deployment
    • Multiplayer
      • Host Mode
      • Broadcast Mode
      • Voice Chat
      • Text Chat
      • Video Chat
      • Screenshare
      • Comments
      • Share Reactions
      • Notifications
      • Troubleshooting webcam and microphone
    • Analytics
      • Advanced Analytics
      • Leaderboard
      • Viewer Sessions
    • Integrations
      • GMetri with SCORM
        • Embed a SCORM package in a GMetri experience
      • Live Stream on GMetri
        • Live Stream Zoom on YouTube
        • Live Stream Zoom on Vimeo
          • Zoom Setup
      • E-Commerce with GMetri
        • Shopify Integration
        • WooCommerce Integration
        • Custom Integration
        • Using an E-Commerce Plugin
      • Adding a Chatbot
      • Sending data to GMetri Deployment
    • Viewing
      • Avatars
      • First/Third Person
      • Concurrency
      • Oculus Controls
      • Viewer Keyboard Shortcuts
      • IT Permissions
        • Whitelisting for Viewing Experiences
        • Whitelisting for Editing Experiences
        • Whitelisting for Analytics
        • Subprocessors
    • GMetri SDK
      • GMetri Player
      • GMetri SDK APIs
        • Project
        • Deployment
        • File
        • Viewer Group
      • GMetri Webhooks
      • API Token
      • Examples
  • Guidelines/Compatibility
    • Guidelines
      • Content Creation Guidelines
        • XR Experience Storyboard
        • 360 Degree Video Shoots
        • Avatars vs Characters
        • Designing 3D Models for Immersive VR mode
      • Asset Guidelines
        • 3D Models
          • Export GLB/GLTF from 3DS Max
          • Export GLB/GLTF from Blender
        • 360 Pano Images Render
        • Resources for Assets
        • Asset FAQs
        • Image Aspect Ratio
      • Experience Optimizations
        • Scene Optimizations
          • Performance Monitor
        • Image Optimizations
        • Audio Optimizations
        • Video Optimizations
        • 3D Model Optimizations
      • Workflows
        • Green Screen
          • Apply Green Screen to Videos
          • Accurate Color Selection
        • QR Code Scanner
        • Adding Sprites
        • Adding Background Music & Persistent Logo
        • EmbedHTML Snippets
    • Compatibility
      • Platform Requirements - Viewer
      • Platform Compatibility Matrix
      • Supported File Formats
      • Supported Browsers
      • Capture Network and Console Logs from Chrome Browser
    • Limitations
      • iOS Limitations
      • VR Mode Limitations
  • Platform
    • Billing
    • Platform FAQs
    • Security
    • Legal
Powered by GitBook
On this page
  • Rendering performance is a complex topic
  • Use complex materials judiciously
  • Compress your textures
  • Mesh Recommendations
  • Draw Calls

Was this helpful?

Edit on GitHub
Export as PDF
  1. Guidelines/Compatibility
  2. Guidelines
  3. Content Creation Guidelines

Designing 3D Models for Immersive VR mode

PreviousAvatars vs CharactersNextAsset Guidelines

Last updated 1 year ago

Was this helpful?

This document provides essential tips and best practices to ensure your 3D models deliver a compelling and comfortable VR experience. Following these guidelines will enhance immersion, reduce motion sickness, and optimize performance.

Rendering performance is a complex topic

In what follows, we provide general guidance and recommendations that can help set appropriate expectations for WebXR experiences running on Meta Quest headsets. But at the outset, it’s important to emphasize that these are recommendations and not guarantees. Rendering performance is a complex topic. Seemingly small, subtle differences can have a significant impact on the performance of your experience, so the only way to know for sure if these recommendations will apply to your experience is to test and measure the improvement.

Use complex materials judiciously

Popular 3D frameworks like ThreeJS and Babylon.js support PBR materials. GMetri uses ThreeJS under the hood. While these materials should be used judiciously, you can use these in your experience to great effect and still achieve good performance on Meta Quest hardware.

As mentioned above, being careful with front-to-back is critical here. You probably can’t afford to render complex materials to every fragment multiple times per frame.

PBR materials support multiple texture maps, such as diffuse, normal, ambient occlusion, roughness, and so on. The more maps you use, and the higher resolution they are, the more work the GPU has to do. Texture bandwidth (the amount of texels the GPU has to read) can become a bottleneck. Experiment with dropping maps entirely or using lower-resolution maps for some or all of the material’s maps as a way to reduce the cost of these materials.

Compress your textures

/Basis Universal is the recommended approach to texture compression for WebXR experiences on Meta Quest devices. While this may not result in file sizes that are as small as JPEG or PNG, the in-memory size of the texture will be smaller and the GPU can access these textures more efficiently which will decrease the texture bandwidth of your scene.

Here are a few resources to help you get started on compressing your textures

  • Use to visualize how much VRAM will be consumed by rendering your 3D model. You want to keep this as low as possible < 10-20MBs

  • also provides a scripting toolkit that uses internally and can optimize your 3D models.

  • Use the ZenCompress tool for compressing textures to KTX2/Basis compressed textures. This video covers the tool in detail

  • Follow this video to look for more ways to optimize your 3D model

Mesh Recommendations

  • Keep the triangle/poly count under 10000

  • Reduce the number of textures used. In an ideal scenario, keep only the base texture and remove all other textures (bump map, normal map, emissive map, etc)

  • Ensure that meshes are not densely packed in a localized region. For example, this can happen in 3D models that represent a meeting room with chairs and tables. The meshes can be densely packed for the chairs

  • Use lower-resolution textures. Recommended resolution is <2K

  • Ensure that the draw calls are low. Recommended is < 10

  • Avoid heavy use of lights. Instead, light bake all the textures using 3D modeling software

  • Remove any unused meshes, vertices, and textures from the 3D model. Any unused textures and meshes are still loaded into RAM.

Draw Calls

The GPU doesn’t render on its own – it has the CPU telling it what to render and how, through the process of a draw call. A draw call is ‘A group of polygons sharing the same properties’ or ‘a group of polygons sharing the same material’.

So say you have a tree that has a material for the bark, one for the leaves and one for the berries/pinecones/acorns. Three draw calls, doesn’t seem a lot? Except you are now on a hill overlooking a forest and there’s several hundred trees in view. That’s now in to the thousands of drawcalls.

But why is this a bad thing? Draw calls are slow due to the tiny pauses the GPU makes between each draw call as it waits for the next piece of information to be handed to it from the CPU. Think of the difference between handing over a 1 GB file vs 1mil 1KB files – it’s much quicker to do one big pass that many little ones. Draw calls will often have a more substantial impact on performance than polycount. It is always best practice to make assets as low poly as you can without losing the visual fidelity you are after.

Reducing Draw Calls

There are a few different techniques you can look into to reducing your draw calls.

  • One other simple method to reduce draw calls is to combine models together that share the same materials. So instead of placing each tree by hand, you group several trees together and then place them in groups. Instead of each tree being a draw call, especially if they share the same material, the whole group becomes one.

Merge as many meshes as possible into a single mesh to reduce draw calls. A tutorial on how to merge meshes using Blender can be found here

Use to visualize how much VRAM will be consumed by rendering your 3D model. You want to keep this as low as possible. Recommended is <30Mbs.

A common solution is to use a – where you combine all of the different texture maps used on a mesh into one single big texture. There can sometimes be issues with texture bleeding at low resolutions, but this is relatively minor compared to the performance gains that can be made.

KTX 2.0
https://gltf.report/
https://gltf.report/
gltf-transform
https://www.youtube.com/watch?v=gsqrHDmgTfA
https://www.youtube.com/watch?v=Djx5WltmTUU
https://blenderfaqs.com/blog/blender-how-to-combine-meshes
https://gltf.report/
texture atlas