I have notice that setting the maximum Simultaneous Tile Loads anything higher then 5 for VR really impacts performance. Both for PC and especially mobile VR like the Meta Quest. I get massive frame spikes. Is there a way we can move the terrain loading off of the main update thread? In Unity there are asynchronous coroutines that process off the main update thread. Is there a possible way to do the tile loading using coroutines?
Actually, terrain loading already happens off the main update thread! All the requests and decoding happen on a worker thread. Besides, using coroutines for this wouldn’t actually help us out that much. Coroutines don’t actually process off the main update thread! They are essentially just “interruptible” functions - you do some work and then give control back to Unity, and Unity comes back and lets you do more work the next frame. The link in your post describes more about how this works.
Unfortunately, part of the issue is that some tasks have to take place on the main thread. Operations like creating textures, meshes, and instantiating GameObjects need to take place on the main thread, as is the case in many other game engines. So once the worker thread operations are done, Cesium Native calls out to Cesium for Unity to perform the main thread loading. There is a time budget here, so the main thread part of loading is limited to a maximum time per frame, but it just can’t be avoided.
If you’re experiencing frame spikes when raising the number of Simultaneous Tile Loads, this is to some degree to be expected! It’s a trade-off between loading speed and performance. More simultaneous tile loads means more work to be done by the worker thread and the main thread, but with the result that tiles load quicker. Even with some of this work being done by the worker thread, it doesn’t come for free - it’s up to the operating system to decide how to schedule work on threads, and more work for the worker thread could mean slowing down other threads that the operating system, unity, or other processes use, which could ultimately bring down performance.
Ok, thanks @azrogers for the reply.
Sounds like a lot of engineering has already gone into this issue. I have noticed the spikes are worse in VR mode. When in normal desktop mode (outside of VR), the spikes are not really noticeable. Perhaps there is something strange with VR rendering going on? I am using the XR Origin (XR Rig) from the XR Interaction Toolkit. I have settled on 5 for Maximum Simultaneous Loads for the Meta Quest which is pretty low. It takes a while (30 to 60 sec) for the tiles to fully load. It would be nice to have it load faster without a bunch of stutters while moving / flying around. I think this is the main bottleneck for XR applications at the moment. If there is anymore optimizations to be made on this problem, that would be amazing. Not that Cesium is already an amazing technology Thanks for taking the time to explain the issue.
Good to hear that the architecture is sound, and that you have thought about this. However, there are (as mentioned by 5DRealities) problems with stuttering on XR (I use Meta Quest 3) if simultaneous loads are higher than about 5 (I use the Google 3D tile set).
Is there a way to explicitly (in the API) set the mentioned time budget, so that we can decouple this from the number of “simultaneous loads”? I would like to download more than e.g. 5 tiles at a time, but if some downloads finish at the same time I would like the loading of textures/meshes to not produce a (too large) drop in framerate.
Just noting this thread as well that has to do with stutters on mobile hardware / Meta Quest VR: VR app hangs per milliseconds while loading tiles