Generated banner for Omniverse Realtime Viewer
Generated logo for Omniverse Realtime Viewer

Omniverse Realtime Viewer

NVIDIAOfficialCreated by NVIDIA Omniverse

  • Skill
  • Tool integration
  • Software development
  • Apache-2.0
  • Medium risk

From the author

Use as the top-level router for Omniverse Realtime Viewer USD apps, XR delivery, SPG GPU processing, stylized rendering, and focused viewer reference documents.
— the description by NVIDIA Omniverse

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

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/nvidia/omniverse-realtime-viewer/download
  2. Unzip 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

  1. When delivery is explicit, select its recipe through references/routing.md and follow its current phase. Otherwise start with references/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.

  2. Resolve the selected libraries through references/dependencies/README.md. Preserve the project's manifest unless an upgrade is requested.

  3. Build a working frame and camera interaction in the chosen shell, then add the requested capabilities. Read references/conventions.md for shared input, camera, selection, and protocol conventions.

  4. Use references/viewer-ux-workflow/README.md for broader interface design. Loading, selection feedback, errors, and input responsiveness belong in the first working app, alongside rendering.

  5. Validate the actual delivery path with references/validation.md. A browser screenshot does not validate a native window or a different transport.

Architecture

OwnerResponsibility
Viewer runtimeOwn the live OVStage, publication clock, OVRTX renderer, scene changes, and render stepping.
UI and input adapterDisplay frames and copied app state; send user intent to the runtime owner.
Storage/query/simulation workersPerform their assigned work and return results through the selected integration boundary.
Delivery adapterPresent 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

references/streaming-viewer-recipe/client-protocol.md

Streaming Client And Protocol

The connection and SDK envelope contracts apply to the chosen browser framework. React provider and widget examples below are optional assembly patterns. Implement only messages/capabilities requested by the app; event names must match both ends.

7. Build The React WebRTC Client

Do this in frontend/src/streaming/ and frontend/src/App.tsx:

  • Create a streaming provider that resolves host and signaling port from URL parameters first, Vite build-time environment variables second, a runtime stream.config.json file third, and browser hostname plus default port last. Follow the per-field resolution and validation rules in Config Resolution.

  • Render the video element with the exact id expected by AppStreamer before attempting to connect.

  • Connect with the Direct stream mode, resolved signaling host/port, fixed width/height, and explicit H264 codec policy from a stable React effect.

  • Before connection, record an embedded-host H264 preflight; after connection, verify an actual decoded frame rather than treating signaling or onStart as video proof.

  • Style the video with object-fit: contain so the fixed-resolution stream scales to the available page area without distortion.

  • Expose status, error message, connection lifecycle events, a guarded send helper, and custom-event subscription to the rest of the app.

  • Mount the viewport video first, then overlay DOM controls such as toolbar, scene picker, tree, property panel, status, and settings.

  • Clean up custom-event subscriptions on component unmount.

Critical contracts:

  • Use signalingServer and signalingPort as in the owning client example; server is a legacy fallback.

  • Do not configure mediaServer or mediaPort for the browser client. SDP negotiates media.

  • Do not construct sign-in URLs, append custom signaling paths, or add auth/session fields to the browser WebRTC config. Orchestrators may launch and route the session, but the frontend should receive a standalone ovstream Direct host and signaling port.

  • The video element must exist before connect starts.

  • Embedded hosts: before connecting, record iframe status and the availability/result of navigator.mediaCapabilities.decodingInfo for H264 when present. This is advisory: an unavailable capability API in Tableau or another host frame must not cause an automatic codec rejection. Continue with the explicit H264 DirectConfig, then require decoded-frame proof.

  • Gate initial data-channel sends on connected status. Connected status means confirmed SDK start success, not just a resolved IN_PROGRESS result. Follow client readiness.

  • Keep the streamer.connect() effect dependent only on immutable connection config. Do not let stateful message routers recreate the effect after openStageResult, getChildrenResult, or status events arrive.

  • Catch rejected streamer.sendMessage() Promises during connect/disconnect windows.

  • Give DOM overlays explicit z-index above the video layer.

  • Use modest reconnect settings to avoid repeated previous session already running churn.

  • Let the streaming library forward mouse, keyboard, wheel, and touch input through NVST's native input channel. Only use mouseInput after the explicit native-callback failure diagnostic in viewer-input-routing; fallback and native input must never run together.

  • Do not send viewport-size messages when CSS layout changes. Keep the stream fixed and rely on NVST letterbox coordinate mapping.

