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/ovui-local-viewer-recipe/setup-shell-renderer.md

ovui Local Setup, Shell, And Renderer

2. Install Dependencies And Configure The Environment

Read references/dependencies FIRST. Its nvidia-runtime.md file is the source of truth for NVIDIA runtime locations. Do not guess or repeat ovui package URLs, wheel names, artifact locations, or fallback install commands in this recipe.

Do this:

  • Resolve the Python environment from the current NVIDIA-Omniverse/ovui README.md, AGENTS.md, relevant skills/omniverse-ui-* references, and package metadata before creating the venv. Do not hard-code a Python version in generated local ovui setup notes.

  • Install ovrtx using the package guidance in references/dependencies.

  • Install ovstage using the package guidance in references/dependencies when the local runtime uses OVStage as the live stage substrate.

  • Install ovui using the current PyPI package guidance in references/dependencies.

  • Install any selected local UI companion packages from the same ovui package set as the base UI package.

  • Install usd-core only when the app creates a USD query worker. Resolve a release compatible with the selected runtime package set after reviewing the current upstream runtime documentation and release notes. Keep routine pxr imports out of the local process that owns OVRTX and live OVStage unless the exact wheel set and import path are verified.

  • Install ovphysx only in a bounded physics worker or isolated attached-stage compatibility probe unless the selected local app has verified PhysX.attach_ovstage(stage, read_ordinal=...) for the exact OVStage/OVPhysX ABI.

  • Install numpy for matrices, camera math, and CPU frame handling (pip install numpy).

  • Install warp-lang only when the local app needs CUDA-side display or image-processing utilities (pip install warp-lang).

  • Do not install ovstream or frontend streaming packages for a local-only viewer.

Set these environment contracts before starting the app:

  • OVRTX_SKIP_USD_CHECK=1 must be set before ovrtx is imported or the renderer is constructed.

  • OVRTX_BIN_PATH must point at the ovrtx bin directory when materials or renderer plugins fail to resolve.

  • The ovrtx plugin library path must be first in the dynamic library path if another USD build is present.

  • PYTHONPATH must include any ovui import paths required by the selected package.

  • A real display must be available. For headless validation, use a configured X display such as Xvfb.

Decision points:

  • Prefer a subprocess for USD queries and keep the main app focused on ovui, OVRTX, and live OVStage/session state.

  • If USD registry or DLL conflicts appear, treat that as confirmation that pxr queries belong in a subprocess.

  • If OVPhysX attach fails with missing OVStage bridge symbols, run physics in a bounded child process and hand pose samples back to the parent; do not call OVPhysX in the local viewer process.

  • If the user only needs rendering and camera navigation, defer usd-core until hierarchy or bounds queries are required.

  • If running on Windows, read references/windows-native-setup, especially Local ovui On Windows, before changing import order or subprocess strategy. Skip its streaming-only frontend/WebRTC sections for local-only apps.

  • If local UI imports report missing package metadata or missing VIEWPORT_CAMERA_POSE_SOURCE, read references/dependencies and use one compatible local UI package set.

Common failure modes:

  • usd-core detected, duplicate USD debug symbols, _tf import failures, or MDL resolver crashes usually mean import order or library path is wrong, or a second USD-populating runtime entered the viewer process.

  • Magenta materials usually mean OVRTX_BIN_PATH or plugin library path is missing.

  • ovui import failure usually means the selected package was not installed or its required import path is not on PYTHONPATH.

  • A blank or crashing local window in CI usually means no real display is available.

Read for depth: see references/dependencies, references/local-viewer, references/ovrtx-rendering, and references/windows-native-setup for the full environment contracts.

3. Build The ovui Window Shell

Do this in local_app/app.py and local_app/viewport.py:

  • Initialize ovui once with the requested title, width, height, and target FPS.

  • Create one main window that fills the app window.

  • Use a large central viewport, a compact header or toolbar, an optional scene tree or info sidebar, and an optional render settings panel.

  • Put the rendered image inside a viewport frame that can resize with the window.

  • Add a transparent hit surface above the image for mouse input.

  • Route toolbar actions to runtime commands such as load scene, reload, fit camera, clear selection, toggle tree, and toggle render settings.

  • For lightweight viewers, prefer a path field plus one LOAD button for scene loading. Add native file dialogs only after they are validated in the same display/session environment as the app.

  • Wrap ovui callbacks so exceptions are logged and do not tear down the app loop.

