Warp: restore the translocation-vortex look + fix texture-scroll precision collapse (task #52)

The death/respawn "blue whirlwind" (tsphere) now matches the original cabinet
photo (capture.png): a smooth spinning lavender vortex with a bright core.

Root cause of the long-standing "radial spokes" artifact was NOT the warp code
but a general engine bug: L4D3D::SetTextureScrolling computed its texture-matrix
offset as scrollDelta * absolute_time, which grows unbounded and collapses UV
float precision -> a smooth scrolled cloud shatters into grainy radial steps.
Wrapped with fmodf(..., 1.0f) (identical under REPEAT tiling, full precision).
This also cleans the scrolling bexp beam grit and any other SCROLL material.

Visual reconstruction (verified against the real 45-vtx TSPHERE.BGF bicone,
offline-rasterized then ported):
  - view ON-AXIS (eye centred on the throat) + spin in place -> concentric rings
    (decomp FUN_00453dc4 does spin-about-local-Z + submit; the port had stubbed it)
  - bintA cloud through a WIDE lavender ramp at full contrast (drawn as SKY);
    no geometry "bands", no log-polar twist, no off-axis tornado (all discarded)
  - tessellate the 12-facet bicone smooth; isotropic + trilinear; ramp baked into
    the texture and drawn SELECTARG1(TEXTURE) to avoid double-tinting

Env knobs (BT_WARP_*) default to the verified values; BT_WARP_SELFTEST/SELFSHOT
are an off-by-default visual-verification harness (backbuffer frame dump).

Docs: new context/translocation-warp.md (geometry/material/visual/lifecycle/env);
reconstruction-gotchas.md gains the accumulated-time precision-collapse bug class;
rendering.md / multiplayer.md / decomp-reference.md / CLAUDE.md cross-linked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-10 14:53:50 -05:00
co-authored by Claude Opus 4.8
parent a35f321ba1
commit 0bfb3d4ab3
10 changed files with 591 additions and 22 deletions
+21
View File
@@ -203,6 +203,27 @@ AVs. Fill gaps with a shared read-only pad member. Same for a class's `<Name>Att
---
## 13. Accumulated-time precision collapse (rate × absolute-time in a matrix)
Any matrix element (or coordinate) computed as **`rate × absolute_runtime`** grows without bound. Float
has ~7 significant digits, so once the value is large its FRACTIONAL precision is gone — and if that
value is then added to a per-pixel/per-vertex quantity, the result **quantizes into coarse steps**. The
visible signature is a smooth field shattering into grainy stair-steps or radial "spokes" that get
worse the longer the app runs (and are invisible right after launch).
- **Archetype (the translocation-warp spokes):** `L4D3D::SetTextureScrolling` set a texture-matrix
translate `_31 = -scrollUDelta * targetRenderFrame` (targetRenderFrame = absolute time). Within
seconds the UV offset was large enough that adding it to the per-pixel UV collapsed precision → the
scrolled cloud rendered as radial grain. It degraded EVERY scrolling texture (beams `bexp`, exhaust),
but the full-screen warp on black made it obvious. **Fix:** wrap into the periodic range —
`fmodf(rate*time, period)` — identical under REPEAT tiling / rotation, but full precision. Prefer
delta-time accumulators that you wrap each frame, over `rate*absolute_time`. [T2]
- **Tell from a symptom:** if a smooth animated/scrolled surface looks progressively grainier or
"steps" and a STILL/offline render of the same data is clean, suspect an unwrapped time accumulator,
not the geometry, texture, or filter. (Cost most of task #52's visual effort — see [[translocation-warp]].)
---
## Diagnostic recipe (the standard loop)
1. Read the RAW decomp `reference/decomp/all/part_*.c` for the `FUN_xxxx`.
2. Map `FUN_`/`DAT_`/`this+0xNN` to engine symbols via BT headers + WinTesla MUNGA source +