Web XR experience becomes unstable on exit

I’ve been battling with this issue for a while and nothing I’ve tried seems to properly sort the issue.

When exiting an web XR experience back to the floating 2D browser window the window will become completely unstable bouncing around and killing the frame rate in the headset, so much so on the Quest 2 that it’s actually impossible to even click on the close button to kill it. I have to restart the whole thing just to get it back to being usable.

It’s not really possible to reproduce this in a simple playground as it only seems to become an issue with larger projects and after using them for a while. If I just open an experience use it for a few seconds and exit it’s not too bad.

Has anyone come across this before, is there a “proper” way to exit that I’m missing.

The best I’ve been able to come up with is a hack that auto restarts the whole page a few seconds after exit.

Just for me to understand - is this a babylon issue, or a webxr general issue? If it is a babylon issue I can at least try to debug the experience, see if I can find something thought all we do is exist the session…

How to tell?

The experience is entirely built with Babylon.
A brief test makes you think it is working but the longer I stay in the experience the more likely it is to become completely unstable on exit as far as I can tell.

I try and dispose of everything before exit, I’m not really sure where to go to even debug it.

Sounds like a memory leak, which I will be really happy to solve.

So - entering and coming out straight after works? Do you have any special features in the scene? or pure VR?

There are many WebXR experiences on the web. I was wondering if it happens when you are visiting them as well, or just your experience

I need to do more testing with other experiences, so at the moment the answer is I’m not sure. I’ll get back to you on that.
As to special features, not really, it’s pure VR, but what it does do is it has a menu to load different models so it’s loading and unloading glb files all the time. I have done a lot to try and debug that it is disposing of everything as it goes. I couldn’t find a way to debug the actual memory state though, so maybe there’s something more I could do there?

I see. it does feel like a high consumption of memory. but I can’t really tell.

What you can tell is connect your device to your PC and start a debugging session. You will need to enable debugging from the Meta App. Afterwards, the dev console of chrome can help with debugging performance and memory consumption

So the issue I have there is the Quest refuses to connect to my laptop either cabled or via wifi. So I’ve not been able to do anything direct like that.

I had this issue for quite some time! what solved it for me was a different cable and a different USBB port, but i agree, it is not 100% stable.

I do have a Rift that’s cabled and runs via Chrome, I’m using that to look at the memory usage… maybe something will show up there

1 Like

One other thing to note, if it is a memory issue why would it only show up as an issue on exit and not during the XR session itself which continues to run smoothly throughout?

I’ve killed all memory leaks as far as I can tell but the issue remains. There were some textures not getting disposed when I was swapping models. So it’s not that.
It is something that builds up over loading different models though. If I just load one large model I can play with it for ages and exit without any issues.

The only other “unusual” thing is that I’m using SPS to improve fps. Could there be something up with loading multiple SPS one after another, even though they do get disposed of. I’m seeing in the logs that I only ever have 1 as a resource at a time.

Another funny thing. If I pause the renderloop on exit and then start it up again after 5 seconds I don’t see the stability issue.

I have likely spent 90% of my time developing my VR thing just focusing on performance. I could start off well but after moving about and doing stuff, I could see the fps dropping below the magic 72 hz and stutters introduced. I spent two days recently trying to figure out what the problem could be that had been introduced only to read on the webz that Meta has totally messed up Quest Link so that struggles to keep up encoding/decoding properly resulting in lost frames enmasse.

I have had many late nights chatting with Gemini about why fps tanks suddenly after a reboot, feeling that it is basically the moon phase that decides if I will have a good WebXR experience or not. I am considering getting Virtual Desktop and a dedicated router for streaming wirelessly instead as I think a lot of the problems is just the Quest Link software being difficult. Especially when I can see that the scene.render takes 3ms and the actual GPU render takes less than 1ms, and I still have this horrible stuttering as it is unable to keep 72hz. I have done lots of profiling and while it seems that havok could be a reason in the chrome performance dumps, they are reflecting that due to the missed frames havok does X number of calculations based on the number of frames dropped. And that with all meshes static so no real calculation needed.

Generally this has been the biggest hurdle with WebXR VR development with Babylonjs as I spend far too much time on trying to keep that 72hz than actually coding my experience lol. But I guess with VR that is important, but still hard when you dont really know the culprit and it could just be the Quest Link connection that is bad. The experience rapid coding cycles using a simple Vite or Tauri build of Babylonjs is lightyears ahead of the slow slog of compiling in Unity. We just need the stable platform with good performance (where are you WebGPU for VR?) and its all golden.

I hear you. The connection issues for debugging continue to plague me. But the fps issue has gone away for me since I discovered SPS and chunking the build process over a number of frames. This exit issue is the last remaining bottleneck to good performance for me.

So I made a playground to try and reproduce the instability issue, but of course when I run it from there it’s all good, so I’m currently none the wiser.

Sticking with my pause renderloop trick for now I guess.

The only other thing I can think of is just all the cleanup that happens on exit is triggering something, especially noticeable on the much slower Quest 2….

This sounds vaguely familiar, I may have had something like that a while ago, and may have solved it.
I don’t really remember, but I had a look at my code, and what I’m doing (among other things) on exit is
this.camera.attachControl(this.canvas, true);
and that’s done in case BABYLON.WebXRState.NOT_IN_XR of state change observer, added with baseExperience.onStateChangedObservable.add().
I.e. called after XR session terminates.
There’s another piece that ensures the right camera is set, but that’s possibly because I have multiple cameras around.

Now, only thing sure is that this piece of code is there for a reason :slight_smile: While I can’t recall the reason exactly, it may have been incorrect camera management, like, XR camera remains active camera after exit, and you get rendered images of both left and right eye.

Long story short, you may want to try
myCamera.attachControl()
scene.activeCamera = myCamera
after XR exit.

Thank you for the reply, unfortunately in my situation that on it’s own doesn’t seem to resolve the issue, I still need to pause the renderloop for 3 seconds to get it to stabilise…

hey, and sorry for a late reply!

Just trying to wrap my head around this

  1. The playground works as expected
  2. The only issue is actually leaving the experiene
  3. when stopping the render loop for 3 seconds and then continuing, the issue is gone

Is that technically right?