Critical contracts:

  • Use fill_app_window=True for the main ovui window so the UI frame tracks GLFW window resizes.

  • The viewport widget must report its current size or provide a reliable fallback so letterbox math remains valid.

  • The transparent mouse surface must be above the image and marked as receiving mouse events.

  • Header, tree, info, and settings widgets must not intercept viewport gestures unless the pointer is actually over those controls.

  • The app loop must call runtime tick/update work from one predictable place.

  • If a selected-prim transform gizmo is visible, enqueue local omni:xform updates through the application-owned transform adapter. The serialized runtime writes OVStage, waits for completion, advances the write floor, and renders the committed ordinal; a visual-only handle is not complete.

Decision points:

  • If the user wants a compact visual tool, keep a header plus viewport and place advanced panels in collapsible sidebars.

  • If the user wants a dense inspection app, reserve width for a stage tree and prim info panel from the start.

  • If the user wants a context menu, show it on right-button release only when the drag threshold was not exceeded.

  • If the user wants a camera gizmo, build it as a local ovui scene overlay rather than using streaming overlay patterns.

  • If the user wants selected-prim movement in a lightweight shell, either use a proven transform manipulator that emits transform deltas or add an app-owned fallback that treats presses near the selected pivot as transform drags.

Common failure modes:

  • Without fill_app_window=True, the OS window resizes but the UI frame stays at the initial dimensions.

  • If the hit surface is behind the image or not opaque to mouse events, orbit, pan, zoom, and picking never receive input.

  • A separate OPEN button can be worse than no button if the native dialog is not implemented or cannot appear under the target display stack. Keep the path-field LOAD path reliable and make dialogs secondary.

  • A selected-prim gizmo that appears but does not move the prim usually means camera/orbit consumed the gesture, or the transform adapter did not write and publish the selected prim's local omni:xform before the render step. See references/prim-transform-safety for parent transforms and animation coordination.

  • Uncaught callback exceptions can stop the app loop or leave drag state stuck.

  • DOM-style browser assumptions do not apply; input comes from ovui callbacks in the desktop process.

Read for depth: see references/local-viewer, references/viewer-input-routing, references/camera-controls, and references/viewport-overlays for ovui shell, input routing, context menu, and local overlay guidance.

4. Construct The ovrtx Renderer Runtime

Do this in local_app/renderer_runtime.py:

  • Create the ovrtx renderer after environment variables are set and import order is settled.

  • Use synchronous rendering first.

  • Store the active render product path, render width, render height, current frame index, and whether a valid stage is loaded.

  • Expose render-loop-only operations for loading a scene, resetting the stage, stepping a frame, mapping render vars, enqueueing and decoding native pick queries, writing native selection outline groups, and writing live attributes.

  • Keep renderer mutations serialized with scene loading, scene reset, settings changes, and camera writes.

  • Use an application-owned OVStage for scene data and attach the renderer to it. Publish runtime mutations through OVStage/session state at monotonic ordinals and render only committed publications. Keep native picking and selection outline groups on OVRTX.

Critical contracts:

  • The application calls renderer.step() explicitly. ovrtx does not run a hidden app loop for the viewer.

  • Pass the exact viewer RenderProduct path to every step call.

  • Extract LdrColor for local image display. It is RGBA8 from ovrtx.

  • For local UI display, copy CPU-mapped pixel data inside the map context before returning it to the widget.

  • Write live camera and object transforms through the OVStage runtime adapter, using local omni:xform values and the publication flow in references/prim-transform-safety.

  • Direct renderer.write_attribute and renderer bindings are only for an explicitly standalone renderer-owned compatibility path. Follow references/ovrtx-rendering for its semantic and create-new prim mode; do not mix those writes with an attached OVStage.

Decision points:

  • If the app only needs basic local viewing, start with LdrColor only.

  • Object selection uses native ovrtx pick queries. Do not add segmentation render vars just to make picking work.

  • If the app needs high-FPS local display, profile CPU readback first before introducing a CUDA-to-UI path.

  • If the renderer reports stale GPU hangs after a crash, inspect running Python GPU processes before changing code.

Common failure modes:

  • Unable to find RenderProduct prim means scene setup did not create the path used by renderer.step().

  • Black frame usually means camera relation, render product resolution, render var source, or camera transform is invalid.

  • Live camera changes doing nothing usually means the app wrote xformOp:transform instead of omni:xform, used existing-only prim mode, or published above the OVStage write floor.

  • Crashes during scene switches usually mean renderer.step() overlapped a reset, load, or layer mutation.

Read for depth: see references/ovrtx-rendering for the full renderer construction, frame extraction, and live attribute contract.

5. Implement Scene Loading

