MozillaReality / unity-webxr-export

INACTIVE - Assets for creating WebXR-enabled Unity3D projects.
https://mixedreality.mozilla.org/unity-webxr-export/Build/
Apache License 2.0
627 stars 127 forks source link

Poor performance on Oculus Quest #372

Closed reillydonovan closed 3 months ago

reillydonovan commented 4 years ago

Hi, is there a way to improve the fps and render quality on Oculus Quest? Whenever I try to run the program it is pixelated and the frame rate is jumpy. Let me know what's possible, thanks!

kexar commented 4 years ago

I had the same poor performance on Quest Oculus browser with the latest 2.0 version in desert demo.

eyegautdis commented 4 years ago

+1 more for the same issue. Some of the jitter issues are a bit better since the webvr release but the other issues above remain. Because it seems to work fine using the Oculus Link I suspect this might be some incompatibility with the Quest's built-in browser (just a guess) since other webvr/webxr experiences I've tried have never shown this issue.

De-Panther commented 4 years ago

A Scene optimization for the Quest might help. Like not use Unity's real time shadows...

eyegautdis commented 4 years ago

I've actually tried a lot of that. I've been trying to fix this myself for the past 4 months or so with no luck. Even a scene with the absolute minimum (including no real time shadows, baked lighting etc.) with a single plane, no background and a single cube in the middle results in the same behavior.

De-Panther commented 4 years ago

Try this https://de-panther.github.io/unity-webxr-export it's based on this repo but with some optimizations (planning to merge them here)

eyegautdis commented 4 years ago

that actually works quite well, de-panther. it's very sharp and the frame rate looks good, too. I'm noticing the initial loading page looks different. What version of unity was this exported from, if you don't mind sharing?

De-Panther commented 4 years ago

Unity 2019.3.0f6 They did added support for Retina displays somewhere on the 2019 cycle. I see that here it was built using 2018.4.17f1 so it might be related to the use of window.devicePixelRatio

eyegautdis commented 4 years ago

If I use Unity 2018.4.17f1 to build, it's dramatically improved. I was originally using 2018.4.18f1. Something in that 18f1 release must be causing an issue. I will continue with 17f1 and see where that takes me and I will also give 2019.3.0f6 a try, too.

De-Panther commented 4 years ago

Great. Maybe it would be better to update the version here to 2019.3

reillydonovan commented 4 years ago

De-Panther this is notably better in so many ways, thank you for this.
Something I'm noticing is a bit of jitter when doing something like picking up the reflective spehere and walking around with it. Regardless previous versions of WebVR & WebXR builds had a lot of tracking drift that would induce visually induced motion sickness whereas the tracking in your iteration is much more stable (I'm sensitive to motion sickness). Please keep up the good work, I would love to help in anyway I can contribute. Cheers~

De-Panther commented 4 years ago

Thanks :) Regarding the jittering when picking objects - Does only the object is jittering or also the hands? If it's only the object, it's related to the FixedJoint, and if the hands are jittering it means that it's FPS issue.

I'm currently working on some PRs with fixes from the other repo, but I'm doing it one feature at a time, as the code there is messy. We already implemented here the Inline Session that should improve some aspects of the pipeline, but the main issue in the Quest is related to the real time shadows IMO.

tvkamara commented 4 years ago

Just want to confirm that there is definitely a "night and day" difference between the current (downloaded today 04/20/2020) Unity Asset Store version of the webxr-exporter and de-panther's own version posted above. 30-40 fps jumps to 72 in Oculus browser. Awesome. Hope the relevant stuff gets updated to Asset store and this repo soon :). Also noticed the small jittering when picking up objects. The hands are completely jitter-free so yes, it is possibly related to the FixedJoint and can be easily fixed.

hybridherbst commented 4 years ago

@De-Panther I see you merged some of your changes in that other build - have that been all? Or is there others that are still missing? I think I'm still seeing a performance difference between latest master and your version above (yours is faster). (by the way, was very surprised to find it supports AR!)

De-Panther commented 4 years ago

There are still some changes to merge here (Or re-write, as the repos are not so similar right now).

