Skip to content

fix(fast3d): don't clamp HD textures to an undefined tile region#1135

Open
bassdr wants to merge 1 commit into
Kenix3:port-maintenancefrom
bassdr:pr/hd-clamp-degenerate-tile
Open

fix(fast3d): don't clamp HD textures to an undefined tile region#1135
bassdr wants to merge 1 commit into
Kenix3:port-maintenancefrom
bassdr:pr/hd-clamp-degenerate-tile

Conversation

@bassdr

@bassdr bassdr commented Jun 24, 2026

Copy link
Copy Markdown
zelda_eye

Summary

With an HD texture pack, characters whose CI eye/face textures are loaded via segment with an unset tile size render those textures as a small repeated grid. Most visible on adult Zelda / Sheik in the Temple of Time. Vanilla textures are unaffected; it only appears with HD replacements enabled.

Root cause

Regression from #1118. That change made HD replacement textures always clamp their sampled width/height to the rendered tile region (tex_width2/tex_height2) via the isHd flag in GfxSpTri1.

These eye textures use a tile with no size set (lrs == uls == 0), so tex_width2 = (lrs - uls + 4) / 4 = 1. The isHd clause then clamps tex_width from its real 32 down to 1. Since tex_width is also the UV normalizer (u / tex_width), the vertex UVs (authored 0..32) now span 0..32, and with wrap addressing (cms == 0) the upscaled texture tiles ~32x across the primitive.

Instrumentation at the clamp, one HD CI8 draw (broken eye i=1 vs. a face tile i=0 with a real region):

i=1  hbs=32 vps=8  tw=32->1  tw2=1   uls=0 lrs=0    cms=0 cmt=0  siz=CI8   <- clamped to 1
i=0  hbs=64 vps=16 tw=192    tw2=192 uls=0 lrs=764  cms=2 cmt=2  siz=CI8   <- no-op (correct)

Before #1118 these textures rendered fine: they are wrap-mode and not pyramid-like, so the tile-region clamp never applied.

Fix

Only force the HD tile-region clamp when the tile actually defines a region (lrs > uls / lrt > ult). The pyramid-like and explicit G_TX_CLAMP paths are unchanged, and HD textures that genuinely define a smaller sub-region (the case #1118 targeted) still clamp as before.

Scope and testing

Affects any HD pack drawing actors that segment-swap a CI eye/face texture with an unset tile size (adult Zelda, Sheik, likely others). Tested with an HD pack on the Temple of Time Sheik-reveal cutscene: the eye renders correctly after the change, with no regressions seen on other textures (HUD, world, faces with real tile regions).

Kenix3#1118 made HD replacement textures always clamp their sampled size to the
rendered tile region (tex_width2/tex_height2). When a tile has no size set
(lrs <= uls) that region collapses to ~1 texel, so the clamp shrinks the UV
normalizer and the upscaled texture tiles across the primitive. This hit CI8
eye textures that load via segment with an unset tile size and wrap-sample
(adult Zelda / Sheik), rendering the HD eye as a small repeated grid.

Only force the HD tile-region clamp when the tile actually defines a region
(lrs > uls / lrt > ult); pyramid-like and explicit G_TX_CLAMP paths are
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant