Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Tips for improving performance?
#1
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.
Reply
#2
(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!
Reply
#3
Thanks for the info! I definitely do have a spiral-of-death problem happening; FixedUpdate gets called on average around 7 times per frame and only gets worse from there when I add characters to the scene. Reducing my maximum time step certainly helps, but limiting it down to 2 or 3 produces very slow and undesirable physics (and even slows my character animations down for some reason that I haven't figured out yet) so I'm at a bit of a loss there. Will have to keep poking around to see if I can get around that any - running Obi at higher timesteps helps with it for the cables, at least.

I'm reluctant to reduce the rope smoothing too much, since these cables are pretty much right up in the VR player's face all the time, but I'll play around with lowering it and maybe reducing the rope resolution some. I used to do the line renderer + normal map when I was rendering my own cables it found it not *too* bad, so maybe I'll switch back to that, too.

In my worst (and only!) scene I currently have 181 ObiCollider objects, 105 of which are not on static objects. This number can get larger depending on how many cables get added to the scenes at runtime, but not by an order of magnitude, and I'll certainly have to cap cable count at some number. If 150 dynamic colliders is the upper end of your stress testing, then it maybe my experience of 20-30% spent on updating those is roughly around what's expected? I'll have to see about trimming some of those down; I'm sure not all of them are necessary, and many of them are on primitives that are part of larger compound colliders that maybe don't need to interact with obi at *all* points.

Thanks again for the info! Cleared up my (apparently common) misconception around FixedUpdate/max timesteps, too.
Reply