Hey guys, I’m really stumped here. I’m in the process of creating an open-world title on the Quest 2, however even after two weeks of optimization I can’t quite understand why I can’t get over 60fps. I’m using URP and vulkan and my terrains are being streaming and instanced with a URP MicroSplat shader for performance. There is nothing in my scenes except for the terrain. I have 54 draw calls and 75k tris (I read an Oculus article stating the Quest two can handle between 200-300 draw calls for mid simulation, and 750k-1m tri’s, so what gives?)
In the editor’s playmode I get nearly 650fps, but when I run on the Quest 2 I get 60fps on the high side, and 40 on the low side with literally nothing going on. I ran renderdoc to see why my performance is so egregious and the only thing that stands out to me is vkCmdEndRenderPass taking 11ms. Is this what’s tanking my framerate? Is this normal?
Thanks for bumping. I’m gonna go ahead and attach what I believe could be the culprit. In the picture it looks like EarlyUpdate.XRUpdate is taking a whopping 47ms.
I’m up to date on the OculusXR plugin, so apparently I should see a new profiling marker labled “WaitToBeginFrame”, but it’s absent. So I’m one less clue down as to what’s really going on. But there’s no way a simply looking at an empty terrain with textures of 512x512 is taxing on the Quest 2.
I would love it if a Unity/Oculus developer could comment as to whether they believe this is a bug or still intended behaviour.
Gotta say I have terrible experience with Unity terrain and performance. Maybe try a regular mesh.
If you have the time, does OpenXR change performance? Or switching opengl and vulkan around? Stuff like multithreaded rendering, graohics jobs and single pass/multiview rendering etc can also help a lot.
The quest definitely has harsh vsync handled by the console itself
OpenXR doesn’t work for me. Apparently there’s a bug affecting it’s integration with the most recent Oculus plugin that should be patched soon. I’m using a low resolution, microsplat terrain which is actually incredibly performant, so I know the issue isn’t there. I’m using single-pass with multi-threading. Guess I’ll give graphics jobs a try, but I truly suspect the issue isn’t to do with any of my own implementations but rather the EarlyUpdate.XRUpdate
Vulkan is not going to be significantly faster than OpenGLES3.1 on Quest2
Terrain is slower than meshes, but more convenient to manage
Microsplat is probably a bit heavy for Quest2. It’s fast but not sure it’s 3k res mobile phone fast (what is?)
So your ideas right out of the gate for what is good for VR is a bit out of touch with what the hardware can do. I’d say it could use terrain and microsplat but you’d need to dump the following:
HDR, shadows and post effects. All of those must go. Also try to avoid writing and reading from the same render textures within the same frame (YMMV).
Please note: Quest 2 is getting a significant performance boost soon - up to 70% via AI (trained data) through what they call Space Warp.
So it’s worth developing but Vulkan is only going to save you some CPU time usually, and looks like you’re GPU bottlenecked - at a guess I’d say with tile resolve and bandwidth, two of the biggest offenders in mobile game development at high framerates.
I’m not quite sure that was your problem though. It was much more likely that Unity’s vulkan was bugged and slow before, so you’ve tested bad vulkan->good vulkan and not es3->vulkan.
There’s a little Unity could do on the GPU side with Vulkan that could be nice too, mostly in reducing the cost of handling HDR. But that’s a hard thing to do and still retain MSAA.