Compliance an XPBD cloth lab

Grab the cloth, pin it, cut it. Then change the solver from XPBD to PBD and drag the substeps slider: one of them keeps the same material, the other quietly gets stiffer. The panel at the bottom runs both solvers against closed form predictions while you watch.

solver XPBD particles 0 links 0 worst stretch 0.0%

Prove it

The same solver that is drawing the cloth, run headless on a single hanging mass until it rests, and compared against two closed forms derived by hand. Every cell is the measured rest stretch in millimetres; the number under it is the prediction.

What is actually happening in there

Every frame is chopped into substeps pieces of length h. In each piece, every particle is moved by gravity as though nothing were holding it, then the constraints pull the positions back, then velocity is read off the position change rather than integrated separately. That last part is what makes it "position based": there are no spring forces anywhere in this file.

A distance constraint says C(x) = |x1 - x2| - L = 0. Plain PBD just moves the two ends until C is smaller, scaled by a stiffness factor between 0 and 1, and repeats. That is a relaxation, so how stiff the cloth ends up depends on how many times you relax it. XPBD instead carries a Lagrange multiplier lambda for each constraint, resets it at the start of every substep, and updates it by

dlambda = (-C - alpha_tilde * lambda) / (w1 + w2 + alpha_tilde)
alpha_tilde = alpha / h^2

with alpha the compliance in metres per newton, the reciprocal of stiffness. That h^2 is doing all the work: it is exactly what cancels the substep length out of the answer, so a hanging mass settles at m * g * alpha whatever you set the solver knobs to. Set alpha to zero and you get a perfectly rigid constraint and the arithmetic collapses back to PBD with a stiffness of 1.

Bend and shear links are given larger compliance than the structural ones, at fixed ratios off the one softness slider, which is why the cloth folds more easily than it stretches.

The number in the corner is the honest one. "Worst stretch" is the largest strain on any structural link, and on a static hanging sheet it should be about 0.69% at these settings: the pins are carrying eight kilograms through links that are stiff enough to barely notice it. At 4 substeps and 1 iteration the same sheet reads 40%, not because it is stretching but because the solver has not caught up. Measured here, at 600 settled frames each: 4x1 gives 40.5%, 8x2 gives 6.7%, 16x2 gives 2.1%, 32x4 gives 0.72%, and it stops moving at 0.685% somewhere past 32x10, which is around 700,000 constraint projections per frame. That residual is the cost of Gauss-Seidel, not of XPBD: the single mass in the lab converges in one pass because it has nothing to be coupled to.