Decision points:

  • If the app should auto-load a default scene, send openStageRequest only after confirmed SDK start success. Do not wait for a decoded scene frame; an idle server may need the request before it can render that frame.

  • If the server loads an initial scene before the browser connects, rely on server initial-state push rather than requiring the frontend to guess.

  • If the user wants a dense tool UI, keep it as DOM overlay around the video. Use server-side overlays only when they must be part of the streamed pixels.

  • If the client runs from a different machine, expose host and signaling port through URL parameters.

Production stream.config.json

For static production builds, fetch an app-owned stream.config.json at startup before resolving the connection. Place it beside the served app entry point (e.g., in the frontend dist/ directory):

{
  "signalingServer": "<server-ip-or-hostname>",
  "signalingPort": 49100
}
  • signalingServer: Hostname or IP of the standalone ovstream signaling server, reachable from the browser; no URL scheme, path, or auth/session fields.

  • signalingPort: Integer WebSocket signaling port (default 49100).

  • This JSON is application configuration, not an SDK connection profile. Map these two resolved values to DirectConfig.signalingServer and DirectConfig.signalingPort in the Direct example. Keep its fixed resolution, explicit H264 policy, callbacks, and media element IDs. Omit server, mediaServer, and mediaPort; SDP negotiates media.

Resolve each field using URL parameters > Vite build-time environment variables > runtime JSON > browser hostname/default port, as specified in Config Resolution. Vite embeds VITE_* values at build time; they work in production but changing a container's environment after building does not update the bundle. Editing the runtime JSON requires no rebuild and takes effect at the next app startup, provided a higher priority URL or built-in environment value does not override that field. Serve fresh configuration at startup (e.g., fetch with cache: 'no-store'). Dev-server proxying does not apply to a static production server.

Common failure modes:

  • An embedded host can hide MediaCapabilities even when the Direct H264 path is viable. Log that absence and validate the same viewer standalone and in the host frame; do not silently substitute a codec or browser renderer.

  • A resolved connect() Promise or onStart without an advancing decoded-frame count is not a working video stream.

  • Connecting before the video element exists produces a connection that cannot display video.

  • Setting media port to the signaling port produces connected-with-no-video failures.

  • Sending requests before data channel readiness drops initial scene loads.

  • Waiting for a decoded scene frame before sending openStageRequest can deadlock idle servers because no stage frame is decoded until the request arrives.

  • One rendered frame then black can be caused by React effect cleanup calling streamer.terminate() after normal app state updates.

  • A frontend waiting for getChildrenResponse while the server sends getChildrenResult leaves the tree empty.

Read for depth: see references/streaming-client and references/streaming-lifecycle for the full React/AppStreamer contract.

8. Define The Data-Channel Protocol

Do this before wiring UI features:

  • Define the app envelope as event_type plus payload in both directions.

  • On WebRTC, register on_app_message: it already receives inner application JSON. Do not unwrap the SDK envelope again. Raw non-WebRTC transports use the explicit adapter in references/streaming-messages/README.md.

  • Register handlers by exact event name.

  • Validate each payload before mutating renderer or USD state.

  • Send all responses and pushed events through one guarded send helper.

This shared example message set supports a complete viewer. Implement only the requested capabilities; an existing app protocol may use other names:

FlowClient eventRequired payloadServer eventRequired payload
Open sceneopenStageRequesturlopenStageResulturl, result, optional error
Reset sceneresetStageRequestempty objectopenStageResult or loading/error eventscurrent URL/result
Loading stateloadingStateQueryempty objectloadingStateResponseurl, loading_state
Progress amountnonenoneupdateProgressAmountamount
Progress activitynonenoneupdateProgressActivityactivity
Get hierarchy childrengetChildrenRequestprim_path, optional filtersgetChildrenResultprim_path, children
Get propertiesgetPropertiesRequestprim_pathgetPropertiesResponseprim_path, properties
Select primsselectPrimsRequestpathsstageSelectionChangedprims
Make prims selectablemakePrimsSelectablepathsoptional status/errorimplementation-specific
Make scene pickablemakePrimsPickableoptional filtersoptional status/errornative pickability state
Get variantsgetVariantsRequestprim_pathgetVariantsResponseprim_path, variants
Set variantsetVariantRequestprim_path, variant_set, variant_selectiongetVariantsResponse plus reload/dirty eventsupdated variants
Set render settingsetRenderSettingRequestsetting key and valuerenderSettingsChangedfull effective settings plus result, applied, applies_at, requires_reload, optional message
Query render settingsgetRenderSettingsRequestempty objectrenderSettingsChangedfull effective settings plus supported-setting capabilities
Camera commandcameraCommandRequestcommand and optional valuescameraStateChangedcurrent camera state
Fit camerafitCameraRequestoptional target prim pathcameraStateChangedcurrent camera state
ErrornonenoneviewerErrorcode, message, optional context

