Proposal: DisplayXR for NVIDIA Omniverse (Kit extension, Leia SR tested) #2331
Replies: 7 comments 1 reply
|
Thanks, this is a well-documented proposal, and the verification against eye captures is exactly the evidence we look for. Hosting: yes in principle. We'll host it as Findings 2 and 3 look like real conformance bugs. Please file them as issues so they get tracked. Finding 5 is the most interesting part. An attach mechanism for engines that own their session would cover Omniverse, Blender, Substance Modeler and others. It overlaps with #697 (windowless target-rect binding), so let's settle the direction there before building more workarounds. An API-layer prototype would be a welcome input to that decision. Finding 4 (legacy compromise resolution) is noted; it ties into the same question. A displayxr.org listing can follow once the repo is in the org and has a tagged release. |
Update: Omniverse now weaves in its own viewport, next to other 3D apps@dfattal, a progress update on this proposal. The code is in joehillthunder/displayxr-omniverse PR #1 (private; you have access). Done since the first post
New findings for discussion
Asks, unchanged: a review, and whether you'd host this as |
Final update: DisplayXR for Omniverse (Kit extension
|
|
Thanks for the update. Putting each app into one of the two target classes (its own viewport, or a dedicated 3D window), with an explicit list of what it needs from a shared host library, is the right framing. It is the input we're using to design that library. The overlay PRs (#2332, #2350, #2353) stay as measurement rigs, as you say. We'll post the host-library API here for review when there's a first draft. |
|
Following up with a result. Woven 3D now runs inside Blender's own 3D View and inside USD Composer's own viewport, with no overlay window. The app keeps its input and presents its own pixels. I checked both seated at a Leia SR panel. How it works: the app renders two off-axis eyes into textures it owns and hands one D3D11 shared texture to the runtime through the
The runtime side is on main: #2373 (texture target), #2379 (windowless weave), #2380 (the hub weaves texture sessions). Correct phase inside a sub-rect of the window needs the Leia plug-in's windowless path, DisplayXR/displayxr-leia-plugin#450. That PR is open; until it ships, the released plug-in phases the weave from the window origin. Measured:
On your Kit black-frame finding: it's the same root cause. Kit drops a frustum that doesn't contain the view axis. The prototype works around it with a frustum that contains the axis, cropped back to the true off-axis frustum. A view-centered frustum option on Kit's side would remove the crop. |
Final update: Omniverse (Kit 110 / USD Composer), 2026-10-27Windowed 3D in Composer
Browser streamKit App Streaming → DisplayXR Browser +
Texture mode (own-viewport 3D, ADR-060): design only, nothing built
For the shared host library
🤖 Generated with Claude Code |
Readiness on the released runtime: Pass (2026-10-28)Installed runtime v2.57.1 with the Leia SR plug-in 2.19.1, the shipped extension code, DisplayXR USD Composer (Kit 110.4), default environment.
This supersedes the earlier v2.55 reading that was over the front budget. Not exercised: the live depth slider. |
Uh oh!
There was an error while loading. Please reload this page.
Proposal: DisplayXR for NVIDIA Omniverse
I've built a Kit extension,
displayxr.omniverse, that runs Omniverse Kit apps in glasses-free 3D on DisplayXR displays. It works with USD Composer, USD Explorer, Isaac Sim, and custom Kit apps. It's tested end to end on a Leia SR laptop. I'd like the maintainers to review it, and to consider adopting it as a DisplayXR integration, for example asDisplayXR/displayxr-omniverse, alongside the Unity and Unreal plugins.Code:
joehillthunder/displayxr-omniverse(private for now). @dfattal is invited as a collaborator. I can add anyone else on the maintainers team.What it does
Omniverse already speaks OpenXR (
omni.kit.xr.system.openxr, D3D12), so there's no renderer plug-in. The extension adds Window ▸ DisplayXR. One click starts 3D, and the panel controls which scene distance lands on the glass.DisplayXR_win64.jsonthrough Omniverse's custom-runtime setting, so the system OpenXR runtime is left alone. Turns on thevrprofile with headset-only behaviour off: floor snapping, height matching, controller models.xrLocateViewson Omniverse's own session (ctypes, via the handlesomni.kit.xr.system.openxrexposes) to measure the rig's convergence and FOV. Then it sets Omniverse's XR user scale:scale = convergence / focus. On this panel the rig measures 2.03 m and 54° × 35°, which matches the documented legacy defaults (0.5 D, about 36° vertical).translate(-k * nominal eye) * camera, which maps the nominal eye exactly onto the viewport camera (verified numerically). Tracked eyes then move around it.weave: target=2610x1137 … canvas=(0,0 2610x1137)). Full screen is one click; it posts F11 to the runtime window, so the runtime's own toggle stays the single source of truth.stereoStrengthsetting seedsDXR_LEGACY_CAMERA_RIG'sipdFactor. It's verified to halve the rendered IPD, and it reapplies on each start, because Omniverse creates a new instance each time.Tested
Kit 110.4 USD Composer (from kit-app-template) with Omniverse XR 109.1, on DisplayXR 2.47.0 and then 2.53.0. Leia SR plug-in 2.16.3, then 2.18.0; SR runtime 1.38. RTX 5070 Ti, Leia SR laptop panel, 3840 × 2400.
schedule_capture_display_frame) confirm the placement:Runtime-side findings (for discussion)
/input/pinch_ext/poseis rejected even thoughXR_EXT_hand_interactionis enabled. Omniverse enables the extension ([XR] Enabled Extension: XR_EXT_hand_interaction) and suggestspinch_extpaths on the controller profiles. DisplayXR returnsXR_ERROR_PATH_UNSUPPORTEDfor every profile (for examplekhr/simple_controller), so every suggested binding fails. That's harmless on a desk display, but per the extension spec those paths should be accepted.XR_ERROR_RUNTIME_FAILUREto Omniverse's frame loop (runSyncSystem) instead of walking the session to STOPPING/EXITING. Omniverse recovers, but logs the error.xrCreateSession/xrLocateViews, so it can't chainXR_DXR_win32_window_bindingorXR_DXR_view_rig. The docking above is the workaround. A runtime-supported way to attach a hosted window to a parent HWND or target rect would make the extension much simpler and also cover Blender and Substance Modeler. That could be an environment variable or app profile, or Design: windowless target-rect binding (decouple position/metrics channel from HWND) #697's windowless target-rect binding. An alternative is an OpenXR API layer that chains the binding and a display rig into the app's calls; I'd be happy to prototype that if it's a direction you'd take.Asks
All reactions