NV3D Vision Restoration Project

Usage

Windows frame-sequential stereo output for NVIDIA 3D Vision glasses. The original USB emitter is driven through WinUSB/libusb and its RAM firmware. Clean stereo over the whole screen was confirmed through the glasses on 2026-09-13, on a Samsung OLED at 4K 240 Hz in HDR with software black frame insertion. Other displays, refresh rates and sequences need separate optical validation. RP2040 OLED operation at 120 Hz and 240 Hz with BFI has also been user-confirmed; see RP2040 setup.

Game integration: the shared Geo11 hook and game-depth controls are available under Input/Games. Isolated renderer/transport tests pass; broad game and optical validation remains incomplete. Resident Evil 2 and Metal Gear Solid V retain unresolved failures. Earlier game trials are historical; see current status. Window capture remains a proven fallback. The old depth-based ReShade hook remains nonworking.

Double-click Launch.cmd to run build/bin/Release/VisionRestoration.exe.

Live controls

During fullscreen output, Home shows or hides the complete controls menu. This works with SBS sources, AI desktop and the test patterns. The normal app window is hidden until fullscreen ends. Opening the menu does not replace the source, restart the emitter or resize the output.

All input, profile, display and diagnostic options are available in the menu. Shortcuts lets you rebind functions, disable individual bindings, or turn all fullscreen shortcuts off for gaming. Outside app makes a binding work while a game or the desktop has focus. Bindings are inactive outside fullscreen and persist in profiles/shortcuts.ini. The tray icon (or launching Launch.cmd again) reopens the controls even when shortcuts are disabled. Tab remains available for normal control navigation.

Phase, Shutter, Image brightness, and HDR output are together at the top of the main and fullscreen control panels. Drag a slider, Ctrl+click to type, or use the phase/shutter minus and plus buttons. Brightness applies live; HDR changes the output buffer format while retaining the output window. HDR highlights controls the brightness test pattern’s peak luminance.

Saved manual profiles, including the Dell preload profile, retain their original timing mode when loaded. They are no longer automatically converted to guarded LCD timing. That mode is optional under Advanced LCD calibration. Profile loading also restores the saved image brightness and black level.

Stereo shaders are compiled when building the app. Switching between fullscreen and preview no longer recompiles them or blocks Stop on shader compilation. Stopping the renderer continues servicing synchronous Windows messages, so a fullscreen transition cannot deadlock while DXGI waits for the control window. AI desktop capture excludes the app’s preview, fullscreen output and controls in every view, preventing the converted image from capturing itself.

Output

Profiles now use version 10 for neutral reset. Older profiles retain their timing; old executables cannot read the new version. The separate experimental build keeps its own profile copies beside its EXE.

Image alignment stays beside the preview: convergence shifts the eye images horizontally, and scene depth changes the built-in stereo scene’s camera separation. Both apply live. Diagnostic eye-isolation targets stay fixed. Sources & games selects stereo images, VLC stereo movies, window capture or the whole screen converted with AI depth. Spout and Blender viewport inputs have been removed. The game-output controls connect existing Geo11 fixes; broader API coverage remains in development. Profiles saves named setups; timing and scene changes also autosave. Diagnostics reports presentation/USB timing and runs checks of the rendered pixels. Advanced holds per-eye timing, sequences, emitter connection and modes.

The software checks verify separate eye frames and black frames in SDR and HDR. They do not establish that all visible leakage through a glasses lens is gone. See the emitter timing fixes and presentation synchronization for implementation details.

Half and Full SBS inputs

Stereo image, Capture window, and VLC stereo movie all offer Half SBS and Full SBS in Packing. Half SBS restores horizontally squeezed eyes: a combined 1920 × 1080 frame displays each eye at 16:9. Full SBS uses each eye’s native proportions: a combined 3840 × 1080 frame also displays each eye at 16:9. Select the format that produced the content; resolution alone cannot identify it.

SBS output preserves those proportions in previews, fullscreen, eye inspection and the 2D stream view, adding black bars when the output shape differs. Window capture uses the client picture without the title bar or borders. After changing packing, click Start source again. Top / bottom remains available with its existing output-area scaling.

