Omniverse Realtime Viewer
NVIDIAOfficialCreated by NVIDIA Omniverse
- Skill
- Tool integration
- Software development
- Apache-2.0
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Omniverse Realtime Viewer skill acts as a central routing and architectural framework for developing USD-based 3D viewer applications. It provides a structured approach to composing rendering, scene state, and delivery mechanisms, ensuring that developers can integrate OVRTX rendering, OVStage scene management, and various UI or streaming adapters effectively. The skill emphasizes a modular architecture where the viewer runtime, UI/input adapters, and delivery systems are decoupled, allowing for consistent behavior across local and streamed environments.
What it does
- Provides a routing architecture for USD viewer apps, XR delivery, and GPU-accelerated rendering.
- Defines the separation of concerns between viewer runtime, UI adapters, and delivery systems.
- Offers guidance on integrating OVRTX for high-fidelity 3D rendering.
- Establishes conventions for camera interaction, scene state management, and input handling.
- Supports the implementation of specialized features like stylized rendering and CAE/CFD visualization.
- Provides protocols for agent-to-UI communication and scene control.
When to use it
- When starting the development of a new USD-based realtime viewer application.
- When integrating advanced rendering features like stylized visualization or AOV switching.
- When building XR or spatial editing capabilities into an existing Omniverse application.
- When you need to standardize the architecture for local and streamed viewer deployments.
- When implementing chat-driven scene control or agent-based inspection of a 3D scene.
Advantages
- Promotes a clean, modular architecture that separates rendering logic from UI and transport.
- Ensures consistent behavior across different delivery methods, such as local windows or WebRTC streaming.
- Provides clear paths for extending functionality without disrupting the core viewer runtime.
- Facilitates the integration of complex simulation and visualization data into the viewer.
- Standardizes conventions for scene state, selection, and camera control.
Usage examples
- “How do I set up a basic USD viewer application using the Omniverse Realtime Viewer architecture?”
- The agent will guide you to start with the viewer app reference, resolve dependencies, and implement the core runtime owner to manage the OVStage and OVRTX renderer.
- “I need to add stylized rendering to my existing viewer. Where should I start?”
- The agent will direct you to the stylized visualization references to implement the required USD/Lua/CUDA nodes within your existing runtime owner.
- “How can I enable an AI agent to control the viewer scene?”
- The agent will point to the A2UI Scene Copilot reference to implement an operation interface that allows the agent to send commands through the existing runtime owner.
- “How do I switch between different render outputs like beauty and depth in my viewer?”
- The agent will explain how to use the AOV switching reference to map RenderVars and update the RenderProduct's orderedVars through the runtime owner.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/nvidia/omniverse-realtime-viewer/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip omniverse-realtime-viewer.zip -d .agents/skills
Documentation by NVIDIA Omniverse
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
Omniverse Realtime Viewer
Build responsive USD viewers by composing OVRTX rendering, OVStage scene state, and the delivery/UI libraries appropriate to the app. Use this package for viewer architecture and interaction; use each selected SDK's upstream guidance for installation and exact release-specific APIs.
Start With The App
When delivery is explicit, select its recipe through
references/routing.mdand follow its current phase. Otherwise start withreferences/usd-viewer-app/README.md. For an existing app, keep its architecture and read only the references for the requested change. Broad app, conventions and UI catalogs are lookups as needed.Resolve the selected libraries through
references/dependencies/README.md. Preserve the project's manifest unless an upgrade is requested.Build a working frame and camera interaction in the chosen shell, then add the requested capabilities. Read
references/conventions.mdfor shared input, camera, selection, and protocol conventions.Use
references/viewer-ux-workflow/README.mdfor broader interface design. Loading, selection feedback, errors, and input responsiveness belong in the first working app, alongside rendering.Validate the actual delivery path with
references/validation.md. A browser screenshot does not validate a native window or a different transport.
Architecture
| Owner | Responsibility |
|---|---|
| Viewer runtime | Own the live OVStage, publication clock, OVRTX renderer, scene changes, and render stepping. |
| UI and input adapter | Display frames and copied app state; send user intent to the runtime owner. |
| Storage/query/simulation workers | Perform their assigned work and return results through the selected integration boundary. |
| Delivery adapter | Present locally or stream through ovstream; respect frame ownership and backpressure. |
Use OVRTX for USD/3D rendering. Browser apps display its WebRTC video; local apps present its output through their native shell. A missing GPU means rendering is unverified, not a reason to substitute a browser 3D renderer.
Keep viewer cameras, settings, effects, and transient edits in app-owned session
or runtime state so the source USD stays intact. Serialize scene mutation and
render stepping through the runtime owner. Read
references/ovstage-ovrtx-integration/README.md for that loop, then the population
or data-plane references when implementing scene loading or attribute writes.
Keep expensive loading and metadata work off the UI and render threads. Keep transport details behind a delivery adapter so camera, selection, properties, and loading state can be reused across local and streamed shells.
Add Capabilities As Needed
Use references/routing.md to select camera/picking, scene management, render
settings, cloud assets, simulation, editor tools, deployment, or CAE/CFD
visualization. Read the selected capability's implementation flow and its linked
contract; the full reference catalog is not a prerequisite for a first frame.
For simulation, use the routing reference's Simulation Ecosystem section plus
references/realtime-sim-integration/README.md. For UI-driven forces or control,
add references/interaction-round-trip/README.md.
For example scenes, use references/usd-sample-data/README.md. When a runtime
failure needs diagnosis, use references/troubleshooting/README.md and the
selected SDK's matching release guidance before changing the architecture.
Solid Modeling: Upstream First
For usd-brep, exact BRep, solid modeling, kernel failures, CAD topology, or
BrepArray questions, first read references/dependencies/README.md → USD BRep. Follow the
owning repository's current agent guidance, skills, operation docs, and package
API before selecting local integration references. Discover the upstream router
rather than assuming skill names or directory layouts remain fixed. Upstream
owns modeling semantics, schema rules, tuning, and diagnostics; this package
owns OVRTX display, worker handoff, selection mapping, and publication timing.
GPU Processing And Stylized Viewers
For custom GPU processing, chained outputs and lens sampling, read
references/spg-processing/README.md. For toon, ink, technical/X-Ray styles,
geometry strokes or full wireframe, continue to
references/stylized-visualization/implementation.md. Its USD/Lua/CUDA starting
node and geometry/depth/composite build sequence work with the selected viewer
recipe; use references/stylized-visualization/style-recipes.md for the preset
math and references/stylized-visualization/README.md for supporting contracts.
Implement the result inside the existing OVRTX/runtime owner and deliver the
published processed output. These instructions do not require a sample checkout
or a prior stylized-rendering implementation.
For an optional usd-brep geometry source, first read
references/dependencies/README.md → USD BRep and the owning repository's
current agent guidance, skills, and operation docs; then read
references/stylized-visualization/usd-brep-source.md for the display boundary.
XR Viewers
For headsets, immersive viewers, or spatial editors, start with
references/xr-viewer-recipe/README.md. Resolve SDK setup and contracts through
references/dependencies/ovxr.md; the library owns OpenXR lifecycle and frame
submission. For controllers, hands, navigation, or scene tools, add
references/xr-spatial-input/README.md and
references/ovxr-python-interactions/README.md. For projection-integrated UI,
read references/ovxr-composition-ui/README.md and
references/ovxr-composition-ui-validation/README.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer943 B
- BENCHMARK.md13.4 KiB
- LICENSELicence file added by AutoGineer11.2 KiB
- SKILL.md6.4 KiB
- evals/evals.json7.0 KiB
- references/a2ui-scene-copilot/README.md10.9 KiB
- references/aov-switching/README.md10.5 KiB
- references/cae-cfd-visualization/README.md10.1 KiB
- references/cae-cfd-visualization/cae-data-ingestion.md5.6 KiB
- references/cae-cfd-visualization/coordinate-systems-and-up-axis.md11.0 KiB
- references/cae-cfd-visualization/data-and-operators.md11.7 KiB
- references/cae-cfd-visualization/driving-cae-viz-via-ovstage.md6.4 KiB
- references/cae-cfd-visualization/emitter-and-seed-sources.md16.3 KiB
- references/cae-cfd-visualization/glyphs.md7.1 KiB
- references/cae-cfd-visualization/ovstage-render-and-camera.md11.0 KiB
- references/cae-cfd-visualization/ovui-controls.md13.2 KiB
- references/cae-cfd-visualization/rtwt-blueprint-recreation.md11.9 KiB
- references/cae-cfd-visualization/streaming-cae-viewer.md25.9 KiB
- references/cae-cfd-visualization/temporal-playback.md9.2 KiB
- references/cae-cfd-visualization/usd-authoring-and-materials.md21.5 KiB
- references/cae-cfd-visualization/volume-rendering.md2.5 KiB
- references/camera-auto-select/README.md9.0 KiB
- references/camera-controls/README.md20.9 KiB
- references/camera-picker/README.md9.5 KiB
- references/cloud-assets/README.md4.5 KiB
- references/cloud-deployment/README.md19.6 KiB
- references/cloud-deployment/container-image-build.md2.2 KiB
- references/cloud-deployment/gpu-container-runtime.md2.8 KiB
- references/cloud-deployment/nvcf-self-hosted.md8.4 KiB
- references/cloud-deployment/nvcf-viewer-container-contract.md4.8 KiB
- references/cloud-deployment/webrtc-network-diagnostics.md3.9 KiB
- references/cloudxr-opaque-data-channel/README.md1.1 KiB
- references/conventions.md7.4 KiB
- references/cpp-native-viewer/README.md4.9 KiB
- references/cpp-native-viewer/build-details.md5.2 KiB
- references/cpp-native-viewer/interaction-features.md11.3 KiB
- references/cpp-native-viewer/presentation-loop.md8.0 KiB
- references/cpp-native-viewer/project-build.md3.4 KiB
- references/cpp-native-viewer/renderer-session.md7.1 KiB
- references/cpp-native-viewer/validation.md3.4 KiB
- references/dependencies/README.md6.8 KiB
- references/dependencies/electron-shm.md1.5 KiB
- references/dependencies/environment-validation.md6.6 KiB
- references/dependencies/frontend.md2.3 KiB
- references/dependencies/local-openusd-gpu.md8.7 KiB
- references/dependencies/nvidia-runtime.md14.8 KiB
- references/dependencies/ovrtx.md3.1 KiB
- references/dependencies/ovstream.md3.3 KiB
- references/dependencies/ovxr.md2.3 KiB
- references/dependencies/quick-setup.md2.6 KiB
- references/dependencies/skia-yoga.md936 B
- references/electron-shm-viewer/README.md2.5 KiB
- references/electron-shm-viewer/architecture-project.md6.3 KiB
- references/electron-shm-viewer/electron-client.md6.5 KiB
- references/electron-shm-viewer/protocol-interaction-lifecycle.md7.9 KiB
- references/electron-shm-viewer/python-shm-server.md5.5 KiB
- references/electron-shm-viewer/validation.md2.8 KiB
- references/exact-brep-in-usd/README.md2.5 KiB
- references/gl-viewport-overlay/README.md8.0 KiB
- references/gl-viewport-overlay/architecture.md4.1 KiB
- references/gl-viewport-overlay/example-gizmo.md5.5 KiB
- references/gl-viewport-overlay/interaction-pattern.md4.0 KiB
- references/gl-viewport-overlay/projection-alignment.md4.3 KiB
- references/headless-shm-cli/README.md12.3 KiB
- references/huggingface-usd/README.md7.7 KiB
- references/interaction-round-trip/README.md40.1 KiB
- references/local-viewer/README.md17.8 KiB
- references/native-picking-selection/README.md13.1 KiB
- references/navigation-presets/README.md4.6 KiB
- references/navigation-presets/preset-camera-ops.md5.1 KiB
- references/newton-physics/README.md8.8 KiB
- references/object-selection/README.md11.1 KiB
- references/ovrtx-rendering/README.md23.0 KiB
- references/ovstage-data-plane/README.md3.5 KiB
- references/ovstage-live-geometry/README.md3.3 KiB
- references/ovstage-ovrtx-integration/README.md5.0 KiB
- references/ovstage-population/README.md3.7 KiB
- references/ovstage-runtime/README.md3.1 KiB
- references/ovui-library/README.md3.3 KiB
- references/ovui-library/api-reference.md4.3 KiB
- references/ovui-library/extending.md4.8 KiB
- references/ovui-local-viewer-recipe/README.md4.7 KiB
- references/ovui-local-viewer-recipe/interaction-features.md16.9 KiB
- references/ovui-local-viewer-recipe/project-structure.md6.2 KiB
- references/ovui-local-viewer-recipe/setup-shell-renderer.md16.4 KiB
- references/ovui-local-viewer-recipe/validation-build-order.md6.1 KiB
- references/ovwidgets-editor-shell/README.md5.4 KiB
- references/ovxr-composition-ui-validation/README.md7.1 KiB
- references/ovxr-composition-ui-validation/evidence-gates.md3.5 KiB
- references/ovxr-composition-ui-validation/frustum-placement.md2.4 KiB
- references/ovxr-composition-ui-validation/library-only-validation.md8.1 KiB
- references/ovxr-composition-ui-validation/owned-orchestration.md5.3 KiB
- references/ovxr-composition-ui-validation/viewer-evidence.md4.0 KiB
- references/ovxr-composition-ui/README.md8.5 KiB
- references/ovxr-composition-ui/async-raster-pipeline.md5.0 KiB
- references/ovxr-composition-ui/compositor-passes-and-sync.md6.4 KiB
- references/ovxr-composition-ui/depth-tools.md5.0 KiB
- references/ovxr-composition-ui/editor-document-model.md4.8 KiB
- references/ovxr-composition-ui/experience-quality.md8.5 KiB
- references/ovxr-composition-ui/foveation-and-edge-math.md3.5 KiB
- references/ovxr-composition-ui/library-only-compositor.md10.4 KiB
- references/ovxr-composition-ui/native-build-and-discovery.md4.6 KiB
- references/ovxr-composition-ui/performance-and-telemetry.md7.9 KiB
- references/ovxr-composition-ui/primary-projection-compositor.md3.5 KiB
- references/ovxr-composition-ui/primary-projection.md4.1 KiB
- references/ovxr-composition-ui/projection-and-depth.md5.3 KiB
- references/ovxr-composition-ui/raster-abi.md3.0 KiB
- references/ovxr-composition-ui/sdk-frame-backend.md1.6 KiB
- references/ovxr-composition-ui/skia-yoga.md2.8 KiB
- references/ovxr-composition-ui/spatial-interaction.md5.6 KiB
- references/ovxr-composition-ui/spatial-surfaces-and-interaction.md10.4 KiB
- references/ovxr-composition-ui/telemetry-contract.md3.8 KiB
- references/ovxr-composition-ui/validation-and-live-gates.md3.9 KiB
- references/ovxr-foveation-and-display/README.md1.1 KiB
- references/ovxr-frame-loop-and-readback/README.md1.2 KiB
- references/ovxr-library-runtime/README.md1.1 KiB
- references/ovxr-library-runtime/ar-compositing.md4.4 KiB
- references/ovxr-library-runtime/frame-input-order.md2.2 KiB
- references/ovxr-library-runtime/library-only.md1.1 KiB
- references/ovxr-library-runtime/live-ar-controls.md4.3 KiB
- references/ovxr-library-runtime/mirror-lifetime.md4.1 KiB
- references/ovxr-library-runtime/settings-and-lifetime.md3.9 KiB
- references/ovxr-library-runtime/viewer-assembly.md225 B
- references/ovxr-openxr-runtime/README.md1012 B
- references/ovxr-python-interactions/README.md1.8 KiB
- references/ovxr-python-interactions/architecture.md5.5 KiB
- references/ovxr-python-interactions/feature-patterns.md7.4 KiB
- references/physics-simulation/README.md7.1 KiB
- references/prim-info-display/README.md10.9 KiB
- references/prim-pick-effects/README.md7.3 KiB
- references/prim-transform-safety/README.md8.6 KiB
- references/realtime-sim-integration/README.md7.0 KiB
- references/render-settings/README.md12.6 KiB
- references/routing.md37.7 KiB
- references/section-views/README.md5.8 KiB
- references/seg-outline-highlight/README.md1.5 KiB
- references/selection-animation/README.md5.0 KiB
- references/selection-feedback/README.md7.5 KiB
- references/smlib-brep-pitfalls/README.md2.5 KiB
- references/spg-processing/README.md8.0 KiB
- references/stage-attribute-reads/README.md6.2 KiB
- references/stage-hierarchy/README.md20.3 KiB
- references/stage-hierarchy/fallback-worker-protocol.md7.4 KiB
- references/stage-loading/README.md7.1 KiB
- references/stage-management/README.md6.6 KiB
- references/stage-queries/README.md6.1 KiB
- references/streaming-client/README.md25.6 KiB
- references/streaming-lifecycle/README.md4.6 KiB
- references/streaming-messages/README.md19.5 KiB
- references/streaming-messages/server-handler-map.md3.1 KiB
- references/streaming-server/README.md17.7 KiB
- references/streaming-server/frame-loop-and-continuity.md3.8 KiB
- references/streaming-viewer-recipe/README.md1.9 KiB
- references/streaming-viewer-recipe/client-protocol.md14.2 KiB
- references/streaming-viewer-recipe/interaction-features.md13.8 KiB
- references/streaming-viewer-recipe/project-structure.md7.3 KiB
- references/streaming-viewer-recipe/server-runtime.md20.2 KiB
- references/streaming-viewer-recipe/validation-build-order.md8.5 KiB
- references/streaming-vs-local/README.md9.4 KiB
- references/stylized-visualization/README.md8.7 KiB
- references/stylized-visualization/aov-guide-contracts.md8.1 KiB
- references/stylized-visualization/implementation.md11.4 KiB
- references/stylized-visualization/line-compositor-delivery.md7.7 KiB
- references/stylized-visualization/mesh-xray.md10.1 KiB
- references/stylized-visualization/reproduction-validation.md10.2 KiB
- references/stylized-visualization/style-composition-contract.md5.4 KiB
- references/stylized-visualization/style-recipes.md14.7 KiB
- references/stylized-visualization/usd-brep-source.md4.9 KiB
- references/subprocess-geometry-bridge/README.md3.5 KiB
- references/tauri-local-viewer/README.md6.7 KiB
- references/tauri-shm-transform-gizmo/README.md12.3 KiB
- references/transform-manipulator/README.md17.1 KiB
- references/troubleshooting/README.md11.2 KiB
- references/troubleshooting/scenario-playbooks.md24.7 KiB
- references/usd-sample-data/README.md12.0 KiB
- references/usd-viewer-app/README.md5.0 KiB
- references/validation.md6.3 KiB
- references/viewer-backend-interface/README.md20.1 KiB
- references/viewer-control-patterns/README.md4.8 KiB
- references/viewer-data-view-patterns/README.md5.6 KiB
- references/viewer-feedback-status/README.md5.0 KiB
- references/viewer-input-routing/README.md11.9 KiB
- references/viewer-layout-patterns/README.md4.7 KiB
- references/viewer-ux-workflow/README.md5.2 KiB
- references/viewport-overlays/README.md9.9 KiB
- references/viewport-overlays/cuda-compositing.md6.6 KiB
- references/viewport-resize/README.md4.0 KiB
- references/vulkan-compositing/README.md6.1 KiB
- references/vulkan-compositing/depth-overlays.md15.7 KiB
- references/vulkan-compositing/interop-and-lifecycle.md6.6 KiB
- references/webgl-shm-transport/README.md14.5 KiB
- references/windows-native-setup/README.md11.6 KiB
- references/xr-client-connection/README.md1.1 KiB
- references/xr-client-message-contract/README.md8.5 KiB
- references/xr-desktop-mirror/README.md13.8 KiB
- references/xr-session-modes-and-passthrough/README.md930 B
- references/xr-spatial-input/README.md2.3 KiB
- references/xr-spatial-input/advanced-tools.md5.2 KiB
- references/xr-spatial-input/controllers.md16.3 KiB
- references/xr-spatial-input/feature-validation.md4.9 KiB
- references/xr-spatial-input/gesture-arbitration.md4.9 KiB
- references/xr-spatial-input/gesture-filtering.md5.5 KiB
- references/xr-spatial-input/hand-recognizers.md4.0 KiB
- references/xr-spatial-input/hands.md10.3 KiB
- references/xr-spatial-input/navigation.md13.5 KiB
- references/xr-spatial-input/physics-interaction.md23.2 KiB
- references/xr-spatial-input/simulation-lifecycle.md5.9 KiB
- references/xr-spatial-input/stage-composition.md4.9 KiB
- references/xr-spatial-input/teleport-acceptance.md5.2 KiB
- references/xr-spatial-input/webxr-client.md3.9 KiB
- references/xr-tracking-anchor-and-scale/README.md950 B
- references/xr-viewer-recipe/README.md10.5 KiB
- skill-card.md7.7 KiB
- skill.oms.sig58.2 KiB
references/troubleshooting/scenario-playbooks.md
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
Troubleshooting Scenario Playbooks
Server Startup
Check first:
OVRTX_SKIP_USD_CHECK=1is set before ovrtx is imported or constructed.OVRTX_BIN_PATHpoints at the ovrtxbindirectory when renderer plugins or MDL materials fail.OVSTREAM_LIB_PATHpoints at the native ovstream library directory whenovstreamcannot import.The process uses one USD import strategy: ovrtx-first for streaming, documented local-viewer ordering for lightweight local paths, or a separate
pxrworker on Windows.OVStage-backed viewers have one parent runtime owner for stage lifetime, ordinals, write floors, renderer attachment, and publication.
pxr/OpenUSD queries and OVPhysX USD population run in workers unless the exact ABI/import path is verified.A GPU is visible and the selected CUDA device is not already held by a stale Omniverse Realtime Viewer process.
Signaling and media ports are available.
For a native startup stall, reduce to a fresh-process probe with the same
packages and no UI, transport, or pxr imports. Record versions and elapsed
before/after markers around registration, renderer/stage creation, attachment,
population/publication, first step, output mapping, and teardown. Bound the
process and capture the stack at the first incomplete phase; allow the existing
300-second cold-cache budget for the first step. An attachment stall is not
first-step shader warmup. Compare initialization orders only in fresh processes
and against the selected upstream example; retain the failing/passing evidence
rather than treating one host's workaround as a universal SDK requirement.
A failed nvidia-smi query or display-related Vulkan warning alone does not
establish that headless rendering is unavailable; identify the failing runtime
call before requesting host changes.
Logs to inspect:
Python server stdout/stderr, including ovrtx construction and ovstream initialize logs.
Any app log file configured by the generated viewer, commonly under
logs/or the current working directory.pxr_worker.pystderr if hierarchy/properties run in a subprocess.Native crash output from the terminal that launched the server.
OVPhysX worker stderr/stdout files if physics was requested.
Usual fixes:
Set the environment before launching Python, then fully restart the server.
Move ovrtx bundled plugin libraries first in the dynamic library path if another USD build is loaded.
Kill stale GPU Omniverse Realtime Viewer processes after a renderer crash or hang.
Change the signaling port if another process owns it.
If
PhysX.attach_ovstage(stage, read_ordinal=...)reports missing OVStage bridge symbols, use the bounded worker path rather than parent-process OVPhysX population.
Server-Side Diagnostics
Run these from the server machine:
nvidia-smi
ps -ef | rg 'python|ovstream|viewer|vite'
ss -ltnup | rg '49100|47999|8554'
lsof -iTCP:49100 -sTCP:LISTEN
env | rg 'OVRTX|OVSTREAM|LD_LIBRARY_PATH|PATH'Interpretation:
nvidia-smishows whether the GPU is visible and which PIDs still own GPU memory.psidentifies duplicate servers, stale renderers, and runaway frontend dev servers.ss/lsofconfirms whether signaling port49100, WebRTC media UDP, or RTSP port8554is already bound.Environment output confirms whether the launched process actually received the paths you set in the shell.
Browser Cannot Connect
Check first:
The server was started before the frontend connects.
DirectConfig sets explicit fixed
width,height,codec: 'H264', andcodecList: ['H264']unless a verified deployment profile selected another codec.The frontend uses standalone ovstream Direct config:
signalingServerandsignalingPort.The frontend does not set
mediaServer,mediaPort,signalingPath, or auth/session fields inDirectConfig. If an orchestrator launches the container, map its exposed endpoint tosignalingServerandsignalingPort.Local development uses
webrtc_public_ip=127.0.0.1or an explicitly reachable LAN IP.Only one WebRTC client is connected unless the server intentionally replaces the old session.
For Tableau or another embedded host, run the H264 preflight before connect and record whether the page is framed and whether
navigator.mediaCapabilities.decodingInfois exposed. Its absence is an embed-host diagnostic, not an automatic codec failure.
Logs to inspect:
Browser console for WebSocket/signaling errors.
Browser Network tab for the signaling request and WebSocket upgrade. If
POST /sign_inreturns HTTP 501, verify the frontend did not follow a standalone-Direct connection profile intended for a different streaming product or inject auth/session fields before changing the ovrtx or ovstream server.Server logs for connection callbacks.
chrome://webrtc-internalsoredge://webrtc-internalsfor ICE, DTLS, and media state.The preflight log: explicit H264 DirectConfig, iframe status, MediaCapabilities availability/result, video
readyState, and decoded-frame counter orcurrentTime.
Usual fixes:
Match frontend host/port to the server's WebRTC signaling config.
Add explicit H264 codec fields when logs mention
Could not get encoded frameor the browser connects with black video and no decoded frames.Remove
mediaPortfrom frontend config.Reduce aggressive reconnect settings when logs show repeated previous-session messages.
Close the old browser tab or restart the ovstream server if the previous session is stuck.
If MediaCapabilities is absent only in the embed, validate the same build standalone and in-frame. Escalate the host-frame media-policy limitation with that evidence; do not claim H264 is unsupported solely from the missing API.
Video Does Not Stream
Check first:
server.on_connection,server.on_message, andserver.on_inputare registered beforeserver.start().The render loop streams a fallback or last-good BGRA frame while a client is connected, even before a USD stage is loaded.
The render loop is calling
renderer.step()with the exact active RenderProduct path.LdrColorexists in the returned render vars.The app submits BGRA8 frames to ovstream, not ovrtx RGBA8.
CUDA or CPU frame buffers stay alive until
stream_video()returns.Render var data is copied while the owning
RenderProductSetOutputsis still alive; frame views are not held across laterrenderer.step()calls.Stream width, height, and pitch match the frame buffer.
The
<video>element exists beforeAppStreamer.connect().In an embedded host, the H264 preflight was recorded before connect; after connect, the video reaches
HAVE_CURRENT_DATAand decoded-frame count orcurrentTimeadvances.On cold start, the first
renderer.step()may spend 2-5 minutes compiling RTX shaders or pipelines before producing a frame.
Logs to inspect:
Server frame counters and render product names.
ovrtx logs for first-run shader or pipeline compilation progress.
ovstream warnings from the log callback.
Browser media element errors in the console.
WebRTC internals inbound video stats: frames decoded, frames dropped, resolution, bitrate.
Embedded-host preflight output: iframe status, MediaCapabilities availability/result, and the explicit H264 config.
Usual fixes:
Fix RenderProduct/session layer setup before changing WebRTC code.
If the session disconnects in roughly 1-2 seconds before app messages arrive, add idle/fallback frame submission before changing scene loading.
Add or repair RGBA-to-BGRA conversion when red and blue are swapped.
Keep browser streaming at the configured fixed resolution. If that startup configuration changes, restart/reconnect instead of resizing the live stream.
Copy frame data inside the same render-loop step when passing it to an encoder, stream, UI bridge, or worker queue.
Use at least a 300 second timeout for the first rendered frame on a cold cache, then expect later steps to be much faster.
Local ovui Window Is Black Or Blank
Use this for local desktop viewers where ovrtx renders in-process and ovui presents copied RGBA frames.
Check first:
Save a direct ovrtx
LdrColorartifact from the same RenderProduct and RenderVar path used by the window.Push a synthetic RGBA gradient through the exact ovui provider/widget path and capture a desktop screenshot of the window.
Verify the image widget has nonzero computed size, visible opacity, and is not covered by an opaque overlay.
Build ovui style colors with
ui.color("#RRGGBB"); integer colors are0xAABBGGRR.Verify only one owner calls
renderer.step(), and no step overlapsopen_usd*, reference mutation, orreset_stage().
Interpretation:
Direct
LdrColoris blank: debug scene loading, camera path, render product, render var source, camera transform, stage lighting, and material/plugin resolution.Direct
LdrColoris nonblank but the synthetic ovui frame is blank: debug ovui presentation, provider updates, widget layout, and main-loop stepping.Direct
LdrColoris nonblank and the synthetic frame paints, but live frames stay blank: debug copied-frame lifetime, provider update calls, and whether the ovui loop is presenting the latest copied frame.
Usual fixes:
Prove presentation with the synthetic frame before changing camera or USD composition.
If dynamic byte-provider updates do not paint in the active build, validate with a known-good ovui-native path such as a
RasterImageProviderscreenshot/frame fallback.Render or warm up one direct ovrtx frame before entering the long-running ovui loop when startup ordering is unstable.
Move continuous rendering into one render worker that owns renderer mutation; let the ovui/main loop present only the latest copied RGBA frame.
Electron SHM Viewer
Use this for local separate-process Electron viewers where the Python server owns ovrtx rendering and Electron only presents already-rendered pixels through SharedArrayBuffer and WebGL texture upload.
Check first:
Black viewport in Electron: check the canvas
desynchronizedcontext flag and remove it under Xvfb, verify SAB delivery, and log frame sequence numbers on both sides.Wrong colors: BGRA/RGBA swap was not applied, or
GL_BGRA_EXTis not available.SHM segment not found: server was not started with
--shm, or the stream name does not match the Electron client.N-API addon won't build:
node-gypis missing, the Node ABI does not match Electron, orlibovstream_shm_client.sois missing.SharedArrayBuffer unavailable: COOP/COEP headers are missing in Electron
BrowserWindowwebPreferences.Electron shows "SHM connected" but no frames: AsyncWorker vs ThreadSafeFunction issue in Electron; use TSFN for frame callbacks.
Frame stutter at >30fps: check the frame pacing throttle and confirm the renderer updates with
texSubImage2Dinstead of reallocating withtexImage2D.
Logs to inspect:
Python server startup arguments, especially
--shm, stream name, frame size, ring-buffer size, and frame counters.Native N-API addon build logs for ABI, include path, and
libovstream_shm_client.soresolution errors.Electron main-process logs for BrowserWindow isolation, preload setup, and native addon load failures.
Electron renderer logs for SAB byte length, frame sequence numbers, pixel format, and WebGL extension availability.
Usual fixes:
Start the server in SHM mode with the same stream name the Electron client uses.
Configure Electron so SharedArrayBuffer is available through the isolated preload/contextBridge path.
Use ThreadSafeFunction for native-to-JavaScript frame notifications instead of relying on AsyncWorker callbacks.
Remove the desynchronized canvas context flag when running under Xvfb.
Apply the expected BGRA/RGBA conversion path or use
GL_BGRA_EXTonly after checking support.Reuse the WebGL texture with
texSubImage2Dand throttle presentation to the intended frame rate.
Data Channel Does Not Work
Check first:
Frontend sends only after streaming status is connected.
Streaming status
connectedfollows confirmed SDK start success; see client readiness. Prove decoded frames separately.Server send helper checks that a client is connected before
send_message.The server unwraps browser library messages that contain
messageType,messageRecipient, and nesteddata.Exact event names match on both sides:
openStageResult,getChildrenResult,stageSelectionChanged,getPropertiesResponse.The frontend
onCustomEventrouter is registered before responses arrive, or the server proactively pushes state on connect.Slow USD queries are not running directly inside ovstream callback threads.
Logs to inspect:
Raw incoming data-channel messages on the server before dispatch.
Frontend
onCustomEventpayloads.Browser console for JSON parse errors.
Server handler map misses or "unknown event" warnings.
Usual fixes:
Unwrap the AppStreamer envelope before reading
event_type.Send initial
openStageRequestand viewport app commands after confirmed SDK start success, without waiting for a decoded scene frame.Add one shared message-name reference and update both frontend and server routers.
Push current stage, hierarchy root, selection, loading state, and render settings after a reconnect.
Queue slow work for the render/runtime thread.
Frame Looks Wrong
Check first:
Red/blue swapped means ovrtx RGBA was sent to ovstream without BGRA conversion.
Black frame means invalid camera relation, bad camera transform, missing resolution, wrong RenderVar
sourceName, or wrong RenderProduct path.Magenta materials mean MDL resolver paths are wrong, usually missing
OVRTX_BIN_PATHor plugin library path.Frozen frame means
renderer.step()stopped, a buffer lifetime bug exists, or the browser is still connected to an old session.For invalid output-handle errors, check output and renderer lifetimes; pass owned copies from inside each RenderVar map context to downstream consumers.
Stale GPU hangs after crashes usually mean an old Python process still owns GPU resources.
GPU utilization can show 0% during first-run shader compilation; inspect logs before assuming a graphics hang.
Logs to inspect:
ovrtx warnings about RenderProduct, RenderVar, camera, material, and MDL resolution.
Per-frame counters on the render loop and stream submission.
nvidia-smiprocess and memory output.Browser WebRTC internals for decoded frame count.
Usual fixes:
Repair stage-loading inline/session data before tuning quality settings.
Set
OVRTX_BIN_PATHand put ovrtx plugin libraries first.Copy mapped render vars before leaving the step context, and never reuse frame views across steps.
Restart the Python process after native-library or import-order changes.
Kill stale render PIDs before relaunching.
Scene Will Not Load
Check first:
The requested path exists from the server process, not just from the browser.
Asset root, allowed schemes, cache path, and user-provided path validation agree.
Inline root sublayer paths resolve from the server process and preserve relative asset resolution.
The viewer creates Camera -> RenderProduct -> RenderVar -> RenderSettings data for every load.
reset_stage()andopen_usd*()do not run concurrently withrenderer.step().
Logs to inspect:
openStageRequestURL and resolved server path.pxr stage-open or worker errors.
ovrtx stage load and RenderProduct errors.
Missing texture, sublayer, and asset resolver warnings.
Usual fixes:
Resolve paths on the server and send clear
openStageResulterrors to the frontend.Keep generated inline/session content stable until the load operation completes and a valid frame is produced.
Rebuild session render prims after every reset.
Write wrapper files near the source asset or preserve directory structure in the cache.
OVStage And OVPhysX Boundary
Use this when runtime transforms, physics impulses, drop tests, or OVStage-backed render updates crash, no-op, or desynchronize.
Check first:
The parent viewer process owns OVRTX, live OVStage/session state, ordinals, write floors, renderer attachment, and publication.
UI/data-channel callbacks enqueue runtime commands; they do not mutate OVRTX or OVStage directly.
OpenUSD/pxr queries run in a worker unless direct imports were verified for the exact OVRTX/OVStage/USD wheel set.
PhysX.attach_ovstage(stage, read_ordinal=...)was probed against the exact installed OVStage/OVPhysX ABI before using in-process attach.If
attach_ovstagefailed or was not probed, the OVPhysX worker path runs only in a bounded child worker, never in the already-running parent viewer process.Physics worker results include selected path, matrices or translations, nonzero displacement/rotation when requested, child return code, and diagnostics.
Parent writes accepted pose samples through OVStage/session state at monotonic ordinals and renders only committed publications.
Known failure signatures:
Missing
ovstage_register_consumer,ovstage_register_output_buffer,ovstage_publish,ovstage_query_changes,ovstage_read_attribute, orovstage_write_attributeduringPhysX.attach_ovstage(stage, read_ordinal=...)means the installed OVStage wheel does not export the bridge symbols OVPhysX expects.A native crash after parent-process OVPhysX population usually means competing USD population entered the process that owns OVRTX/OVStage.
Duplicate USD registries,
_tffailures,TfType::AddAlias, or repeated USD plugin/type aliases point to mixed USD runtimes in one process.
Usual fixes:
Move physics simulation to a child process and return structured JSON pose samples.
Keep worker stdout JSON-only and put native logs on stderr or in log files.
Recreate the parent runtime after ABI/import-order changes instead of trying to recover native state in place.
Include the parent/worker process model and OVStage write/consume ordinals in focused validation proof for physics demos.
Camera Does Not Move
Check first:
In WebRTC streaming, camera input normally arrives through NVST/ovstream
InputEventcallbacks. If the data channel is proven live but an explicit pointer/button/wheel test produces no serveron_inputevents, enable the browser-only JSON fallback fromviewer-input-routing; do not enable it alongside native input.In SHM streaming, camera input must use
ovstream.Client(ovstream.ClientType.SHM, stream_name="...").send_input_event(event)from Python, orovstream_client_send_input_event(client, event)from C, not JSONmouseInput.In in-process apps, camera input should call the Python/C++ camera APIs directly.
Mouse coordinates are converted through the rendered image rect, including letterboxing.
The camera path used by controls is the same path referenced by the RenderProduct.
Live transform writes target
omni:xform, not authoredxformOp:*.Writes use the correct transform semantic and create attributes that may not already exist.
Orbit/pan/zoom state remains finite after scene switch or camera restore.
Logs to inspect:
Input callback event type, button/wheel state, and coordinates.
Camera controller target, distance, azimuth/elevation, and matrix values.
Renderer write errors or silent skipped writes.
Usual fixes:
Route input events to a render-thread command queue.
If the browser data channel works but native events are absent, first confirm viewport ownership and callback registration. Then select the mutually exclusive
mouseInputfallback, log that decision, map DOM coordinates to render pixels, and dispatch through the same camera/pick queue.Write
omni:xformwith create-new prim mode for viewer camera updates.Refit the camera to stage bounds after invalid restore state.
Keep drag threshold logic from turning every click into a camera move or every drag into a selection.
Picking Does Not Work
Check first:
The native pick query was enqueued for the same RenderProduct that is stepped next.
The next frame contains the synthetic
ovrtx_pick_hitrender var and its params pass validation.Picked
primPathids are resolved through the renderer path dictionary before publishing UI state.Pixel coordinates are render pixels, not full DOM/widget pixels when letterboxed.
Pending pick state and selectable path sets are cleared after scene reset.
Tree selection expands Xform/Scope paths to descendant mesh paths for highlight feedback.
Logs to inspect:
Pick click coordinates before and after viewport-to-render mapping.
Pick-hit params and resolved prim paths.
Selected prim path, mesh expansion result, and
stageSelectionChangedpayload.
Usual fixes:
Pin the picking RenderProduct to CUDA-visible GPU 0 when required by the active ovrtx build.
Use
renderer.query_primsor native pickability APIs to refresh selectable paths after scene switches.Avoid selecting on left-button release if the drag threshold was exceeded.
Hierarchy, Prim Info, And Variants
Check first:
Direct
pxrimports follow the process import discipline, or USD queries run in a subprocess worker.Worker protocol is one JSON object per line and logs go to stderr, not stdout.
USD values are serialized into JSON-safe primitives before sending to React.
Frontend route names match the active protocol:
getChildrenResult,getPropertiesResponse,getVariantsResponse.Variant changes refresh children, properties, selection expansion, pickability filters, and selected paths that may have changed.
Logs to inspect:
Worker request and response IDs.
Frontend custom-event router output.
Serialization failures for large arrays, matrices, asset paths, or unknown pxr values.
Usual fixes:
Move pxr queries into a worker on Windows or when USD registry conflicts appear.
Cap large arrays in property payloads.
Re-query affected subtree and selected prim info after variant edits.
Scene Switching And Persistent State
Check first:
Scene switch clears selection, info panel, hierarchy cache, pending pick state, animation bindings, and native selection outline state before the new load.
Settings are stored in app JSON and reapplied after each load, not authored into user USD files.
Native selection outline groups are cleared after every stage load when selection feedback is present.
Scene switches should reuse the configured fixed stream/render resolution. For local Omniverse Realtime Viewers or explicit startup configuration changes, rebuild derived buffers, letterbox math, and pick coordinate mapping together.
Logs to inspect:
Stage lifecycle state: idle, loading, streaming, error, shutting down.
Active settings snapshot before and after load.
Concurrent render-step and reset attempts.
Usual fixes:
Serialize stage mutation through the render thread.
Rebuild all derived state after
reset_stage().Send fresh initial state to reconnecting clients.
Frontend Diagnostics
Use these browser tools:
Console: AppStreamer errors, JSON parse failures, unhandled custom events, media element errors, React state warnings.
Network tab: signaling request, WebSocket upgrade, failed CORS/proxy requests, and any
POST /sign_in501 response that indicates the wrong standalone ovstream Direct client profile.chrome://webrtc-internalsoredge://webrtc-internals: ICE candidate pair, connection state, bytes received, frames decoded, frame size, frame rate.React DevTools: connection status, current scene URL, selected prim, hierarchy cache, settings state.
What to look for:
Connected state but zero decoded frames points at stream submission or media negotiation.
Decoded frames increasing but black video points at renderer or scene setup.
Custom events arriving but UI unchanged points at frontend reducer/state wiring.
No custom events arriving points at data-channel send/receive, envelope unwrapping, or server send guard.
Recovery Patterns
Restart the Python server when:
Environment variables, dynamic library paths, import order, ovstream native libraries, or ovrtx plugin paths changed.
The renderer crashed, hung, or left stale GPU memory in
nvidia-smi.Callback registration order or WebRTC server configuration changed.
Fixed stream resolution configuration, codec, or native frame buffer allocation changed.
Restart or reconnect the browser when:
AppStreamer config changed.
A previous WebRTC session is stuck.
The video element or frontend connection provider was rebuilt.
Fix code before restarting repeatedly when:
Event names do not match.
Renderer stage mutation races with
renderer.step().Scene wrappers are written to paths that break relative asset resolution.
Camera writes target
xformOp:*instead ofomni:xform.Picking uses DOM coordinates or
[x, y]buffer indexing.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python, Needs Node.js
The author says: Orchestrator skill. Downstream focused references may require NVIDIA GPUs, ovrtx, ovstream, ovui, OpenUSD, Python, Node/React, Tauri, Electron, C++, or cloud GPU deployment access depending on the selected viewer path.
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- NVIDIA Omniverse
- Publisher
- NVIDIA (Official)
- Source
- NVIDIA/skills · skills/omniverse-realtime-viewer · commit fce3cca
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE-APACHE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA Omniverse or NVIDIA.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download omniverse-realtime-viewer.zip