Hello, while developing some VR applications for the Vive, I’ve noticed a few cases where certain CPU intensive operations cause the VR scene to briefly fad away which brings you back to the SteamVR sample scene (The one that says This is Real in the sky and has the nighttime view of the earth overhead).
This happens when I, for example perform many operations in a loop that might take awhile to complete.
I’m guessing that the thread running my C# script gets so busy that the threads that render the image on the headset are unable to do their job and so the whole scene craps out for awhile.
Has anyone else seen this? I’m wondering if there is a way to possibly slow down the problematic C# operation in order to allow the scene rendering threads to do their job. I tried Thread.sleep in my C# loop, but that didn’t work. Does anyone have any ideas about how to handle these types of situations? It could be that I’m simply pushing Unity too hard, but I’m hoping there are some tricks to help with this kind of thing.
No tricks, just proper development. You simply have to identify the real cost of what you are doing first. Sort by Time ms, do what you can there and then eliminate GC.
Probably what you’ll need to do is break up whatever work you’re doing so it can be done over multiple frames. You don’t really want to hang the main thread by sitting in a loop in Update() for too much time.
For instance, if you’ve got some loop going from 1-10,000,000 with a huge workload in each loop, try doing 1-1000 on the first frame, 1001-2000 on the second, etc… Something like that.
Another option might to be to use threading so the main rendering thread can continue running, but it would probably be easier just to break things up per the above. Can’t say for sure without knowing what you’re doing though.
I don’t know anything about your setup, but it doesn’t quite sound like you understand how the threads in Unity work. It can get pretty in depth, but as a general explanation, there is the Unity Main Thread (CPU) and the rendering thread (GPU). These are separate threads, yes, but the rendering thread does need to wait for the Main thread to finish working each frame before it can present.
There are internal operations that happen on each thread that do not depend on each other that allow the threads to do some operations in parallel, but the rendering thread does need to wait for the scene to update before doing it’s work. All of your scripts execute on the main thread. Even coroutines are run on the main thread. Coroutines are separate, but behind the scenes they aren’t actually separate threads. Unless you actually call to create a New Thread, you are running on the main thread.
If you are running for Vive, you have 11ms per frame to split between the CPU and GPU, if you go over that amount, you will not hit frame rate and the experience will be choppy and unpleasant. If you are doing a lot of work on the CPU, try breaking it up like Todd suggested or in some other way.
Definitely do not use Sleep on the main thread though. That will pause the main thread from doing any work, thus preventing other threads from continuing if they depend on the main thread.