VLC stereo movies

  1. Install 64-bit VLC 3.x. The application loads its optional library; it does not modify VLC settings or require the legacy NVIDIA stereo driver.
  2. Under Input, select VLC stereo movie and choose Half SBS, Full SBS or Top / bottom to match the file. Choose movie… opens a local video file. Half and Full SBS use the same eye split with different width restoration, preserving the intended eye aspect ratio.
  3. Click Start source, then start your calibrated 3D preview or fullscreen output. Use Swap eyes for right-first movies. Packing changes stop the source; start it again with the new setting.
  4. Pause movie / Resume movie controls both VLC video and audio while the output retains a complete stereo pair. Movie position seeks when supported; Movie volume adjusts sound. Stop movie stops decoding. At end-of-file the last complete pair remains visible; Start source starts the movie again.

Installed VLC is detected in its standard Program Files location. A complete vlc folder beside the application also works, or Choose VLC… selects a portable installation’s vlc.exe. Keep libvlc.dll, libvlccore.dll and plugins together. A 32-bit or VLC 4.x runtime is rejected with an error; other inputs continue to work without VLC installed.

The integration uses the documented VLC 3 video callbacks to receive video pixels at VLC’s presentation time, then publishes complete GPU-shared pairs to the existing output. Audio remains with VLC. The VLC window and controls are not part of the movie pixels. CPU decoding and copies can limit high-resolution playback; this first implementation provides SDR pixels and does not claim faithful HDR movie output. External subtitle composition, disc/MVC decoding, other stereo formats and movie playback through the glasses remain unverified. Ordinary 2D video requires the separate AI desktop conversion while playing in VLC.

Screen sharing and recording (2D stream view)

Frame-sequential 3D cannot be captured. The output alternates left and right once per refresh, and a black-frame sequence adds dark refreshes between them; a recorder sampling that at 30 or 60 frames a second lands on a different eye each time. That is what a viewer sees as the picture jumping sideways and flashing. Only the glasses resolve the sequence, because only they are synchronized to it. No encoder setting fixes this.

So the recorder gets its own picture. Under Input, tick 2D stream view. The presenter then draws one eye, at up to 60 pictures a second, into a second window, without the stereo band, the eye shift, the crosstalk subtraction or the brightness gain - those exist to make an alternating image look right through the glasses and look wrong on a flat capture. Two options sit beside it:

Built 2026-09-22 and not yet watched from the receiving end of a call. The capture exclusion that Cover the display relies on is the same one the whole-screen conversion already uses successfully, but whether a covered window keeps feeding a screen capture has not been confirmed here. If a screen share comes out frozen or black, untick Cover the display and share the stream view window instead; window capture does not depend on that behaviour.

Right eye streams the other eye instead. The glasses keep the full stereo sequence in every case; nothing about the calibration changes.

The stream view is drawn by the presenter, from the stereo pair it is already holding, when the stream swap chain has room. Its Present call requests DXGI_PRESENT_DO_NOT_WAIT; a busy stream frame is skipped instead of waiting for the compositor. Drawing and resizing still cost GPU time. If it fails it turns itself off and reports why; the 3D output continues.

Window-captured games now use the click-through, nonactivating game overlay in fullscreen, including after F11 returns from the embedded preview. Earlier builds only used that path for direct-eye providers, so captured games could fight an activating fullscreen window and bypass overlay compatibility. The captured window can be on another monitor; fullscreen covers the selected output display regardless of the captured window’s position or size. The session log records passthrough and gameOverlay to identify that path. Switching focus to Discord, another monitor or another application leaves both output windows visible. Minimizing the game holds the last captured pair and output position; it does not hide the stereo or stream window. Stop output with the existing Stop control or shortcut.

For repeatable diagnosis of an already running SBS game, start the app with --capture-pid <game PID> --start-fullscreen --stream-view. Add --stream-window for the separate capture window. These options do not launch or modify the game.

The whole-screen AI depth conversion needs none of this: it already hides its output from capture, so a recorder sees the plain 2D desktop.

Whole screen in 3D (AI depth)

Built 2026-09-15 and checked only on the desktop without glasses: the capture, the depth network and the eye images work (--screen-test). Whether it looks right through the glasses, and whether the network’s GPU work disturbs the shutter timing, is not yet verified.

