The **ObiSolver** component is arguably the most important component in Obi. It is responsible for simulating particle physics and enforcing constraints. Three important things
to remember about solvers:

- They can be added to any GameObject in your scene and there can be more than one solver working simultaneously in the same scene.
- Every actor needs to have a solver up its hierarchy in order to get updated and rendered.
- Each solver is completely independent from other solvers. Therefore, actors being updated by different solver won't interact / collide with each other. Only actors in the same solver will react to each other.

Solvers always perform the simulation in **local space**. This means that translating, rotating or scaling the solver will rigidly transform the simulation as a whole.

You can inject a percentage of the solver linear/rotational movement back into the simulation, in the form of inertial forces. For instance, you might want to control how much of the overall character movement will affect the clothing simulation. For this purpose, solvers expose two parameters to independently control linear and rotational inertial forces (see below).

The solver inspector is organized in 4 foldable panels, each one contains parameters affecting one specific aspect of the solver's behavior.

These settings control how the solver works internally:

Which simulation backend to use. If any given backend is not available, Obi will try to fall back to the Oni backend. See the backends page for more information.

The solver can simulate in 2D or 3D mode. In 2D mode, simulation only happens in the XY plane.

2D mode is usually coupled with the use of 2D colliders. However, you can also use 3D colliders together with 2D mode for convenience.

Interpolation mode used to render particles. *None* is faster to calculate, but *Interpolate* will give more visually pleasing results. However, *Interpolate* will introduce a **1-frame delay** between the actual physical location of particles and the position they're rendered at. Keep this in mind when using interpolation around other objects in the scene. If you have rigidbodies interacting with Obi, it is generally a good idea to either use interpolation for both, or not use it at all.

"Interpolate" works best for slow-mo effects, as it avoids stuttering when Unity's timescale is < 1.

Keep in mind that interpolation introduces a 1-frame delay. This is specially important to keep in mind when attaching actors to other objects.

Various global parameters regarding external/internal forces, such as gravity, damping, inertia, etc:

Whether to apply gravity in the solver's local space (**Self**) or in world space (**World**). If set to "Self", the direction of gravity will rotate together with the solver.

Direction and magnitude of gravity applied to particles in this solver, expressed in the solver's local space.

Any particle with a kinetic energy below this value will be freezed in place. This is useful when you don´t want minuscule variations in velocity or force to perturb an actor, making it look like its jittering or moving very slowly. Set it to zero if you want your particles' positions to be affected by any force that acts upon them, however small it may be.

Unlike asleep rigidbodies in most rigidbody engines, asleep particles are not taken out of the simulation and will not save performance. Their position is simply not updated.

Velocity damping applied to particle velocities. Increase it to reduce their kinetic energy.

High damping values can be useful to simulate underwater effects. Low non-zero values (eg. 0.15) can improve the realism of your simulation in most situations, accounting for aerodynamic drag.

Controls how much of the world-space linear inertia of the solver transform is applied to the particles. Values range from 0 (none) to 1 (100% of it).

Analogous to the previous property, but controls angular inertia (rotations) instead of linear inertia (translations). Note that **centrifugal** and **coriolis** forces are accounted for.

Fluid particles in Obi can be ellipsoidal in shape, instead of perfectly spherical. This is used to better adapt their shape to the surface of the object they represent, achieving more accurate collision detection and smoother rendering. Max anistropy lets you determine the maximum ratio between the ellipsoid's radii: a value of 1 will force all particles to be spherical (deactivates anisotropy), values larger than 1 will allow particles to become more ellipsoidal the higher max anisotropy is.

Fluid rendering can benefit enormously from enabling anisotropy (max anistropy > 1). It will allow you to use lower fluid resolutions and get a much smoother looking fluid surface.

Should this solver keep the simulation going when invisible to all cameras? Keep this enabled if your simulation needs to be updated at all times, disable it to improve performance when multiple solvers exist in the scene but they are not visible at all times.

These control the solver's collision detection pipeline:

Percentage of particle/rigidbody velocity used to expand their bounding box during collision detection. A value of 1 will use 100% of the velocity, resulting in full **continuous** collision detection. A value of 0 will result in purely **static** collision detection.

Margin added to particle bounding boxes (after CCD expansion), used when generating contacts. Any colliders/particles within the particle's bounding box will be considered for contact generation. This value should be kept relatively low. Large values will generate more contacts, which can improve robustness in very complex scenes, but will negatively affect performance.

