2
$\begingroup$

I am experiencing some weird issues related to Cloth physics in Blender. It does not work correctly when the cloth object has some specific locations. Exact steps to reproduce the error are given below. Moreover, this seems to be a bug right from version 3.3 to the most recent 4.0 - I am surprised how such a basic thing was missed out always. I saw similar reports from others, without very well documentation, and none of them had any proper solution.

The same cloth physics without any change seems to again work when the object is moved to a different location. I could not establish any specific pattern between the location and the working/non-working status, but changing the location randomly solves the issue - although temporarily. If we again move it back to the previous location, cloth physics again stops working.

Exact steps for others to reproduce the error (we will discuss only about version 3.6.1 which is the most recent official release):

  1. Start with the default scene and delete the default cube.

  2. Add a plane, change X-rotation to 90 and Y-location to -2 (minus 2).

  3. Go to edit mode, right-click and subdivide, set subdivision level to 6.

  4. Select only the top-left & bottom-left vertices (blend file is attached for reference).

  5. Create a new vertex group and assign the selected vertices to this vertex group.

  6. Back to the object mode, add cloth physics with all default options.

  7. Enable self collisions, and select the above vertex group in the Pin group.

  8. Now run the simulation, or bake it and run. The cloth physics does not work.

  9. Now change the Y-location to zero. Cloth physics starts working after a few frames.

  10. Again change the Y-location to minus 2. Cloth physics stops working like before.

A blend file is attached here for your quick reference. If someone knows a solution for this, or even a work-around, it will be very helpful for me. I need to create flags in many different locations, and they should work irrespective of their locations.

