17-03-2018, 01:20 PM
(This post was last modified: 17-03-2018, 01:24 PM by josemendez.)
(17-03-2018, 03:05 AM)CageyKG Wrote: Are there any general guidlines or tips to follow in order to reduce Obi Rope’s CPU footprint? Obi currently more than halves my framerate when simulating and I’m looking to get it back down to acceptable VR speed. It seems like most of it comes from updating obi colliders (ObiSolver.FixedUpdate.UpdateColliders is around 30% of frame’s total time.) I’ve been pretty fast and loose with adding obi colliders around since a lot of the game is very up close to the ObiRope cables and I wanted them to interact well with things inside the VR space. Do I need to be more sparing with these?
The other large chunk comes from rendering with ObiSolver.LateUpdate…ObiRopeThichRenderMode.Update being another 25% of my frame’s time. Smoothing seems like the main culprit (drops to aroung 7% when changing smoothing from max 3 down to 0), but decreasing it doesn’t have pleasing results. Should I be using higher cable resolution or some other method to achieve less angular cables instead?
It’s also a huge multiplier on the physics update, increasing it by at least 2 times when the solver is enabled, sometimes more (running on a timestep of .01 with the default 6 solver iterations). Is this just part of the deal when it comes to running this solver, or does it seem like that should be reducable somehow as well?
The scene in question has around 20 cables with an average of around 15 particles each, 4 pins constraints each, hierarchical tethers, and full smoothing/rendering. The solver is set to skip skin, volume, stitch, and density, but does everything else on Sequential settings with 5 iterations. Solver reports that it’s only using 466 particles total, which seems well within a reasonable range, hence my looking elsewhere for spots to improve performance.
Hi there!
ObiColliders are not completely free in terms of performance. If they're static they add a very small overhead, but many dynamic ones will noticeably hinder performance. All ObiColliders perform a check every frame to see if their transform or any of the collider properties (size, axis, etc) has changed since last frame. This is relatively cheap as it is just a handful of booleans.
However if the check determines the collider has changed since the last frame, Obi's internal hierarchical collider structure must be updated. For this you pay the cost of interop (C#->C++ data transfer) and a few moderately expensive math operations.
We've tested up to around 3000 static colliders and 100-150 dynamic ones. How many are we talking about in your scene?
Also, smoothing the rope mesh can be a bit costly. Each smoothing level roughly doubles the work needed to render the rope, as the amount of vertices in the rope increase. Note that the default rope section has 8 vertices, you might be able to get away with a simpler section (6 or 5 vertices) while maintaining performance at the cost of slightly less round rope. If you can afford the slightly less appealing visuals, switching to line rendering mode and using a material with an appropriate normal map (such as the included LineRope material) will greatly improve performance too.
Rope rendering in general is extremely well optimized, using a direct smoothing scheme instead of a recursive one, and allocating memory only when necessary, so I doubt huge gains can be obtained from here.
Regarding the simulation itself, make sure you're not running into a spiral of death-type situation. Use the profiler to make sure FixedUpdate() is being called only once or twice per frame, if not, keep the max fixed timestep as low a possible (ProjectSettings->Time). This video might help:
https://www.youtube.com/watch?v=sUVqa-72-Msç
Also, if you're using 3.3 or higher, you can also increase the global timestep and add a couple substeps to the ObiSolver instead. This will allow Obi to run at a higher frequency than the rest of the physics.
cheers!