Vehicles: some parts not rendering #88

Closed
opened 2026-09-27 05:53:26 +00:00 by backspace119 · 4 comments
Owner

Reported: vehicles have parts that don't render at all. Cause unknown.

Repro details still needed

  • Parts missing while the vehicle is parked, being driven, or both? Do they appear when it stops?
  • Missing parts: mesh or prims? Alpha/blend materials? Tiny parts (wheels, glass, trim)? Flexi or animated-texture parts?
  • Same vehicle rezzed statically (not physical / not sat on) vs worn/driven.
  • Does it happen for other people's vehicles passing by, or only yours?

Hypotheses (to check in order)

  1. Active linksets / spatial bridges. A physical or driven vehicle becomes an LLSpatialBridge (active drawable). If the VK ingest or instance-transform updates miss bridge children, those parts vanish or freeze. Related: mMovedBridge / mPartitionQ never drain under VK (GL-A3, #48); the GLResidue counters (#45) show if they grow.
  2. Child transforms of moving linksets: instance transforms for child prims not re-uploaded when only the root moves.
  3. Frustum culling with stale bounds for moving objects (bounds not refreshed while moving; compute cull rejects them).
  4. Parity gaps that look like this: flexi parts (#25), glow on transparent parts (#26), alpha auto-mask (#82), sculpt aliasing (#44), invisiprims (#27).

Debug aids

RenderVKSectionLog GLResidue line (partQ / movedBridge); select a missing part (Edit) to check it exists and get its type/material.

**Reported:** vehicles have parts that don't render at all. Cause unknown. ### Repro details still needed - Parts missing while the vehicle is **parked**, **being driven**, or both? Do they appear when it stops? - Missing parts: mesh or prims? Alpha/blend materials? Tiny parts (wheels, glass, trim)? Flexi or animated-texture parts? - Same vehicle rezzed statically (not physical / not sat on) vs worn/driven. - Does it happen for other people's vehicles passing by, or only yours? ### Hypotheses (to check in order) 1. **Active linksets / spatial bridges.** A physical or driven vehicle becomes an `LLSpatialBridge` (active drawable). If the VK ingest or instance-transform updates miss bridge children, those parts vanish or freeze. Related: `mMovedBridge` / `mPartitionQ` never drain under VK (GL-A3, #48); the GLResidue counters (#45) show if they grow. 2. **Child transforms of moving linksets:** instance transforms for child prims not re-uploaded when only the root moves. 3. **Frustum culling with stale bounds** for moving objects (bounds not refreshed while moving; compute cull rejects them). 4. **Parity gaps that look like this:** flexi parts (#25), glow on transparent parts (#26), alpha auto-mask (#82), sculpt aliasing (#44), invisiprims (#27). ### Debug aids `RenderVKSectionLog` GLResidue line (partQ / movedBridge); select a missing part (Edit) to check it exists and get its type/material.
Author
Owner

Update from reporter: it does not affect all vehicles, only some.

That points away from a blanket moving-linkset/bridge failure (hypothesis 1 would hit every driven vehicle) and toward something content-specific: a particular prim/mesh type, material/alpha mode, flexi, sculpt type, texture animation, or linkset construction (e.g. very large link counts, child prims with scripted/local motion, llSetLinkPrimitiveParams-driven parts). Next step: compare an affected vs an unaffected vehicle - select a missing part in Edit and note its type (prim/sculpt/mesh), material (legacy/PBR, alpha mode), flexi, and whether it's animated by script.

**Update from reporter:** it does **not** affect all vehicles, only some. That points away from a blanket moving-linkset/bridge failure (hypothesis 1 would hit every driven vehicle) and toward something content-specific: a particular prim/mesh type, material/alpha mode, flexi, sculpt type, texture animation, or linkset construction (e.g. very large link counts, child prims with scripted/local motion, llSetLinkPrimitiveParams-driven parts). Next step: compare an affected vs an unaffected vehicle - select a missing part in Edit and note its type (prim/sculpt/mesh), material (legacy/PBR, alpha mode), flexi, and whether it's animated by script.
Author
Owner

More evidence: on the affected vehicle the doors were missing but eventually appeared; the front tires never appear (the wheels render). Selecting it in Edit draws no selection wireframe for the tires - the GPU outline is built from VK instance/slot data, so the tire mesh never reached the GPU scene: an ingest failure (missing/delayed/stuck), not culling/shading.

Log: the async mesh decoder shows skipped[latched=102278] with the same meshes decoded repeatedly (decodes=8, latched=7). GLResidue shows movedBridge growing (unprocessed moving linksets, GL-A3 #48).

In progress: a select-to-diagnose log (VKIngestDiag: per selected object/face - mesh+LOD, decode state, capture accepted/refused + reason, slot/instance) and investigation of latched decodes, allocator-ceiling refusals (GL-A10 #55) and the settled-skip signature not resetting when mesh data arrives late.

**More evidence:** on the affected vehicle the doors were missing but eventually appeared; the **front tires never appear** (the wheels render). Selecting it in Edit draws **no selection wireframe for the tires** - the GPU outline is built from VK instance/slot data, so the tire mesh never reached the GPU scene: an **ingest** failure (missing/delayed/stuck), not culling/shading. Log: the async mesh decoder shows `skipped[latched=102278]` with the same meshes decoded repeatedly (decodes=8, latched=7). GLResidue shows `movedBridge` growing (unprocessed moving linksets, GL-A3 #48). In progress: a select-to-diagnose log (`VKIngestDiag`: per selected object/face - mesh+LOD, decode state, capture accepted/refused + reason, slot/instance) and investigation of latched decodes, allocator-ceiling refusals (GL-A10 #55) and the settled-skip signature not resetting when mesh data arrives late.
Author
Owner

Intermittent: on the next launch (no ingest changes) the same vehicle's front tires loaded and rendered correctly. So it's timing/ordering-dependent, not content-specific - points at an ingest race (data arriving later than the first ingest visit and never revisited), not at the mesh itself. Fix in progress targets the self-healing paths + a VKIngestDiag reason code to make the next occurrence conclusive.

**Intermittent:** on the next launch (no ingest changes) the same vehicle's front tires loaded and rendered correctly. So it's timing/ordering-dependent, not content-specific - points at an ingest race (data arriving later than the first ingest visit and never revisited), not at the mesh itself. Fix in progress targets the self-healing paths + a VKIngestDiag reason code to make the next occurrence conclusive.
Author
Owner

Root cause found with VKIngestDiag (selected a partially loaded car: 101 objects, dozens of parts with missing faces).

Example, a 7-face mesh part:

LOD ll_mLOD=1 live(ingest key)=1 gpu_desired=3
face 1: capture=REFUSED reason=empty_face nv=1 ni=3 (at LOD1) | levels[0..3]=-,-,-,6020 | INSTANCE=NONE
face 4: ingested at LOD1 | INSTANCE present
  1. The creator zeroed most faces at LOD1 (normal practice). Those faces have resident LOD3 geometry and the GPU wants LOD3.
  2. Ingest keys each face on LL's mLOD; the LOD1 face is empty, so no GPU instance is ever created and the face never draws at any distance.
  3. LL's mLOD is stale under VK: calcLOD/updateLOD run from stateSort/updateGeom, which Vulkan bypasses, so an object keeps the LOD from when it first appeared. That explains the intermittency.

Also confirmed: the face-list resync (placeholder face count frozen at creation) fired for 45+ objects - a second real cause, fixed.

Fix in progress: instance a face if it has geometry at any LOD; GPU LOD select skips empty levels; drive decode/capture from the GPU-desired LOD instead of LL's stale mLOD.

**Root cause found with VKIngestDiag** (selected a partially loaded car: 101 objects, dozens of parts with missing faces). Example, a 7-face mesh part: ``` LOD ll_mLOD=1 live(ingest key)=1 gpu_desired=3 face 1: capture=REFUSED reason=empty_face nv=1 ni=3 (at LOD1) | levels[0..3]=-,-,-,6020 | INSTANCE=NONE face 4: ingested at LOD1 | INSTANCE present ``` 1. The creator zeroed most faces at LOD1 (normal practice). Those faces have resident LOD3 geometry and the GPU wants LOD3. 2. Ingest keys each face on **LL's mLOD**; the LOD1 face is empty, so **no GPU instance is ever created** and the face never draws at any distance. 3. **LL's mLOD is stale under VK**: calcLOD/updateLOD run from stateSort/updateGeom, which Vulkan bypasses, so an object keeps the LOD from when it first appeared. That explains the intermittency. Also confirmed: the face-list resync (placeholder face count frozen at creation) fired for 45+ objects - a second real cause, fixed. Fix in progress: instance a face if it has geometry at any LOD; GPU LOD select skips empty levels; drive decode/capture from the GPU-desired LOD instead of LL's stale mLOD.
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
backspace119/Slipstream#88
No description provided.