fernandojsg commented 4 years ago

@soraryu I'm going to do some benchmarks to try to identify which parts are adding being the bottleneck or changes that are increasing the performance and I'll let you know. I agree with @De-Panther that realtime shadows probably is quite heavy although he has included other optimizations on his fork that look interesting to analyse and incorporate here, but it could be great to identify the impact of all them somehow.

fernandojsg commented 4 years ago

I just tested it. TL;DR having shadows or not is a difference of around 15% in performance on the current master branch.

The current master release:

 {
  fps: {
    n: 19,
    min: 24,
    max: 72,
    sum: 849,
    mean: 44.68421052631578,
    q: 2002.1052631578943
  },
  tear: { n: 27, min: 0, max: 0, sum: 0, mean: 0, q: 0 },
  early: {
    n: 27,
    min: 0,
    max: 70,
    sum: 187,
    mean: 6.925925925925924,
    q: 10713.851851851847
  },
  stale: {
    n: 27,
    min: 0,
    max: 72,
    sum: 1753,
    mean: 64.92592592592594,
    q: 11225.851851851854
  },
  mem: {
    n: 27,
    min: 1554,
    max: 1804,
    sum: 43458,
    mean: 1609.5555555555554,
    q: 291666.6666666668
  },
  app: {
    n: 27,
    min: 0,
    max: 6.92,
    sum: 13.84,
    mean: 0.5125925925925926,
    q: 88.67851851851852
  }
}

and with the same configuration but just removing the shadows:

 {
  fps: {
    n: 17,
    min: 50,
    max: 53,
    sum: 871,
    mean: 51.23529411764706,
    q: 13.05882352941175
  },
  tear: { n: 17, min: 0, max: 0, sum: 0, mean: 0, q: 0 },
  early: { n: 17, min: 0, max: 0, sum: 0, mean: 0, q: 0 },
  stale: { n: 17, min: 72, max: 72, sum: 1224, mean: 72, q: 0 },
  mem: {
    n: 17,
    min: 1554,
    max: 1804,
    sum: 29168,
    mean: 1715.7647058823527,
    q: 242647.05882352922
  },
  app: { n: 17, min: 0, max: 0, sum: 0, mean: 0, q: 0 }
}

You can see on average it's around 14%+ on avg fps from 44 to 51. That's just when loading the scene and looking around.

If I take one cube on each hand and I move them around: master:

 {
  fps: {
    n: 16,
    min: 39,
    max: 44,
    sum: 648,
    mean: 40.5,
    q: 36.00000000000013
  },
  tear: { n: 16, min: 0, max: 0, sum: 0, mean: 0, q: 0 },
  early: { n: 16, min: 0, max: 0, sum: 0, mean: 0, q: 0 },
  stale: { n: 16, min: 72, max: 72, sum: 1152, mean: 72, q: 0 },
  mem: {
    n: 16,
    min: 1554,
    max: 1804,
    sum: 28364,
    mean: 1772.75,
    q: 109374.99999999997
  },
  app: { n: 16, min: 0, max: 0, sum: 0, mean: 0, q: 0 }
}

no-shadows:

{
  fps: {
    n: 15,
    min: 44,
    max: 49,
    sum: 718,
    mean: 47.86666666666667,
    q: 17.733333333333334
  },
  tear: {
    n: 17,
    min: 0,
    max: 2,
    sum: 2,
    mean: 0.11764705882352944,
    q: 3.764705882352941
  },
  early: {
    n: 17,
    min: 0,
    max: 70,
    sum: 103,
    mean: 6.058823529411764,
    q: 5364.9411764705865
  },
  stale: {
    n: 17,
    min: 0,
    max: 72,
    sum: 1115,
    mean: 65.58823529411765,
    q: 5854.117647058824
  },
  mem: { n: 17, min: 1804, max: 1804, sum: 30668, mean: 1804, q: 0 },
  app: {
    n: 17,
    min: 0,
    max: 7.09,
    sum: 7.09,
    mean: 0.41705882352941176,
    q: 47.311152941176466
  }
}

Again similar difference, from 40fps to 47fps ~15%.

