I’m currently working on a virtual reality project using WebXR, and I’m trying to understand why I get such low FPS when entering VR mode.
At the moment, the scene runs at around 20 FPS when I’m in VR Mode, but if I open the scene on my computer it run at 50-60 FPS.
I’ve tried optimizing the scene and setting the hardware scaling level to 2, but it doesn’t significantly increase the performance in VR.
I’m using a PICO 4 headset.
Here is an example scene where I get around 20 FPS. You can try it yourself: VR Scene Example
If anyone could explain why it runs so slowly and how I could optimize the scene to get stable performance, it would be very helpful.
P.S :
I use scene.createDefaultXRExperienceAsync() to create the XR session
Ignore textures/materials that do not load in the scene example it’s normal.
The usual suspects are big and complex meshes that are still marked as pickable.
In the scene you provided there are some meshes with 40k vertices (the Ballon#2 for example), and the ground is also very high on vertices. if these are pickable and you have the controllers enabled it will iterate the entire array to find the picked point. A quick check is - point the pointers towards the sky and see if the FPS is a little better.
It also depends on the device you are testing with, but if i see correctly, it’s a device with native 90 fps, which probably means - quite a new one.
Seeing the debug graphs, it seems like the GPU is always at high usage. Can you try eliminating some meshes, or setting them to bi invisible to see which is the culprit?
Thanks for the answer, I’ve tried deleting heavy meshes, so now only the essential ones remain. I also tried pointing the controller pointers toward the sky and optimized the scene, but despite these changes, I’m still stuck around 30 FPS.
I’ve updated the example scene I provided earlier if you want to test it yourselves.
Maybe the problem comes from the materials or textures?
I’m using a Pico 4 headset, so it should definitely be able to handle this type of scene.
In my VR tests it’s draw calls that are the real killer not the mesh size so much. If you can reduce the number of materials then you can reduce draw calls and radically improve fps
What GPU are you using? Is it PCVR through a cable/wireless? What compression/bitrate if using either? Is it standalone on a web browser on the Pico? Is the native browser there any good if so? There are many factors that define the performance. Having a Quest 3 myself, I have had to fiddle a lot with the Oculus debug tool to get stable 72fps without reprojection frames over USB3 cables (and you need good cables to get high bitrates). On my 4070 Ti Super I am unable to keep that target fps when I have more than 2500 draw calls. Also the number of meshes that Babylonjs has to iterate over can easily kill performance, same with lots of garbage collection - so make sure your render loops arent allocating a lot of objects that need to be GCed - recycle objects as often as possible.
Personally I dont use the picker in Babylonjs and neither the built in physics. Havok plugin for both is way faster.
Also be careful with transparent materials, some more advanced shaders on those will absolutely tank performance.
Mesh size can influence your CPU usage if it is pickable (which is what i tried expressing in my message ). Of course, optimizing a scene will help with performance, but for webxr specific (and in babylon), it’s also optimizing other things, or at least understanding the trade-offs.
Thank you for your feedback; I’ve been away for the last three weeks, so please excuse the delay.
@RaananW To give a quick summary, I’m now at around 60–80 draw calls (see attached stats). I’ve removed complex and unnecessary meshes, as well as unnecessary materials and textures, and I’ve optimised the scene as much as possible.
Note that I’ve also disabled the picker and set the hardwareScalingLevel to 1.5.
Despite all these optimisation changes, I’m still below 30 FPS.
Could I ask you to test my scene with your headsets and let me know what configuration you’re using?
This would help me determine whether the problem is specific to my headset.
You might be at the mercy of the Pico Browser WebXR implementation. I have very little experience with running WebXR in my Quest 3 browser as I feel the quality you can get there is just too low unless you prebake everything and it is basically all static meshes with little interactivity. But then again I have not tried it much - just a build from Unity once a good while back. I am tempted to see however how well I could run my VR world thingy - but it would have to be noodled down to barebones then.