Skip to content
HN On Hacker News ↗

GitHub - xloveee/jiggle-physics: An open reference standard for jiggle physics: weight-painted regions + damped spring bones, one rule (vertex += weight * boneJiggle). Portable, dependency-free, WebGL demo included. By the xlovecam team.

▲ 52 points • 21 comments • by vesperance • 5mo ago • HN discussion ↗

Pangram verdict · v3.3

We believe that this document is fully AI-generated

99 %

AI likelihood · overall

AI
0% human-written 100% AI-generated
SEGMENTS · HUMAN 0 of 3
SEGMENTS · AI 3 of 3
WORD COUNT 841
PEAK AI % 99% · §3
Analyzed
Jun 6
backend: pangram/v3.3
Segments scanned
3 windows
avg 280 words each
Distribution
0 / 100%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 841 words · 3 segments analyzed

Human AI-generated
§1 AI · 99%

A reference standard for real-time jiggle physics by xlovecam — how to paint soft regions, drive damped spring bones, and deform meshes consistently across engines.

Not ragdoll. Not cloth. Not full soft-body FEM. Paint weight on a UV map, drive randomized spring bones from parent motion, one rule: vertex += weight * boneJiggle.

Author: xlovecam No build step. Open index.html in any WebGL-capable browser.

Also known as Spring bones · jiggle bones · soft-body secondary motion · weight-painted physics · vertex weight jiggle · Blender-style flesh bounce · mesh wobble · damped spring deformation · parent-velocity lag · orbit-driven bounce

The standard Two pieces, one contract:

Piece What it is

Weight map Per-region softness in [0, 1], painted on a UV texture (one weight per vertex in a real engine).

Jiggle bones A small set of damped springs; each painted region follows one bone. Randomized frequency/damping so regions wobble out of sync.

The entire deformation: vertex += weight * boneJiggle; In this demo (SDF ray-marcher), the equivalent samples the base shape at q - offset where offset = weight * boneOffset, with asymmetric squash & stretch along the motion vector (trailing bulge, leading flatten).

Architecture The engine and the renderer are separate by design. jiggle-physics.js does the math only — no DOM, no WebGL — so you can drop it into any renderer. This repo ships one such renderer (a WebGL demo in jiggle-app.js) to show the standard in action. jiggle/ ├── index.html # markup, styles, GLSL shader ├── jiggle-physics.js # pure simulation (no DOM, no WebGL) ├── jiggle-app.js # WebGL demo renderer (consumes the engine) └── asset/ └── jiggle-physics-demo.gif

jiggle-physics.js — simulation engine createJigglePhysics({ bones: 3 }) — drop into any game loop.

§2 AI · 99%

No DOM, no WebGL — renderer-agnostic; all WebGL lives in the demo, not the engine. Each bone is a damped spring driven two ways:

Impulse on parent acceleration (flicks, reversals, constructive interference). Velocity drive — sustained lag while the parent keeps moving.

Per-bone character: randomized stiffness, damping, coupling, and gravity sag. Returns bone offsets each frame:

const offsets = physics.update(dt, { yaw, pitch, body: { x, y, z } }); // Float32Array [x0,y0,z0, x1,y1,z1, ...] jiggle-app.js — the WebGL demo renderer This is one example renderer, not part of the engine. It owns the WebGL setup, orbit camera, UV weight painting, controls, and render loop. Each frame it feeds parent state into the engine and uploads the returned bone offsets + weight textures to the shader. index.html — the reference scene Five test geometries with demo presets, weight heatmap, physics sliders, and a 2D UV paint window.

Weight painting Weights live in a 512×256 RGBA texture (R / G / B = three jiggle bones). Each geometry uses a Smart-UV-style projection so paint maps cleanly to the surface:

Geometry Projection

Orb Sphere (equirectangular)

Capsule Cylinder along Y

Torus Major ring U + tube V

Air dancer Cylinder along swaying centreline

Walker Cylinder, seam at back

Paint in the 2D UV map panel (not on the 3D viewport). One texture lookup per sample — no brush cap, no per-step cost scaling. Controls

Input Action

P Paint mode — UV map panel appears

Paint in UV window Add weight (Blender-style flow build-up)

+ / − Add / erase brush

W Toggle weight heatmap (blue = anchored → red = soft)

G Cycle geometry

C Clear weights

X Random paint

Space Shake

R Reset camera

Drag Orbit (drives jiggle)

Shift-drag Move object (also drives jiggle)

Wheel Zoom

Region strength sliders Below the UV map — scale

§3 AI · 99%

painted regions after the fact without re-painting:

all — master gain on every painted region bone 0 / 1 / 2 — per-channel gain (each stroke assigns a bone in rotation)

Demo presets Each geometry loads a preset weight map on switch (G) that showcases the standard with multiple out-of-sync bones:

Orb — heavy sagging bottom + softer equatorial band Capsule — heavy hanging bottom cap + mid belly Torus — three lobes evenly spaced on the outer rim Air dancer — head-heavy stacked rings, feet anchored Walker — soft bust, glutes, groin

Physics sliders

Slider Parameter

stiffness spring constant

damping velocity damping

mass inertia

gravity sag under gravity

orbit drive how hard camera orbit drives jiggle

brush size UV paint radius

brush weight paint target strength

force radius jiggle spread from painted regions

Integration const physics = createJigglePhysics({ bones: 3 });

// each frame: const offsets = physics.update(dt, { yaw, pitch, body: { x, y, z } // parent object translation });

// per vertex in your mesh: const w = sampleWeight(vertex.uv); // from your weight map (0..1) const bone = sampleBoneIndex(vertex.uv); // which spring drives this texel vertex.position += w * boneOffset(bone); The weight map and bone index map are the portable assets. The physics engine is the portable simulation. Any renderer that can multiply and add vectors can implement the standard.

Running locally open index.html # or serve statically: python3 -m http.server 8080 License Use freely. Please attribute xlovecam and link to github.com/xloveee/jiggle-physics if you ship this standard in a project.