Do this in local_app/scene_loader.py and call it only from the render loop or serialized runtime load path:

  • Resolve the requested URL/path against the configured asset root, allowed schemes, and security policy.

  • Create viewer-owned camera, RenderProduct, RenderVar, and RenderSettings data through one inline root/session USDA string when the user stage lacks viewer render config.

  • Load the user stage without modifying it.

  • Store the viewer camera path and render product path in runtime state.

  • Reset selection, native selection outline groups, stage query caches, pending pick queries, and loading status for the new stage.

  • Fit the camera to the stage bounds unless the user requested preserving the current camera or using an authored stage camera.

Critical contracts:

  • Every loaded stage needs Camera -> RenderProduct -> RenderVar -> RenderSettings wiring that ovrtx can find.

  • The viewer camera path must be the same path used by camera controls when writing omni:xform.

  • Do not inject lights unless the user explicitly asks for viewer-controlled lighting.

  • Include segmentation render vars only for explicit debug/AOV display modes, not for picking.

  • Prefer OVStage population.open_usd_from_string() for inline roots that sublayer the user USD and author viewer render config. Publish the ordinal before the attached renderer consumes it.

  • Do not call renderer-owned reference or layer-add APIs in an attached viewer; use OVStage population operations through the serialized runtime path.

Decision points:

  • Use a single inline root USDA string with subLayers = [@user_scene@] when the user file needs viewer camera/render-product/render-var data. Copy source upAxis and metersPerUnit onto that root as described in stage-loading.

  • If the user stage has an authored camera and the requested policy is stage-camera, copy its focal length, apertures, clipping range, and transform into the viewer camera.

  • If the user requests persistent camera across scene switches, keep camera state but sanitize and refit only when the old state is invalid for the new bounds.

  • If the user requests viewer lighting controls, add explicit viewer-owned light prims only with a verified live apply path or an explicit reload/profile workflow; otherwise leave lighting untouched and omit live lighting controls.

Common failure modes:

  • Inline roots that omit or misquote the user sublayer path fail composition or break relative asset resolution.

  • Camera path mismatch makes input appear connected but the view never moves.

  • A stage-load operation that reports an error must not be treated as a successful load just because the enqueue call returned.

Read for depth: see references/stage-loading, references/render-settings, references/selection-feedback, and references/stage-hierarchy for the full scene setup contract.

6. Display The Rendered Image

Do this in local_app/viewport.py:

  • Create an ImageBridge with the render width and height.

  • Display the bridge provider through an ovui image widget using preserve-aspect fit.

  • Before connecting ovrtx output, push a synthetic RGBA gradient through the same provider path and capture a window screenshot proving the native widget paints nonblank, non-solid pixels.

  • On each rendered frame, update the bridge with copied RGBA pixels from LdrColor.

  • Compute the visible image rectangle inside the viewport widget after every resize.

  • Store the current widget size, visible image offset, visible image size, render width, and render height for input mapping.

  • Show explicit idle, loading, and error states when no frame should be displayed.

Critical contracts:

  • The ovrtx LdrColor buffer is RGBA8 and is suitable for local image display through ImageBridge.

  • Copy CPU-mapped pixel data while the render var map context is still open.

  • Preserve-aspect display creates letterboxing. All pick and camera coordinates must pass through the same letterbox transform.

  • If render resolution changes, recreate or resize all dependent state: render product, ImageBridge, letterbox math, pending pick coordinate state, and viewport overlays.

  • Do not run scene load/reset work while the image update is reading render output.

  • A nonblank direct LdrColor artifact plus a blank ovui window points at presentation, not scene setup. Fix or switch the ovui presentation path before changing camera, render product, or USD composition.

  • If ImageBridge or ByteImageProvider updates do not paint in the active ovui runtime, validate with another ovui-native presentation path such as a RasterImageProvider screenshot/frame fallback instead of continuing to debug renderer state.

Decision points:

  • If the target is a simple viewer, keep render resolution fixed and let the image widget scale with letterboxing.

  • If the target requires pixel-perfect viewport resolution, treat resize as an explicit render product reconfiguration path.

  • If the app needs a screenshot command, read from the same copied LdrColor frame used by display unless a higher-quality render path is requested.

  • If CPU readback is too slow, investigate a GPU-native UI path only after the basic Omniverse Realtime Viewer is correct.

Common failure modes:

  • Reading pixels after the map context closes returns invalid or stale data.

  • Ignoring letterboxing makes picks offset and camera drag speed inconsistent.

  • Recreating the image bridge on every frame causes flicker, memory churn, or UI stalls.

  • Changing render resolution without updating viewport math and pick query coordinates causes selection to drift.

  • A wrong background color can be a style-color packing problem. Use ui.color("#76b900") or ui.color(r, g, b, a) rather than hand-packed integers.

Read for depth: see references/local-viewer, references/ovrtx-rendering, and references/object-selection for image bridge, frame extraction, and coordinate mapping details.

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