Critical contracts:

  • Client and server event names must agree exactly. The shared example uses openStageResult, getChildrenResult, and stageSelectionChanged; these are application events, not SDK-reserved names.

  • paths: [] in selectPrimsRequest clears selection.

  • Children semantics must be stable: expandable-but-not-loaded is truthy, loaded children is an array, and leaf is null or absent.

  • Properties and variants responses must include the requested prim_path so the frontend can ignore stale responses.

  • Message handlers that load scenes, set variants, or change heavy settings must enqueue work for the render thread.

  • Message handlers that only query cached state may respond immediately if they do not touch renderer-owned state.

  • setRenderSettingRequest must reject keys that are not in the server capability list. Success means the active viewer state changed, or an explicit non-live action was accepted.

  • For runtime prim discovery, use the application-owned OVStage adapter's runtime.query_prims(...) / query_prims_async(...) and return copied, resolved path strings as described in references/stage-hierarchy. Direct renderer queries are only for standalone renderer-owned compatibility paths. Use a pxr worker only for queries the runtime cannot supply; keep native picking and renderer-visible selection groups on OVRTX.

  • Push openStageResult and root getChildrenResult after a client connects if a stage is already loaded.

Decision points:

  • If stage hierarchy queries are slow or risky in the renderer process, move them behind a subprocess owned by stage_queries.py.

  • If multiple UI panels can request the same data, make responses idempotent and keyed by prim path instead of relying on request ordering.

  • Keep implemented message names in one app-owned definition; do not add unused optional handlers just to reproduce the example table.

Common failure modes:

  • Using raw-envelope parsing on WebRTC on_app_message can drop already decoded application events. Keep transport adaptation at its boundary.

  • A response name such as getChildrenResponse fails if the app client expects getChildrenResult; this is an application agreement, not SDK versioning.

  • Sending app state before the data channel is ready causes permanent loading indicators unless initial state is pushed on connection.

Read for depth: see references/streaming-messages, references/streaming-lifecycle, and references/stage-hierarchy for the full protocol and query contracts.

14. Wire Frontend Components

Do this after the stream connects and core messages work:

  • Viewport renders the video element and any DOM overlay controls.

  • Toolbar sends fit camera, reset view, render settings toggle, and debug view commands.

  • ScenePicker lists available scenes and sends openStageRequest.

  • StageTree requests children lazily and sends selectPrimsRequest on row selection.

  • PrimInfoPanel subscribes to selection and requests properties/variants for the active prim.

  • RenderSettingsPanel renders backend-advertised capabilities, displays effective settings, and sends validated changes.

  • StatusBar displays connection, loading state, current scene, FPS if available, and latest viewer error.

Critical contracts:

  • The video element id must match AppStreamer config exactly.

  • Keep data-channel sends behind the streaming provider's connected-state guard.

  • Treat server events as authoritative for loaded scene, selection, settings, and errors.

  • Do not duplicate pointer input handling in DOM unless it is for UI widgets outside the video viewport or the verified, mutually exclusive mouseInput fallback.

  • Clean up event subscriptions when components unmount.

Decision points:

  • If a panel is optional, still keep the provider and message types stable so the feature can be added later.

  • If a UI widget overlaps the video, ensure it does not intercept pointer events meant for camera/selection unless the widget is actively being used.

  • If the app needs keyboard shortcuts, decide which shortcuts are browser UI shortcuts and which should pass through to the streamed app input path.

Common failure modes:

  • DOM overlays intercept all pointer events and camera controls stop working.

  • Frontend local state diverges when it assumes requests succeeded instead of waiting for server events.

  • Components leak subscriptions and process every server event multiple times after navigation.

Read for depth: see references/streaming-client, references/streaming-messages, and references/streaming-lifecycle for the full frontend contracts.

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