Skip to content

Fix doubled stereo image on UE 5.5/5.6 (zero-based eye index misclassified as full pass)#422

Open
adambenovic wants to merge 1 commit into
praydog:masterfrom
adambenovic:fix/ue56-stereo-support
Open

Fix doubled stereo image on UE 5.5/5.6 (zero-based eye index misclassified as full pass)#422
adambenovic wants to merge 1 commit into
praydog:masterfrom
adambenovic:fix/ue56-stereo-support

Conversation

@adambenovic

Copy link
Copy Markdown

Problem

On UE 5.5/5.6 games, everything rendered near the camera (hands, HUD, world-space UI) appears heavily doubled with a cross-eyed effect, while distant geometry looks mostly fine. Related: #329 (UE 5.5.3 games not entering VR correctly), #368 (UE 5.6 compatibility).

Root cause

FFakeStereoRenderingHook::calculate_stereo_view_offset classifies a call as a mono "full pass" via:

const auto is_full_pass = view_index == 0 && !index_was_ever_two && !index_was_ever_negative;

UE <= 5.4 called CalculateStereoViewOffset with view index -1 (INDEX_NONE) or 2 early on, flipping those flags so index 0 was subsequently treated as a real eye. UE 5.5/5.6 only ever sends indices 0/1, so view 0 stays permanently misclassified as a full pass. That skips the per-eye mod callbacks (on_pre/post_calculate_stereo_view_offset) and update_hmd_state() for one eye only, while the other eye receives the full treatment.

Measured on Satisfactory (CSS custom UE 5.6.1, 1.2 experimental branch) with first-N-call instrumentation: the two eye view locations ended up ~33.6 cm apart (including a 15.7 cm vertical offset) instead of IPD (~6.5 cm), and the offset varied with head position. Near-field content at such disparity is unfusable - hence the double image.

Fix

On UE5 (already detected via m_has_double_precision / LWC double-precision math), index 0 in a stereo pass is always a real eye - a genuine mono pass arrives as INDEX_NONE (-1), which the function already filters earlier. One-line change gating the full-pass classification to non-UE5 binaries.

Testing

  • Satisfactory 1.2 experimental (CSS UE 5.6.1, D3D12, OpenXR via Virtual Desktop): double image fully resolved, eye separation verified at IPD via instrumentation, extended play session stable with the UEVR Enhancements gameplay mod.
  • The remaining UE 5.6 hook warnings (Slate.DrawToVRRenderTarget cvar removed upstream, etc.) are unrelated to this fix and the slate path still works via the engine''s RDG deprecation bridge, which routes to the legacy RenderTexture_RenderThread vtable entry that UEVR already hooks.

🤖 Generated with Claude Code

…ified as full pass)

UE <= 5.4 called CalculateStereoViewOffset with view index -1 or 2 early,
flipping the index_was_ever_two/negative flags so index 0 was treated as a
real eye. UE 5.5/5.6 only ever sends indices 0/1, leaving view 0 permanently
classified as a mono "full pass" - which skipped per-eye mod callbacks and
HMD state updates for one eye only. Measured result on a UE 5.6.1 game
(Satisfactory 1.2 experimental): eye separation of ~33.6 cm (incl. 15.7 cm
vertical) instead of IPD, producing a heavily doubled image for near-field
content.

Fix: on UE5 (already detected via LWC double-precision math) index 0 in a
stereo pass is always a real eye - a genuine mono pass arrives as
INDEX_NONE (-1), which is already filtered above.

Likely also addresses praydog#329 (UE 5.5.3 games not entering VR
correctly) and contributes to praydog#368 (UE 5.6 support).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
joeyhodge added a commit to joeyhodge/UEVR that referenced this pull request Jun 6, 2026
Treat view index 0 as a real eye for UE5/LWC builds instead of a mono full pass. This restores per-eye callbacks and HMD state updates in UE5.5/5.6 games that only emit 0/1 stereo indices while preserving legacy UE4 behavior.\n\nBased on praydog/UEVR PR praydog#422 by Adam Benovic.
@joeyhodge

Copy link
Copy Markdown

Approval from me, Good work!

@joeyhodge

Copy link
Copy Markdown

I have been testing on many different uevr/ue versions and have noticed no regressions myself with this included

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.

2 participants