Skip to content

BotW: fix shadow seam on Steam Deck and other non-16:9 displays - #744

Open
scndls wants to merge 1 commit into
cemu-project:masterfrom
scndls:fix/botw-shadow-seam-non-16-9
Open

BotW: fix shadow seam on Steam Deck and other non-16:9 displays#744
scndls wants to merge 1 commit into
cemu-project:masterfrom
scndls:fix/botw-shadow-seam-non-16-9

Conversation

@scndls

@scndls scndls commented Apr 3, 2026

Copy link
Copy Markdown

What this fixes

A dark horizontal shadow band cuts across the screen in Breath of the Wild when playing at any non-16:9 resolution. This is most visible on Steam Deck (1280x800, 16:10) but affects all non-standard aspect ratios — 16:10, 3:2, 4:3, and ultrawide.

The bug has likely been present for every non-16:9 user since the rounding hack was introduced. Anyone who saw a mysterious dark line across the ground in BotW at a custom resolution was hitting this.

The fix

Remove + 0.49 from two height formulas for the 640x368 half-resolution texture. That's it — two characters deleted on two lines.

Before: overwriteHeight = (($height/$gameHeight) * 368) + 0.49
After: overwriteHeight = ($height/$gameHeight) * 368

Why it works

The + 0.49 was added as a rounding trick (truncation + 0.49 ≈ round-to-nearest). But for resolutions where the fractional part exceeds 0.51, it rounds up by one pixel. That single extra pixel misaligns the shadow cascade boundary, producing the visible seam.

Example at 1280x800 (Steam Deck native):

  • With + 0.49: (10/9) × 368 + 0.49 = 409.38 → truncates to 409 ❌ (1px too tall)
  • Without: (10/9) × 368 = 408.89 → truncates to 408

At 16:9 resolutions the scaling factor is always an integer, so the result is exact with or without rounding. This fix changes nothing for 16:9 users.

Tested at

  • 1280x800 (Steam Deck native) — shadow seam gone ✓
  • 1920x1200 (16:10) — no regression ✓
  • 16:9 resolutions — unaffected (integer scaling) ✓

Remove the +0.49 rounding hack from 640x368 TextureRedefine height
formulas. At 1280x800 (Steam Deck native), rounding up produces 409
instead of the correct 408, causing a visible dark horizontal shadow
band between cascade levels. Plain truncation gives correct results
at all tested resolutions (1280x800, 1920x1200, and all 16:9).
@scndls scndls changed the title BotW: fix shadow cascade seam at non-16:9 resolutions BotW: fix shadow seam on Steam Deck and other non-16:9 displays Apr 3, 2026
scndls added a commit to scndls/cemu_graphic_packs that referenced this pull request Apr 7, 2026
Adds a self-contained workaround pack at Workarounds/GraphicsNon16By9 that
serves as a drop-in replacement for the main Graphics pack on non-16:9
aspect ratios (16:10, 21:9, 4:3, 3:2, 32:10, etc.).

Fixes two artifacts that persist on every reported non-16:9 configuration:

1. Rain bottom-strip artifact: when it's raining and the camera is pitched
   downward, a horizontal strip of broken rain particles appears at the
   bottom of the screen. Most visible at Steam Deck native 1280x800 and at
   1920x1200.
2. Shadow cascade seam: the pre-existing cemu-project#568 bug, partially addressed by
   cemu-project#744 but still visible at non-16:9 aspects.

Both artifacts disappear when the aspect ratio is switched to 16:9 in the
Graphics pack, confirming the bugs are driven by how the depth-pyramid
TextureRedefines scale at non-uniform aspect ratios.

Root cause: at non-16:9 the ratios diverge -- e.g. at 1280x800,
\$width/\$gameWidth = 1.0 but \$height/\$gameHeight = 1.111 -- which
introduces a non-uniform Y stretch in every depth-pyramid downsample-chain
TextureRedefine. BotW's rain pixel shader samples half-res depth using
hardcoded native-720 assumptions, and the half-res 640x368/640x360 pair is
structurally coupled (the 8-pixel padding gap is required for shadow
cascade alignment). Verified empirically by bisection of the Graphics pack
TextureRedefine entries on Steam Deck at 1280x800.

The only artifact-free configuration is to scale the main framebuffer
upward but leave the depth-pyramid downsample chain at native dimensions.
This pack contains exactly 6 TextureRedefines: the 1280x720 main
framebuffer plus the 5 shadow cascade entries driven by \$shadowRes. All
other depth/bloom/GUI/cubemap downsample entries from the main pack are
removed.

The 40 companion files (3 .asm patches + 37 shader patches) are
byte-identical copies of the corresponding files in Graphics/, so the pack
is fully self-contained. The [Definition], [Default], and all [Preset]
blocks (aspect ratio, resolution, ultrawide HUD, AA, shadows, shadow draw
distance) are preserved verbatim from Graphics/rules.txt, so user-facing
behavior is identical apart from the depth-pyramid omission.

Quality tradeoff: non-16:9 users lose the depth-pyramid upscale chain for
downsampled effects (SSAO, fog masks, bloom downsamples). At 1280x800 on
Steam Deck the difference is imperceptible.

Why a separate pack: Cemu's TextureRedefine parser silently ignores
'condition = ...' clauses inside TextureRedefine blocks, and does not
evaluate user-defined integer variables in arithmetic expressions like
'\$useDepthPyramid * X + (1 - \$useDepthPyramid) * Y'. Both were verified
empirically. Without a working conditional mechanism inside rules.txt, a
separate pack is the cleanest approach that preserves zero regression for
16:9 users (the main Graphics pack is unchanged).

Tested on Steam Deck at 1280x800 native and on 1920x1200 16:10. Rain
bottom-strip and shadow cascade seam are gone in both. 16:9 users are
unaffected because they continue to use the main Graphics pack.

Related: cemu-project#568 (original report), cemu-project#744 (shadow seam rounding fix, still
open) -- this PR is complementary to cemu-project#744 rather than a replacement.
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