$\endgroup$
12
  • 1
    $\begingroup$ THere are no Blender programmers here and no-one here has any association with the Blender Foundation. If you think you've found a bug you should report it through the official Help > Report a Bug route in Blender. $\endgroup$
    – John Eason
    Aug 10, 2023 at 16:18
  • $\begingroup$ @JohnEason Yes, I already reported this to Blender. Additionally I posted here, just in case someone knows about a work-around, or any other suggestion. My work is completely stuck due to this. There has to be some workaround, since it is so basic in nature and it seems to exist from very old versions till date :( $\endgroup$
    – Jeet GT
    Aug 10, 2023 at 17:22
  • $\begingroup$ Has it been confirmed as a bug? - They're pretty quick to triage bug reports nowadays. $\endgroup$
    – John Eason
    Aug 10, 2023 at 18:12
  • $\begingroup$ Not yet, still in "Needs Triage" status. But it has been just a couple of hours, so I am hoping something by tomorrow. Here is the link to the bug report: projects.blender.org/blender/blender/issues/111013 $\endgroup$
    – Jeet GT
    Aug 10, 2023 at 18:22
  • 1
    $\begingroup$ They are quite clear as to why it isn't considered to be a bug so I think you'll be out of luck: "Moving the mesh introduces larger floating point errors that introduce this noise into mesh. As far as solver is concerned, the piece of cloth is so stiff and flat, that it supports itself. The issue reported here is a request for modified behavior and not a bug in current behavior. this bug tracker is only for bugs and errors." $\endgroup$
    – John Eason
    Aug 14, 2023 at 9:31

1 Answer 1

2
$\begingroup$

This is not a bug of the cloth simulation. You are running into some special kind of numerical issue which gives you a false sense of works vs. works not. First lets state that the flag positioned at the world origin should not collapse.

Why should it not collapse?

You designed the flag to be perfectly flat, upright and oriented parallel to the XZ-plane a.k.a. the global Y-axis. Regarding the Y-axis, it has zero dimension. This is a physically idealised object which can't exist in the real world in this perfection. But the solver doesn't care. He happily applies gravity which points downwards (hence no forces spreading into the Y-axis direction) and all the cloth springs will only act within the XZ-plane. If the flag is stiff enough, it will support itself with some constant tension. Even if the stiffness is too low, the flag should bend only in the XZ-plane.

So why does it actually collapse?

Because it's not perfectly flat. There is a rotation applied on the flag to make it upright and this rotation, when evaluated causes numerical rounding errors to the vertices' coordinate values. A little caution has to be taken to see that in Blender: apply the rotation and then print the y-coordinate value of the vertices directly (printing the whole vector does not show enough digits, e.g. <Vector (-0.7143, 0.0000, -1.0000)>)

for v in bpy.data.objects["flag"].data.vertices:
    print(v.co[1])

This gives:

4.371138828673793e-08
4.371138828673793e-08
-4.371138828673793e-08
-4.371138828673793e-08
-3.1222420204812806e-08
-1.8733452122887684e-08
-6.2444835968733514e-09
...

These values are very small but not zero. Looking at the "working" cloth simulation one can observe that at the beginning the flag supports itself and only after some frames starts to collapse. This is because the springs -due to the non-zero values- now have room to act into the Y-axis direction and at some point the numerical errors accumulated enough to make a difference.

enter image description here

Now the fun part: if we zero out the y-values explicitly again and run the simulation, it will behave like explained above and not collapse (even with all Stiffness and Damping options zeroed out, the flag will not make an inch into the Y-axis direction).

enter image description here

So why does it "stop working" if we move the plane away? Because the non-zero values are so small, that adding a small (but bigger) y-value cancels out the last digits so that the y-values converge to a constant value (if they are all treated as, say $1.0$, then we have basically the same situation as if they were all zero). In the following image, the flags have y-value locations of $0$, $0.01$, $0.02$, $0.05$ and $0.1$. Note how the flags take longer to collapse the farther away they are from the origin because the differences in the y-values are getting smaller and thus need more time to accumulate until collapse. $0.1$ is big enough to cancel out all other digits already, so we got a perfect flat flag again.

enter image description here

Note: moving the non-perfect flag along the X- or Z-axis makes no difference, its all about the zero-dimensioness in the Y-axis direction (you could observe the same if everything would have set up in the X-axis direction).

Therefore, the solution is to add noise to the springs, so they can act in all dimensions resembling a more real world like object. Moving one vertex a little is enough to trigger collapsing, but adding some average noise over the whole object seems more natural. One could use Mesh > Transform > Randomize with a visually not noticeable value for the job. Note that when you are far away from the world origin, the noise value also might have to be bigger for the same rounding error reasons. In the image there are the flags with $0$, $0.01$, $0.02$, $0.05$, $0.1$ again and another at $2$ from your inital setup. Randomize value is $0.001$ and the cloth simulation engine is your friend again :

enter image description here

Addendum:

The numerical rounding error behaviour is based on the fact that floating point numbers cannot represent any number but only a discrete subset (check out "Why 0.1 + 0.2 != 0.3 in most programming languages" if you are curious) and only have some consecutive digits for precision (for float it's around 7). Closer to zero, the representable numbers are denser, hence a better precision in calculations. This is the reason why one should be always not too far away from the origin when modeling/simulating and so on.

$\endgroup$
4
  • $\begingroup$ Thank you so much for taking your time to explain the dynamics behind the working/not-working cases. Really appreciate that! However, it only proves that the cloth solver is doing the correct mathematics (or as correct as possible). I have never contested that. A bug in a software does not always have to be in the code, it may be in the design as well. It is a fair expectation from the user that cloth physics on any flat object should work. The imperfections that are necessary at times can be added by the cloth physics itself, improving the user experience and making this physics more robust. $\endgroup$
    – Jeet GT
    Aug 16, 2023 at 11:12
  • $\begingroup$ I have to disagree: "It is a fair expectation ... that cloth physics on any flat object should work." It does work as i have shown you, not just the way you want it to work. If you want it to behave like a 3D object, design it as such. I expect the physics to produce a self-supporting flag if it is perfecly flat. If the engine secretly adds imperfections, i would conclude its not robust. In fact, physic engines tend to explode due to necessary linearisations and effort has to be made to avoid that. The perfect flat flag not collapsing actually shows that the physics are well made. $\endgroup$
    – taiyo
    Aug 16, 2023 at 18:04
  • $\begingroup$ Don't get me wrong, i am not against improvements, to the opposite. People will look at that now (hopefully). But this is still not a bug. Adding a slider for imperfection in your bug report (they confirmed a known issue btw, not a bug) is a nice idea to improve user experience for the unwary. But that should not be the default in the physics engine, why? Tbh, I don't see how the solutions given are only "workarounds" for you, they do the same as you propose (as far as i can tell). But they are not imposed on the user or the engine if not necessary. $\endgroup$
    – taiyo
    Aug 16, 2023 at 18:39
  • $\begingroup$ In my bug report, I have explained why it is better to have an option to add imperfections in the physics itself than leaving it up to the user to do a trial-n-error thing every time such needs arise. But I think the main point of our disagreement is this: We don't have anything in the real world that is self-supporting (standing straight against gravity & wind) - but at the same time a zero-thickness object also does not exist in the real world - so we are dealing with an imaginary object here & our expectations are different. So an optional input for imperfection can make both of us happy :) $\endgroup$
    – Jeet GT
    Aug 16, 2023 at 21:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .