INDEX carried XPR2 as "colours unverified (dynamic item)". The failure mode that matters is a swapped red/blue channel: invisible on greys, invisible without ground truth, and it poisons every asset silently. Method: pick an asset that is strongly asymmetric in hue and has known in-game appearance. DeltaSaber_T.xpr (1024x1024 Dxt1, 11 mips) decodes to white/grey panels with orange-rust accents; the game renders the same hull in the ARSENAL scene. decoded texture : 1073 warm px, 0 cool, median saturated hue 23.3 deg in-game render : 916 warm px, 124 cool, median saturated hue 9.3 deg Both orange/red; a red<->blue swap would put the texture at ~200 deg. The cool pixels are the blue UI behind the model and the 14 deg offset is the hangar's red key light -- neither can move a hue by 180. Stated as a bounded result, not "colours are correct": a hue-family comparison cannot see a gamma/sRGB error, premultiplied alpha, or a per-channel scale, so exact fidelity stays open and needs a flat unlit known-value surface. Cubemap face ordering untouched. BG_Earth.xpr (A8R8G8B8 cubemap face) decoding to a coherent nebula is corroboration for the de-tile step, not proof. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2.5 KiB
XPR2 colours: channel order ✅ confirmed against the running game
INDEX carried XPR2 as 🟡 with "colours unverified (dynamic
item)". The failure mode that matters for a texture decoder is a swapped red
and blue channel — it is invisible on greys and on anything you have no ground
truth for, and it silently poisons every asset. This settles that one, and is
explicit about what it does not settle.
Method
Pick an asset whose in-game appearance is unambiguous and strongly asymmetric in hue — the Delta Saber's livery is white/grey panels with orange-rust accents, so a red↔blue swap would render it cyan. Then compare the decoded texture against the game rendering the same asset.
- Decoded:
hidden/resource3d/DeltaSaber_T.xpr— 1024×1024, Dxt1, 11 mip levels — exported withsylpheed-cli texture export. - In-game: the Delta Saber standing in the ARSENAL scene, captured at
x 700..830, y 180..480of the framebuffer so the crop is hull, not UI.
Both images were resampled to 96×96 and every pixel classified; for the
saturated pixels (max−min ≥ 50) the median hue was taken.
warm px (R > B+40) |
cool px (B > R+40) |
median hue of saturated px | |
|---|---|---|---|
| decoded texture | 1073 | 0 | 23.3° (orange) |
| in-game render | 916 | 124 | 9.3° (orange-red) |
Both land in the orange/red family; a red↔blue swap would put the decoded texture at ≈200° (azure). The 124 cool pixels in the game crop are the blue UI panel behind the model, and the 14° offset is the hangar's red key lighting tinting the lit model — both expected, neither able to move a hue by 180°.
Evidence: captures/xpr2-colour-check-deltasaber.png
— decoded atlas beside the in-game hull.
What this establishes, and what it does not
✅ Channel order is right for the XPR2 path, on a DXT1 texture with mips.
Separately, BG_Earth.xpr decodes as a 1024×1024 A8R8G8B8 cubemap face and
produces a coherent nebula rather than noise, so the de-tile step is sound on
that path too — though a nebula has no ground truth, so it is corroboration, not
proof.
🟡 Exact colour fidelity is still open. A hue-family comparison cannot see a gamma/sRGB curve error, a premultiplied-alpha mistake, or a small per-channel scale — all of which preserve hue. Settling those needs a flat, unlit, known-value surface rather than a lit hero model.
❔ The ~15 % of T8aD variants noted elsewhere and the XPR2 cubemap face
ordering are untouched by this.