Rig weld: decide weld pairs once at rest pose (per avatar, on outfit/shape/LOD change); per-frame pass only averages the pairs #641

Closed
opened 2026-10-10 12:06:02 +00:00 by sky_line · 2 comments
Owner

Idea (owner, 2026-10-10)

Decide rigged-mesh weld pairs once, at the avatar's rest pose, and apply them cheaply every frame. Today the weld rediscovers the same pairs every frame.

Today

clean_rig_weld.comp / llcleanrigweldvk.cpp runs after pre-skin every frame:

  1. Hash ~43k boundary vertices by skinned position (boundary vertices live 42951).
  2. Search neighbouring cells for vertices of other meshes of the same avatar within RenderVKRigWeldDistance (0.2 mm).
  3. Average the matches.

Steps 1-2 are most of c_rigweld (~0.5-0.7 ms in a ~62-avatar crowd).

Do

  1. Pair discovery, once per avatar: skin each rigged mesh with the bind/rest pose including the avatar's shape (fitted mesh / collision volumes / joint offsets), on the GPU. Find cross-mesh boundary pairs within the weld distance. Apply the #626 rule: only pair vertices whose skin weights are similar (same dominant joints, weights within a tolerance), so cavities and onion-skin layers aren't welded. Store a compact per-avatar pair list (vertex index pairs + mesh ids).
  2. Per frame: a tiny gather pass after pre-skin averages each pair's position (and normal) from the skinned output. No hashing, no search. Expected ~0.05-0.1 ms for the same vertex count.
  3. Recompute asynchronously only on: attach/detach, wearable/outfit change, appearance/shape change, rigged LOD switch (#561/#612), rig weld setting changes. Until the new list is ready, keep the old one or skip welding; never stall.
  4. Keep meshes separate. Merging gives no per-mesh saving: draws are GPU MDI with per-face materials, pre-skin and refit are per-vertex, RT is already grouped. It would also break per-attachment hide/LOD/alpha/detach.

Behaviour change

Pairs are fixed by how meshes meet at rest instead of per pose. Real seams (neck/head, wrists/hands, clothing edges) meet at rest and stay joined. Accidental pose-dependent welds go away.

Measure

c_rigweld before/after in the same crowd; pair count and recompute count/time in the VKRigWeld log line. Visual: neck/wrist seams under animation, cavities (mouths, pockets), layered clothing.

Absorbs #626 (weight-based weld). Related: #574, #632.

## Idea (owner, 2026-10-10) Decide rigged-mesh weld pairs **once**, at the avatar's rest pose, and apply them cheaply every frame. Today the weld rediscovers the same pairs every frame. ## Today `clean_rig_weld.comp` / `llcleanrigweldvk.cpp` runs after pre-skin every frame: 1. Hash ~43k boundary vertices by skinned position (`boundary vertices live 42951`). 2. Search neighbouring cells for vertices of *other* meshes of the same avatar within `RenderVKRigWeldDistance` (0.2 mm). 3. Average the matches. Steps 1-2 are most of `c_rigweld` (~0.5-0.7 ms in a ~62-avatar crowd). ## Do 1. **Pair discovery, once per avatar:** skin each rigged mesh with the bind/rest pose *including the avatar's shape* (fitted mesh / collision volumes / joint offsets), on the GPU. Find cross-mesh boundary pairs within the weld distance. Apply the #626 rule: only pair vertices whose skin weights are similar (same dominant joints, weights within a tolerance), so cavities and onion-skin layers aren't welded. Store a compact per-avatar pair list (vertex index pairs + mesh ids). 2. **Per frame:** a tiny gather pass after pre-skin averages each pair's position (and normal) from the skinned output. No hashing, no search. Expected ~0.05-0.1 ms for the same vertex count. 3. **Recompute** asynchronously only on: attach/detach, wearable/outfit change, appearance/shape change, rigged LOD switch (#561/#612), rig weld setting changes. Until the new list is ready, keep the old one or skip welding; never stall. 4. **Keep meshes separate.** Merging gives no per-mesh saving: draws are GPU MDI with per-face materials, pre-skin and refit are per-vertex, RT is already grouped. It would also break per-attachment hide/LOD/alpha/detach. ## Behaviour change Pairs are fixed by how meshes meet at rest instead of per pose. Real seams (neck/head, wrists/hands, clothing edges) meet at rest and stay joined. Accidental pose-dependent welds go away. ## Measure `c_rigweld` before/after in the same crowd; pair count and recompute count/time in the VKRigWeld log line. Visual: neck/wrist seams under animation, cavities (mouths, pockets), layered clothing. Absorbs #626 (weight-based weld). Related: #574, #632.
sky_line added this to the Slipstream project 2026-10-10 12:06:02 +00:00
Author
Owner

Started 2026-10-10 together with #632.

Started 2026-10-10 together with #632.
Author
Owner

Shipped in 1.3.0 Beta 2: rig weld pairs are decided once per avatar at the rest pose, and the per-frame pass only averages the pairs.

Shipped in 1.3.0 Beta 2: rig weld pairs are decided once per avatar at the rest pose, and the per-frame pass only averages the pairs.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#641
No description provided.