BotW: fix shadow seam on Steam Deck and other non-16:9 displays - #744
Open
scndls wants to merge 1 commit into
Open
BotW: fix shadow seam on Steam Deck and other non-16:9 displays#744scndls wants to merge 1 commit into
scndls wants to merge 1 commit into
Conversation
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.49from two height formulas for the640x368half-resolution texture. That's it — two characters deleted on two lines.Before:
overwriteHeight = (($height/$gameHeight) * 368) + 0.49After:
overwriteHeight = ($height/$gameHeight) * 368Why it works
The
+ 0.49was 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):
+ 0.49:(10/9) × 368 + 0.49 = 409.38→ truncates to 409 ❌ (1px too tall)(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