Hello! I’m looking for advice or general tips for improving framerate and performance of ragdolls in Maya. I’m currently working with a ragdoll that needs to animate at 60fps consistently, but is experiencing drops to ~30fps after a few minutes of working with the rig. There is nothing else in the scene, and the rig is referenced in.
I’ve optimized the ragdoll as much as I currently know how, via:
Using as little mesh islands on the custom ragdoll geo as possible
Using the default capsule mesh shape where possible
Setting the Solver’s substeps to 2 and iterations to 4
Ensuring that no Stiffness or Damping or other ragdoll attribute is set to an unreasonably high or negative number.
Are there other ways I can optimize the ragdoll? It’s impossible to preview it realistically at 30fps.
I’m also wondering if this ragdoll is setting itself to Serial evaluation instead of Parallel due to a cycle error? I have a string of capsules coming from the back attached at the end to the ragdoll’s arm via an Attach constraint, which I’m wondering could be causing a cycle error? Is this possible?
This is as challenging of a question as one regarding plain Maya rigs, and the answer is typically the same; it depends.
But before diving into specifics, generally speaking:
Less Markers mean less work
Markers are limited by what they are assigned to, e.g. the rig. Markers need to compute the rig to know where to go, so any work is work added on top of that cost
Less contacts mean less work
Permanent self-intersections can generate unnecessary contacts
Scene Scale being too large or to small
(4) is something that would cause a major slowdown and could easily be avoided without consequence. It can also easily happen, so is worth looking out for. When two markers are intersecting and cannot escape each other, a contact will be generated each frame and will eat up on your solver iterations until it runs out, always running the maximum number of them. (The solver Iterations attribute is a max count, typically finishing prior to whatever number you give it)
(3) is true, but generally fades in comparison to Marker count and assignee complexity. You can avoid collisions by using spheres and capsules in favour of boxes and meshes; keeping a sphere on the ground requires just 1 contact, whereas a box requires 4. A bit counter-intuitive to think that a box is more expensive than an infinitely smooth sphere, but such is physics.
(1) and (2) is generally your main culprit for performance.
As an experimental solution for (2), and one being incorporated into Ragdoll 4 as we speak, would be to disconnect the inputMatrix of Markers you know won’t need to follow the input animation, and to set this attribute manually if/when the start pose changes. For example, if you know that some backpack or pony tail is fine just following the static pose from the start frame, then updating this each frame is unnecessary work for Ragdoll. The inputMatrix is the attribute which queries your rig for a final position and typically involves having the whole rig compute itself. For example, for a Marker assigned to the hand, it would need to know the position of the rigged hand, which in turn needs the lower arm, upper arm, shoulder, and so on. Basically the whole rig, for just this one hand.
In general, Maya is smart enough to not re-compute the upper arm when the lower arm Marker then queries its input matrix, but explicitly disconnecting and preventing this from happening could/should speed things up. This also very much depends on the rig itself, as things such as scriptJobs or expressions can rob Maya from this level of “caching” and time savings.
(5) Is another easy win, but only so when done early. Changing it will have an impact on the simulation but it is important for performance. In a nutshell, Ragdoll tries to avoid the cost of contacts by discarding Markers that are clearly not going to collide. Such as two Markers that are far from each other and aren’t moving towards each other quick enough to come into contact at the next time step. The distance at which it considers it at a risk of contact depends on scene scale. A lower value for Scene Scale means this distance increases, and more work is done unnecessarily.
You can somewhat hack your way forward by making scene scale too large, and cranking up Gravity to compensate. But, performance also suffers if that distance is too small and it ends up trying to solve an intersection instead. So it’s a balance, that can be tuned.
At 60 fps, 2 substeps should definitely suffice. Substeps divides your playback, rate meaning that a playback rate of 60 fps with a substep of 2 is equivalent (but not identical) to a playback rate of 30 and a substep of 4.
Also wise. Values between 0-10 should have little to no impact on performance, but anything that eats up solver iterations would, and values in the thousands to millions definitely would.
There is no data flowing out of Ragdoll, other than when recording. So there could not be a cycle due to Attach Constraints or Markers. This must be coming from elsewhere. But depending on how it is attached (Parent Constraint?) it could definitely contribute to making the rig slower. This should also happen without Ragdoll, e.g. if you hide the solver or disable Plug-in Shapes in the viewport. Ragdoll won’t solve, but your rig would still run as normal.
This caught my eye. Do you mean that it does run at 60 fps at some point? What happens to make it drop to 30? Keyframing generally causes more evaluation on the Maya side, so this could be one cause. E.g. a static rig in T-pose would effectively be free to compute, whereas keyframes on e.g. the hip to move the entire character around would be more espensive.
If so, maybe try Maya’s own Cached Playback. It is meant to remove computation from rigs, and Ragdoll is meant to simulate on-top of it. However I say “meant” because it rarely works as advertised.
Specifics
I saved this for last, because I realise the challenge of trying to reproduce this on a smaller scale. But if you are able to cause a slowdown like the one you are seeing and upload a sample here, we’d be happy to take a closer look.
Hey @Hallie, just checking in to see whether any of this helped or if you are still stuck at 30 fps? I thought of one more thing you could try too, “Stepped Simulation”.
This would effectively skip simulation on every other frame, or more, which should save on performance. It wasn’t really intended for this usecase, but it might fit.
Thanks for checking in, and sorry for the late reply! I discovered that the scene scale was set very small, and fixing that did save a few frames, but the rig is still running ~30-40fps. I’m currently working with my and your team to send over the files for a more thorough investigation- hence the late reply.
Once we know the culprit I’ll post the answer for anyone else having this issue!