I'll be testing the @De-Panther branch to see how much difference is still without the shadows disabled and track down the changes needed too.

hybridherbst commented 4 years ago

Shadows shouldn't have a giant impact (the 15% sounds reasonable) on URP. But on Quest the branches make the difference between "40-50fps" (as you were seeing) and "butter smooth 72fps" (on the above linked version from @De-Panther).

Note that ultimately there are a lot of optimizations on Unity end (both core and on project side) for this - big improvements probably would be

  1. single-pass instanced support (have you talked to Unity's XR / WebGL teams about that?) - this is approx. a 30-50% speed improvement
  2. FFR (fixed foveated rendering) on Quest - there seems recent movement on that here: https://github.com/immersive-web/layers/pull/145 (original discussion here https://github.com/immersive-web/layers/issues/2) - this is a 20-40% speed improvement depending on content and strength of foveation
  3. custom version of the URP that strips out all unnecessary passes - current URP is still not really ready for Quest dev because of this, for our Unity-based Quest apps we have a URP fork that does that.
De-Panther commented 4 years ago

We are investigating right now what was the big boost in performance on the fork. I thought that it was related to the communication between the browser and the Unity build (WebAssembly), but it seems that it's related to some basic optimizations I made to the Desert scene. Also the fork uses the Legacy RP instead of the URP.

Single pass is something that would really help. As far as I know it'll require the Unity XR SDK.

FFR on Quest. I thought it's only for apps, not for the browser. Depends on how many changes there need to be done to the WebGL pipeline, it might not be available for the WebXR Exporter. But I can't find much info about it. Only found info about "Multiview WebGL Rendering". I'm not sure if it's related to FFR. https://developer.oculus.com/documentation/oculus-browser/browser-multiview/?device=QUEST

I don't know much about the URP, I didn't use it in the fork because it'll just add more weight to the final build size. And I also didn't want to be bound to it. It's more easy to add URP instead of removing it IMO. (Also less options to check. Currently I try to test builds on couple of platforms, adding to that tests for with/without URP would take more time). So in your opinion Legacy is better for VR? Or should we use custom URP?

hybridherbst commented 4 years ago

I think Unity XR SDK shouldn't be too hard to add; if you want I can provide a basic framework for "how to make a custom XR Plugin" and you could fill in how the data gets received from the js libs?

FFR on Quest is for rendering in general; regarding this PR it seems that this will probably take a while for WebXR (if I understand the process right, Immersive Web XR has to accept it, then at some point Oculus browser user-agent would need to respect the setting), so there's not much that can be done on that end right now.

Regarding URP: a well-configured URP is definitely faster than Built-in pipeline (we're seeing between 20% and 200% performance improvements in our Quest Unity apps - the former for unlit scenarios, the latter for multi-light scenarios with shadows - the more complex the scene the higher the improvements), but I agree about the filesize. I can try to make a build with optimized URP over the next days so we can compare. Would you say your fork is the better starting point for that, or master?

De-Panther commented 4 years ago

As far as I know, you need to contact Unity to get the XR SDK. Without it you are limited with what can be done. You can create a framework similar to the XR Providers Packages, but you won't be able to define the nodes and enable features like single pass. https://twitter.com/Amel_negra/status/1234459025426780160

Well, so we'll have to wait for FFR 😃

That sounds awesome. The choice is yours, but we are trying to figure how to improve the frame rate here. So I think that this repo would gain more. Thanks :)

malDuffin commented 4 years ago

Nice work on the AR support - have those changes been ported back to the main branch, and how can I enable it?

De-Panther commented 4 years ago

@hybridherbst did you have any success with URP? I tried URP in my repo and I got 50 FPS instead of 72 FPS on the Oculus Quest... But I'm not familiar enough with URP so I might set things wrong.

hybridherbst commented 4 years ago

Didn't get to it but it's still on my list, sorry. Which exact Unity + URP combination did you try so I have a baseline? Most released URP versions aren't really suited for Quest (there's custom modifications needed currently).

De-Panther commented 4 years ago

@hybridherbst Unity 2019.3.0f6 and URP 7.1.8 or 7.2.1. Thanks