Add experimental water stereo fixes - #49
Draft
philpax wants to merge 1 commit into
Draft
Conversation
The WaveWorks ocean simulation is gated to one step per frame. The simulation step inside the main-body water draw runs on the first water draw of the frame and is suppressed thereafter, so both eyes render the same archived displacement state. The planar reflection camera is re-mirrored per eye. The water shader samples reflection maps at the pixel's own screen position, so a map rendered from one mirrored camera only matches one view. The engine mirror is snapshotted on the first dispatch and the eye's rigid pose delta is conjugated by the water-plane mirror before being applied to the camera. Reflection pre-passes are re-rendered on the second eye when the toggle is on. The screen-space water reflection flag can be disabled for A/B testing. Disabling forces the water onto the full-reflection binding; if the per-eye mismatch disappears, the screen-space sampling is the seam. Screenshots now capture per-eye water draw inputs. WaterDrawSnapshot records frame, dispatch ordinal, render pass, under-water flag, simulation time, screen-space reflection state, per-eye reflection state, reflection camera pose, reflection pass count and texture identities. The sidecar JSON emitted with F12 captures includes a water field. The debug UI exposes share_water_simulation, per_eye_water_reflection and disable_screen_space_water_reflection. The scene module visibility is widened to pub(crate) so the screenshot path can read the water snapshots. This is incomplete experimental work for #47.
philpax
force-pushed
the
issue-47-water-stereo-experimental
branch
from
August 12, 2026 13:14
887caf9 to
8ade05c
Compare
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.
Summary
Adds experimental per-eye water corrections for issue #47. The WaveWorks ocean simulation is gated to one step per real frame, the planar reflection camera is re-mirrored per eye, and diagnostic toggles for screen-space water reflection are exposed. Screenshots capture per-eye water draw inputs for offline inspection.
Context
In two-pass stereo the second eye advances the WaveWorks simulation again and renders a later ocean, decorrelating sun-glint sparkle between eyes. The water planar reflection camera is mirrored once per frame for the centre pose; the water shader samples reflection maps at the pixel's own screen position, so a map rendered from the centre mirror is only valid for one view. The screen-space reflection path samples a reflection map aligned to one view; disabling it provides an A/B test for the seam.
Changes
payload/src/stereo/config.rsaddsshare_water_simulation,per_eye_water_reflectionanddisable_screen_space_water_reflectionwith defaultstrue,true,false.payload/src/hooks/graphics_engine/scene/water.rsimplements the once-per-frame simulation latch viaSIMULATION_STEPPED_THIS_FRAMEandbegin_dispatch, re-mirrorsCWaterPatchManager::m_ReflectionCameraper eye withmirrored_eye_reflection_transform, and addsapply_ssr_overridewith save/restore ofm_EnableScreenSpaceWaterReflection.WaterDrawSnapshotandlast_water_drawscapture per-eye inputs for diagnostics. Unit tests verify the reflection transform.payload/src/screenshot.rsstores[Option<WaterDrawSnapshot>; 2]inPendingWriteand emits awaterfield in the sidecar JSON.payload/src/ui/render/corrections.rsexposes the three toggles in the debug UI with hover text referencing issue #47.payload/src/hooks/graphics_engine/mod.rswidensscenetopub(crate)so the screenshot path can read water snapshots.Testing
Tested in-game. The simulation gating and per-eye reflection re-mirror reduce the per-eye decorrelation, but the issue is not fully resolved. Further testing and analysis are required.
Notes
Experimental and incomplete. The per-eye reflection re-render requires pre-pass sharing to be carved out elsewhere. The single-pass collapse path is intentionally left on the engine centre mirror.
Closes #47