Input/Games > Source > Whole screen (AI depth) converts everything on a display into 3D, the way Leia’s SpaceWalker and Samsung’s Reality Hub do: the display is captured, a depth network (Depth Anything V2 Small, through ONNX Runtime on DirectML) estimates the depth of every pixel, and both eyes are resampled from the picture with that depth. The network runs in its own process, VisionDepth.exe, at a low GPU scheduling class so its work queues behind the presenter.

Games (existing Geo11 fixes)

The left workspace has Tuning and Input/Games tabs. Keep the calibrated output selected. The existing community fix renders the eyes; the app receives completed pairs and presents them in frame sequence.

  1. Install the game’s compatible community fix according to its instructions.
  2. In Input/Games, use Choose game… to select the actual rendering EXE. With the game closed, click Connect game. Geo11 is detected automatically. Native and legacy inputs require their actual output layout; selecting frame sequential cannot turn a mono backbuffer into stereo.
  3. Launch normally. The same tab matches the game’s window and shows whether its stereo provider is available. Click Start game 3D for output over the game with input passed through. Use windowed/borderless mode on the selected output display. Start game capture remains available for feeding the separate preview.
  4. Geo11 depth controls appear under Game depth. They save only when edited or applied; the community fix retains shader corrections and auto-convergence.

The connector supports x86 and x64. Geo11 uses its existing proxy interface; other supported providers use the capture add-on. Classic 3Dmigoto capture does not restore its NVIDIA stereo-rendering backend. See tested capabilities.

Before updating or removing a fix, close the game and use Disconnect adapter. Connection ownership and restoration records live in VisionRestoration.CaptureBackup beside the game EXE.

Existing SBS/TAB modes retain their supplied eye resolution. Katanga supplies full-resolution eyes. The adapter preserves the Geo11 output mode.

Historical trials and troubleshooting

Both game deployments below were rolled back. They are not results for the new shared hook; see current validation for the isolated test results.

Native NVAPI stereo, DX9/10, native DX12 and other media-player integrations need separate backends. VLC SBS/TAB files use the direct movie source above. The old ReShade hook remains nonworking; historical notes are in adapters/README.md. Window capture and AI desktop remain. See runtime documentation for implementation and test scope.

Build and check

Requires Visual Studio 2022 C++ desktop tools, Windows SDK and CMake 3.24+. Third-party dependencies are not part of the repository; tools/Get-Dependencies.ps1 downloads them into third_party/ from their official releases.

.\tools\Get-Dependencies.ps1
.\build.ps1
# Hardware-independent pattern rendering and native UI checks:
Start-Process .\build\bin\Release\VisionRestoration.exe --gpu-test -Wait
Start-Process .\build\bin\Release\VisionRestoration.exe --smoke-test -Wait
Start-Process .\build\bin\Release\VisionRestoration.exe --probe -Wait
# Vblank timing of every output against the presentation timestamps (reports/vblank.txt):
Start-Process .\build\bin\Release\VisionRestoration.exe --vblank -Wait

CTest includes core tests and an integration test using the installed GPU and stereo image fixtures. It checks retained GPU frames across source restart/stop and HDR output format changes without physical emitter writes or display-mode changes. --gpu-test uses WARP; --smoke-test uses the actual GPU and writes an image of the application’s own UI. These checks do not establish optical performance.

Original application code is provided under GPL-3.0-or-later; preserve the upstream notices and licenses. Proprietary firmware is not bundled.

Prepare a game before launch

In the left Input/Games tab, choose the game’s EXE and click Prepare game. The app checks the current display/emitter prerequisites and connects the existing supported capture adapter if needed. Initial adapter connection requires the game to be closed. Existing classic 3Dmigoto installations still require their NVIDIA stereo rendering backend; preparing capture does not provide that backend.

Launch the game normally through its launcher. While prepared, the app watches the exact executable path every 100 ms, including while minimized or on Tuning. It attaches the stereo reader when the matching process publishes its provider, without requiring a game window first. Once a complete pair and a foreground game window exist, the app starts its frame-sequential output automatically. Use windowed/borderless mode on the selected output display. Detection is automatic, not a guarantee of zero startup latency.

The status distinguishes waiting for launch, waiting for the provider, connected/waiting for eyes, and active 3D. When the game process exits, the app remains prepared for its next launch. Cancel preparation / stop game 3D, Stop capture, switching sources/games, or Escape from output cancels preparation. A provider/startup failure is shown as an error, not reported as active 3D. Preparation does not repair a renderer that crashes before providing usable eyes.