An unofficial build on
tig3rmast3r's v0.2.1.
A follow-up to 0.2.3_beta3.
Short version
On SteamVR, more of the frames the bridge generates now actually reach the
headset. Measured on Hogwarts Legacy through UEVR — the title that has been
sitting below the others since beta1 — delivered frames went from about 77 to
about 84 a second, with stretches holding 89–90.
Nothing changed in how frames are generated, only in when they are handed
over. Image quality and every setting are untouched, and the pacing work is
SteamVR-only — VDXR, Oculus and PimaxXR hand frames over exactly as before.
The overlay's FPS number is also fixed — on Quest, Pico and anything else
that is not SteamVR it was counting frames that carried no new picture, and
could read your headset's refresh rate while the image was nothing like it.
If you still see dips, read the known issues. We now know what most of the
remaining ones are, and there is a one-minute test you can run yourself.
What was wrong
On SteamVR the bridge has to choose the moment to hand each frame to the
compositor. Miss the compositor's deadline and your frame is counted against the
next display refresh — which means two frames land on one refresh, the
compositor shows the first one twice, and the second is thrown away before it is
ever displayed.
Three separate mechanisms inside the bridge were all moving that moment, and
they were aimed at targets that did not agree with each other. Two of them
predate the current design and should have been retired when it arrived.
One was holding the schedule wherever the session happened to start. It had
no way to know whether that was a good place — it simply pinned the schedule
there. Across a 45-second capture it sat at its maximum correction on every
single evaluation, with an error it never once reduced, while pulling against
the mechanism that does know where the compositor's deadline is.
One was reading the compositor's clock at the wrong moment. It asked "how
long until your deadline?" before the bridge's own wait, then compared the
answer to a target describing the moment after it — about 9.9 ms apart, which
is very nearly a full display period. That mismatch did not show up as an
obvious ten milliseconds; it wrapped around into a small, plausible, wrong-signed
error. It spent 69% of frames pulling the schedule in the wrong direction.
The consequence was that the hand-over settled wherever those forces balanced,
rather than where SteamVR had asked for it — and whenever the game's load
shifted, the balance point moved and delivery followed it down.
Separately, the spacing between the generated frame and the real one could not
reach even. The controller that sets it was aiming at a band that made an even
spacing unreachable, so it always held some offset whether one was wanted or not.
The fix
The schedule now has one owner: the step that reads the compositor's clock at
the moment the frame actually goes out, and aims at the margin SteamVR asks for.
The other two stand down on SteamVR and are unchanged everywhere else. The pair
spacing controller can now settle at even, and does.
In numbers, on the same title and machine: the hand-over used to land with
3.3 ms of the compositor's frame remaining against a 2.5 ms target, and never
got there. It now lands at 2.50 ms — on target — and the correction that was
firing on 97–100% of frames now fires on 3–8%.
How to tell it is working
On SteamVR the overlay's figure should sit closer to your headset's refresh rate
and, more importantly, should stop wandering down over a session while every
other number looks fine. If you run fpsVR alongside, its frame-time graph should
look steadier between dips.
Also fixed: the overlay's FPS number
On runtimes other than SteamVR the counter was reporting submissions rather
than frames, and those are not the same thing.
When your game cannot produce enough frames to fill the headset's refresh rate
even after generation, the bridge hands the runtime the picture it already has
rather than leaving a gap — that is what keeps the image stable instead of
juddering. Those repeats were being counted. The result was a counter that could
read your headset's exact refresh rate no matter what was actually on screen.
Measured on The Witcher 3 at 144 Hz through Virtual Desktop: the overlay read
144 while the headset was receiving 78 distinct pictures a second, the other
66 being repeats. The number was wrong by nearly a factor of two, and it was
wrong in the most misleading direction — it looked perfect.
The counter now counts only frames that carry a new picture. On the run above it
would read 78.
On SteamVR you will see no change. There the figure is replaced by the
compositor's own count of what it actually displayed before it ever reaches the
overlay, so it was already telling the truth. This only ever affected runtimes
with no such source — Virtual Desktop, VDXR, Oculus, PimaxXR.
This makes the number honest, not the game faster. If it now reads lower
than it used to, that lower figure is what you were always getting.
Known issues
-
The remaining dips are a resolution ceiling, not the bridge. This is the
answer to the "Hogwarts sits at 81" item carried since beta2, and it is worth
a minute of your time:The test. Disarm the bridge and play the same scene. If the dips are still
there, they are not the bridge — your machine is past its comfortable per-eye
resolution, and no version of this tool will fix that. On the reporting machine
the dips appeared with the bridge disarmed whenever the game's own rate fell to
roughly 55 FPS or below.The lever is resolution. Dropping per-eye resolution to about 0.92× removed
almost all of them. Start there before changing anything else.If you use UEVR, its Synced Sequential rendering mode did noticeably
better than Native Stereo on the reporting machine. Worth trying. -
Very high per-eye resolutions remain the hard limit, unchanged. Above
roughly 9 megapixels per eye the generated frame cannot be finished early
enough to be shown, and the bridge cannot tell that this is happening — the
overlay will read the full rate while the headset does not. -
If SteamVR is restarted while a game is running, the delivery counters may
stop being meaningful until the game is restarted. Unchanged from beta3. -
The D3D11 fix from 0.2.3_beta2 is measured, not proven. The fault it
addresses is probabilistic, so a clean session does not demonstrate much. If a
D3D11 game still crashes inside the runtime, please report it. -
Selecting the NVIDIA backend without an NVIDIA card silently does nothing.
On AMD or Intel leave the backend on FidelityFX, the shipped default. -
A very high headset refresh rate can outrun what generation can produce.
Generation doubles your game's frame rate; if double is still short of the
refresh rate, the bridge fills the difference with repeats and the result
judders however good the pacing is. The Witcher 3 at 39 FPS into a 144 Hz
Quest 3 is 78 against 144, and it shows. Pick a headset refresh rate close to
double your game's frame rate — 72 Hz in that example — or lower settings
until the game can feed the one you want.
About the measurements in this note
The pacing figures come from one machine, one headset and one title —
Hogwarts Legacy through UEVR on SteamVR with a Pimax Crystal Super OLED. The
counter figures come from The Witcher 3 on a Quest 3 through Virtual Desktop.
Both faults are structural and not specific to those setups, but the size of the
difference on yours may vary. Reports either way are useful.
Everything else is unchanged from 0.2.3_beta3
The Assetto Corsa crash fix, the D3D11 fix, the NVIDIA backend recommendation,
the optical flow resolution setting and every game-facing setting behave exactly
as in 0.2.3_beta3. Non-SteamVR runtimes are not touched by any
of this.
Installing
Unzip anywhere and run OFXRBridgeTray.exe, then Arm bridge. Keep
OFXRBridgeTray.exe and the ofxr folder together. If you have an earlier
version armed, disarm it first.
Tested
- Hogwarts Legacy (UEVR) — the title this release is aimed at
- The Witcher 3 on a Quest 3 through Virtual Desktop at 144 Hz — where
the counter fault was found - The Callisto Protocol (UEVR)
- Skyrim VR through OpenComposite, with the FUS modlist
- Assetto Corsa — the beta3 crash fix, still fixed
on SteamVR with a Pimax Crystal Super OLED, on the NVIDIA OFA backend.
This is an experimental beta and compatibility is not universal. Please report
results — working and not — on this fork's GitHub Issues, with
an OFXR flight log where you can. Enable one by setting logging_enabled=1
under [diagnostics] in ofxr_bridge.ini; logs are written next to the armed
layer under %LOCALAPPDATA%\OFXR Bridge\RuntimeLayer\v277\.
If you are reporting a dip, please say whether it survives disarming the bridge,
and at what per-eye resolution — that one line saves the most time.