Linked Shipwright report: HarbourMasters/Shipwright#6666
I investigated the Shipwright water/lava texture animation jitter locally and the repro points at LUS-side tile-size derivation rather than frame pacing or skipped interpolation.
In the Fire Temple lava case, the interpolation replay cycle stayed regular (0 -> 1 -> 2 -> 0 ...), but one replay phase derived a different rendered texture window size from the interpolated tile coordinates.
Bad phase example:
replay=1
tile0=(0.000,6.333,124.000,130.333)
renderSize0=(32, 31)
texSize0=(32, 31)
Adjacent phases for the same lava surface stayed 32x32:
replay=0 tile0=(0.000,6.000,124.000,130.000) renderSize0=(32, 32)
replay=2 tile0=(0.000,6.667,124.000,130.667) renderSize0=(32, 32)
So the visual jitter appears to come from alternating between a 32x32 and 32x31 texture window. The intended height is still 32 texels, but the current conversion effectively truncates (lrt - ult + 4) / 4 after interpolation. With interpolated float values like 6.333 and 130.333, precision can land just below 32.0, and the cast becomes 31.
The conversions I found are in src/fast/interpreter.cpp, in the code paths that derive rendered/imported tile dimensions from uls/ult/lrs/lrt, including:
ImportTextureRgba16
ImportTextureRgba32
ImportTextureCi4
ImportTextureCi8
GfxSpTri1
A minimal local fix that made the lava case stable was to round the derived texel count instead of truncating it:
static uint32_t GetTileSizeFromCoordinates(float low, float high) {
float size = (high - low + 4.0f) / 4.0f;
if (size <= 0.0f) {
return 0;
}
return static_cast<uint32_t>(lroundf(size));
}
Then use that helper instead of directly casting (high - low + 4) / 4 to uint32_t/int32_t in those tile-size calculations.
I tested this locally in Shipwright; the lava scene stopped visibly alternating between good and bad texture phases. The local soh target built successfully after the change. I did not need to change interpolation scheduling or texture cache behavior for this specific symptom.
Additional Shipwright-side diagnostic comment: HarbourMasters/Shipwright#6666 (comment)
Linked Shipwright report: HarbourMasters/Shipwright#6666
I investigated the Shipwright water/lava texture animation jitter locally and the repro points at LUS-side tile-size derivation rather than frame pacing or skipped interpolation.
In the Fire Temple lava case, the interpolation replay cycle stayed regular (
0 -> 1 -> 2 -> 0 ...), but one replay phase derived a different rendered texture window size from the interpolated tile coordinates.Bad phase example:
Adjacent phases for the same lava surface stayed
32x32:So the visual jitter appears to come from alternating between a
32x32and32x31texture window. The intended height is still 32 texels, but the current conversion effectively truncates(lrt - ult + 4) / 4after interpolation. With interpolated float values like6.333and130.333, precision can land just below32.0, and the cast becomes31.The conversions I found are in
src/fast/interpreter.cpp, in the code paths that derive rendered/imported tile dimensions fromuls/ult/lrs/lrt, including:ImportTextureRgba16ImportTextureRgba32ImportTextureCi4ImportTextureCi8GfxSpTri1A minimal local fix that made the lava case stable was to round the derived texel count instead of truncating it:
Then use that helper instead of directly casting
(high - low + 4) / 4touint32_t/int32_tin those tile-size calculations.I tested this locally in Shipwright; the lava scene stopped visibly alternating between good and bad texture phases. The local
sohtarget built successfully after the change. I did not need to change interpolation scheduling or texture cache behavior for this specific symptom.Additional Shipwright-side diagnostic comment: HarbourMasters/Shipwright#6666 (comment)