Maximum velocity (in meters/second) applied to particles to take them out of a collider. This only applies to particles that **start the physics step already inside a collider**. Low values will gently take the particle out of the collider. High values allow the solver to take the particle out immediately, causing it to "jump" out of colliders.

High values will artificially increase the mass of particles supporting other particles. Use it to obtain better stacking stability.

Maximum amount of iterations performed to refine surface collisions.

Tolerance threshold below which surface collision refinement will stop. Increasing it a bit can help obtain more stable surface collisions against flat surfaces.

You can globally enable/disable each constraint type for all actors being managed by the solver. Disabling constraints this way (as opposed to disabling constraint components for individual actors) will allow the solver to completely skip any calculations related to that specific constraint type.

For instance, if you disable **collision constraints** and **particle collision constraints**, the entire collision detection pipeline is skipped.
This allows you to customize what's being done under the hood and get rid of unnecessary overhead.

ObiSolver exposes 4 parameters for each constraint type:

Are these constraints updated at all? By default all constraint types are enabled, altough this is rarely what you want for production-ready simulations. You should disable any constraints that are not critical for the final look of your simulation.

Some constraint groups will not reduce performance when enabled, if no actors are using them. For instance, **density constraints** are only used by fluids. So if no fluid emitters are present in your scene, enabling density constraints won't affect your performance at all.

How many times per substep should these constraints be evaluated? A high iteration count will keep the simulation closer to the ground-truth solution. Keep it low if these constraints aren`t very important for your particular purpose and you want to get better performance. The default is 3.

In some situations, it makes sense to crank the amount of iterations of a given constraint group way higher than 3. For instance, it is not uncommon to use **ropes** with a **distance constraints** iteration count > 15.

Determines how to enforce constraints of this kind. There are two modes:

- In
**Sequential**mode, all constraints are evaluated in the order they were created (which is determined by each specific ObiActor) and each constraint “sees” the adjustments made by all previous constraints. This ensures quick convergence, so your constraints will need few iterations to look good. However it is not very stable when several constraints are fighting for control -it will introduce jittering-, so there are some use-cases where this mode is not a good choice. It is**order-dependent**, so in low-budget situations (few particles, few iterations and/or large timesteps) this can result in visible patterns in particle arrangement. For those of you a bit on the technical side, this is a Gauss-Seidel type of solver. - In
**Parallel**mode, all constraints are evaluated but their adjustments are not immediately applied to the particles. Instead, they are stored, averaged, and then the final result is then used to adjust particle positions. This yields a very stable simulation even with lots of constraints applied at once, however more iterations are needed for “hard” constraints as it converges more slowly. It is also**order-independent**, so it ensures smooth particle arrangements. Use this mode if you want to trade performance -with high iteration counts- or quality -with low iteration counts- for stability and smoothness. Again, for technical users: this is Jacobi-like solving.

Parallel mode converges slowly and isn't guaranteed to conserve momentum (things can sometimes gain energy). So use sequential mode when you **can**, and parallel mode when you **must**.

The following images show a rope that's been stretched way past its rest length, using different evaluation modes for distance constraints. In **sequential** mode (left), a clumping pattern in particle placement caused by order-dependent evaluation is clearly visible. In **parallel** mode (right) all particles are evenly spaced, but the rope sags a bit more due to reduced convergence speed.

Here's another example: some rigidbodies on a trampoline. Cloth tension is mapped to a color gradient for visualization purposes. In **sequential** mode (left), tension is unevenly distributed over the cloth's surface, resulting in a noisy color pattern. In **parallel** mode (right) tension is evenly distributed, but the cloth is more elastic due to reduced convergence speed.

Successive Over-Relaxation (SOR) factor. When trying to satisfy constraints, one way to improve convergence is to “over-relax” the constraints. That is, if moving a particle 2 units to the left would satisfy the constraint for now, why not moving it 3 units? This is exactly what this factor is used for. 1 is the default value, which does not perform over-relaxation at all. 2 is the maximum, which allows you to perform twice as much (200%) relaxation on constraints. High values can be used to help speed up convergence in any of the two modes (sequential or parallel), but keep in mind that simulation stability can degrade. Values lower than 1 will only partially enforce constraints. For instance, with a relaxation factor of 0.25 constraints will only have a 25% of their normal effect.