You are browsing as a guest. Sign up (or log in) to start making projects!

1h 36m 8s logged

FaceFall — Devlog #2

2026-07-04 — The cloth was invisible the whole time

This update started with one simple bug report:

“the cloth barely renders and it keeps clipping into the model.”

It turned out to be three completely different problems.

By the end of today I’d rebuilt the renderer, rewritten parts of the collision system, doubled the maximum cloth resolution to 128x128, added adjustable cloth and collider sizes, and accidentally made the entire simulation explode into NaNs.

The invisible cloth

At first I assumed the renderer or lighting was broken.

It wasn’t.

The real problem was raylib’s batching. I disabled backface culling before submitting the cloth geometry, but re-enabled it before the batch was actually flushed to the GPU. The simulation itself was perfectly fine, but almost the entire cloth was getting backface-culled before it ever reached the screen.

The fix was simply flushing the render batch before and after changing the GPU state so the cloth was actually drawn with culling disabled.

While I was there I also rewrote the lighting. Instead of flat shading per quad, the cloth now generates smooth per-vertex normals and uses simple Gouraud shading. The difference is huge, especially on higher resolutions.

The clipping bug

The second issue was much harder.

The first problem was that my collision shell was far too thin. At lower resolutions the particles stayed outside the collider, but the rendered surface between them could still cut straight through the mesh. I fixed that by scaling the collision shell with particle spacing so coarse cloth stays slightly further away from the surface.

That solved part of it.

The bigger issue only showed up against thin meshes. Sometimes a particle could move completely through the object in a single step, and because the collision system only looked at the particle’s final position it would happily push it out of the wrong side.

The solution was switching to continuous collision detection. Every particle now stores its previous position, and I sweep that movement against the mesh instead of only checking where it ended up.

The explosion

My first implementation of continuous collision looked perfect.

For about three seconds.

Then the cloth completely disappeared.

It turned out I had created an energy feedback loop where particles bounced between both sides of thin geometry until the simulation exploded into NaNs.

Instead of pushing particles to a new position after a collision, I now simply restore their previous valid position and remove the inward velocity. It’s slightly more conservative, but completely stable.

Bigger simulations

With collision working properly again I increased the maximum cloth resolution from 64x64 to 128x128.

That pushed the simulation to over 16,000 particles, nearly 100,000 springs, and roughly 32,000 rendered triangles.

To keep performance reasonable I added a simple spatial grid for mesh collisions so particles only test nearby triangles instead of the entire mesh every substep.

The result is still effectively real-time, even at the highest resolution.

New settings

The settings menu also picked up a couple of new options:

  • Adjustable cloth size
  • Adjustable collider size

Changing either one rebuilds the simulation immediately, updates the collision data, and automatically reframes the camera so everything stays visible.

Current state

FaceFall is finally starting to feel like a proper tool rather than just a physics demo.

The renderer looks significantly better, collisions are much more reliable, larger simulations run comfortably, and exporting deterministic comparison clips is now almost entirely hands-off.

There’s still plenty left to do, especially around self-collision, but it’s getting much closer to the project I originally imagined.

0
11

Comments 1

@water

peak project twin!! keep it going!